/**
   * Processes a new connection making it idle or active depending on whether requests are waiting
   * to be sent.
   *
   * <p>A new connection is created when a request needs to be executed; it is possible that the
   * request that triggered the request creation is executed by another connection that was just
   * released, so the new connection may become idle.
   *
   * <p>If a request is waiting to be executed, it will be dequeued and executed by the new
   * connection.
   *
   * @param connection the new connection
   */
  public void process(final C connection) {
    HttpClient client = getHttpClient();
    final HttpExchange exchange = getHttpExchanges().poll();
    if (LOG.isDebugEnabled())
      LOG.debug("Processing exchange {} on {} of {}", exchange, connection, this);
    if (exchange == null) {
      if (!connectionPool.release(connection)) connection.close();

      if (!client.isRunning()) {
        if (LOG.isDebugEnabled()) LOG.debug("{} is stopping", client);
        connection.close();
      }
    } else {
      final Request request = exchange.getRequest();
      Throwable cause = request.getAbortCause();
      if (cause != null) {
        if (LOG.isDebugEnabled()) LOG.debug("Aborted before processing {}: {}", exchange, cause);
        // It may happen that the request is aborted before the exchange
        // is created. Aborting the exchange a second time will result in
        // a no-operation, so we just abort here to cover that edge case.
        exchange.abort(cause);
      } else {
        send(connection, exchange);
      }
    }
  }