code: @Override
    public <O extends Message> ListenableFuture<O> encodeMethodCall(final ClientMethod<O> method,
        Message input) {
      clientLogger.logMethodCall(method);
      final EnvelopeFuture<O> output = handler.newProvisionalResponse(method);
      Envelope request = Envelope.newBuilder()
          .setRequestId(output.requestId())
          .setService(method.serviceName())
          .setMethod(method.name())
          .setPayload(input.toByteString())
          .build();
      // TODO(julien): might be nice to couple the future returned from writeAndFlush
      // into the one returned to the user, so that calling cancel on the userland
      // future may also cancel the outgoing request if it isn't done yet.
      channel.writeAndFlush(request).addListener(new GenericFutureListener<ChannelFuture>() {
  
        public void operationComplete(ChannelFuture future) {
          if (!future.isSuccess()) {
            clientLogger.logLinkError(method, future.cause());
            handler.finish(output.requestId());
            output.setException(future.cause());
          }
        }
  
      });
      return output;
    }
docs: {@inheritDoc}