/** {@inheritDoc} */
 public boolean canCacheConnection() {
   if (config.getMaxTotalConnections() != -1
       && trackedIdleConnections.size() >= config.getMaxTotalConnections()) {
     return false;
   } else {
     return true;
   }
 }
  /** {@inheritDoc} */
  public boolean offer(String uri, Channel channel) {
    if (!provider.getConfig().isSslConnectionPoolEnabled() && uri.startsWith("https")) {
      return false;
    }

    log.debug("Adding uri: {} for channel {}", uri, channel);
    channel
        .getPipeline()
        .getContext(NettyAsyncHttpProvider.class)
        .setAttachment(new NettyAsyncHttpProvider.DiscardEvent());

    ConcurrentLinkedQueue<Channel> pooledConnectionForHost = connectionsPool.get(uri);
    if (pooledConnectionForHost == null) {
      ConcurrentLinkedQueue<Channel> newPool = new ConcurrentLinkedQueue<Channel>();
      connectionsPool.putIfAbsent(uri, newPool);
      pooledConnectionForHost = connectionsPool.get(uri);
    }

    boolean added;
    int size = pooledConnectionForHost.size();
    if (config.getMaxConnectionPerHost() == -1 || size < config.getMaxConnectionPerHost()) {
      added = pooledConnectionForHost.add(channel);
      if (added) {
        Timeout t =
            timer.newTimeout(
                new IdleRunner(channel, pooledConnectionForHost),
                config.getIdleConnectionInPoolTimeoutInMs(),
                TimeUnit.MILLISECONDS);
        trackedIdleConnections.put(channel, t);
        log.debug("ConnectionsPool increment totalConnections {}", trackedIdleConnections.size());
      }
    } else {
      log.debug("Maximum connections per hosts reached {}", config.getMaxConnectionPerHost());
      added = false;
    }
    return added;
  }
    /**
     * Create a config builder with values taken from the given prototype configuration.
     *
     * @param prototype the configuration to use as a prototype.
     */
    public Builder(AsyncHttpClientConfig prototype) {
      allowPoolingConnection = prototype.getAllowPoolingConnection();
      providerConfig = prototype.getAsyncHttpProviderConfig();
      connectionsPool = prototype.getConnectionsPool();
      defaultConnectionTimeOutInMs = prototype.getConnectionTimeoutInMs();
      defaultIdleConnectionInPoolTimeoutInMs = prototype.getIdleConnectionInPoolTimeoutInMs();
      defaultIdleConnectionTimeoutInMs = prototype.getIdleConnectionTimeoutInMs();
      defaultMaxConnectionPerHost = prototype.getMaxConnectionPerHost();
      defaultMaxConnectionLifeTimeInMs = prototype.getMaxConnectionLifeTimeInMs();
      maxDefaultRedirects = prototype.getMaxRedirects();
      defaultMaxTotalConnections = prototype.getMaxTotalConnections();
      proxyServer = prototype.getProxyServer();
      realm = prototype.getRealm();
      defaultRequestTimeoutInMs = prototype.getRequestTimeoutInMs();
      sslContext = prototype.getSSLContext();
      sslEngineFactory = prototype.getSSLEngineFactory();
      userAgent = prototype.getUserAgent();
      redirectEnabled = prototype.isRedirectEnabled();
      compressionEnabled = prototype.isCompressionEnabled();
      reaper = prototype.reaper();
      applicationThreadPool = prototype.executorService();

      requestFilters.clear();
      responseFilters.clear();
      ioExceptionFilters.clear();

      requestFilters.addAll(prototype.getRequestFilters());
      responseFilters.addAll(prototype.getResponseFilters());
      ioExceptionFilters.addAll(prototype.getIOExceptionFilters());

      requestCompressionLevel = prototype.getRequestCompressionLevel();
      useRawUrl = prototype.isUseRawUrl();
      ioThreadMultiplier = prototype.getIoThreadMultiplier();
      maxRequestRetry = prototype.getMaxRequestRetry();
      allowSslConnectionPool = prototype.getAllowPoolingConnection();
      removeQueryParamOnRedirect = prototype.isRemoveQueryParamOnRedirect();
      hostnameVerifier = prototype.getHostnameVerifier();
      strict302Handling = prototype.isStrict302Handling();
      useRelativeURIsWithSSLProxies = prototype.isUseRelativeURIsWithSSLProxies();
    }