protected boolean sendOutRequest(OutRequest outRequest, Connection connection) {
    Request request = outRequest.getRequest();

    // Validate if the ArgScheme is set correctly
    if (request.getArgScheme() == null) {
      request.setArgScheme(ArgScheme.RAW);
      outRequest.setLastError(
          ErrorType.BadRequest, "Expect call request to have Arg Scheme specified");
      outRequest.setFuture();
      return false;
    }

    // Set the default retry flag if it is not set
    if (request.getRetryFlags() == null) {
      request.setRetryFlags("c");
    }

    long initTimeout = this.initTimeout;
    if (initTimeout <= 0) {
      initTimeout = request.getTimeout();
    }

    if (connection == null) {
      outRequest.setLastError(ErrorType.BadRequest, new TChannelNoPeerAvailable());
      outRequest.setFuture();
      return false;
    } else if (!connection.waitForIdentified(initTimeout)) {
      connection.clean();
      if (connection.lastError() != null) {
        outRequest.setLastError(ErrorType.NetworkError, connection.lastError());
      } else {
        outRequest.setLastError(ErrorType.NetworkError, new TChannelConnectionTimeout());
      }

      return false;
    }

    // Get a response router for our outbound channel
    ResponseRouter router = connection.channel().pipeline().get(ResponseRouter.class);
    return router.expectResponse(outRequest);
  }
  protected <V extends Response> TFuture<V> sendRequest(
      Request request, InetAddress host, int port) {
    OutRequest<V> outRequest = new OutRequest<V>(this, request);
    if (host != null) {
      Connection conn = peerManager.findOrNew(new InetSocketAddress(host, port));
      // No retry for direct connections
      outRequest.disableRetry();
      if (!sendOutRequest(outRequest, conn)) {
        outRequest.setFuture();
      }
    } else if (peers.size() == 0) {
      outRequest.setLastError(ErrorType.BadRequest, new TChannelNoPeerAvailable());
      outRequest.setFuture();
    } else {
      sendOutRequest(outRequest);
    }

    return outRequest.getFuture();
  }