protected Client apacheHttpClientSpecificInitialization() {
        httpClient4 = NFHttpClientFactory.getNamedNFHttpClient(restClientName, this.ncc, true);

        if (httpClient4 instanceof AbstractHttpClient) {
            // DONT use our NFHttpClient's default Retry Handler since we have
            // retry handling (same server/next server) in RestClient itself
            ((AbstractHttpClient) httpClient4).setHttpRequestRetryHandler(new NFHttpMethodRetryHandler(restClientName, 0, false, 0));
        } else {
            logger.warn("Unexpected error: Unable to disable NFHttpClient "
                    + "retry handler, this most likely will not cause an "
                    + "issue but probably should be looked at");
        }

        HttpParams httpClientParams = httpClient4.getParams();
        // initialize Connection Manager cleanup facility
        NFHttpClient nfHttpClient = (NFHttpClient) httpClient4;
        // should we enable connection cleanup for idle connections?
        try {
            enableConnectionPoolCleanerTask = ncc.getOrDefault(CommonClientConfigKey.ConnectionPoolCleanerTaskEnabled);
            nfHttpClient.getConnPoolCleaner().setEnableConnectionPoolCleanerTask(enableConnectionPoolCleanerTask);
        } catch (Exception e1) {
            throwInvalidValue(CommonClientConfigKey.ConnectionPoolCleanerTaskEnabled, e1);
        }
        if (enableConnectionPoolCleanerTask) {
            try {
                connectionCleanerRepeatInterval = ncc.getOrDefault(CommonClientConfigKey.ConnectionCleanerRepeatInterval);
                nfHttpClient.getConnPoolCleaner().setConnectionCleanerRepeatInterval(connectionCleanerRepeatInterval);
            } catch (Exception e1) {
                throwInvalidValue(CommonClientConfigKey.ConnectionCleanerRepeatInterval, e1);
            }

            try {
                connIdleEvictTimeMilliSeconds = ncc.getDynamicProperty(CommonClientConfigKey.ConnIdleEvictTimeMilliSeconds);
                nfHttpClient.setConnIdleEvictTimeMilliSeconds(connIdleEvictTimeMilliSeconds);
            } catch (Exception e1) {
                throwInvalidValue(CommonClientConfigKey.ConnIdleEvictTimeMilliSeconds, e1);
            }

            nfHttpClient.initConnectionCleanerTask();
        }

        try {
            maxConnectionsperHost = ncc.getOrDefault(CommonClientConfigKey.MaxHttpConnectionsPerHost);
            ClientConnectionManager connMgr = httpClient4.getConnectionManager();
            if (connMgr instanceof ThreadSafeClientConnManager) {
                ((ThreadSafeClientConnManager) connMgr)
                .setDefaultMaxPerRoute(maxConnectionsperHost);
            }
        } catch (Exception e1) {
            throwInvalidValue(CommonClientConfigKey.MaxHttpConnectionsPerHost, e1);
        }

        try {
            maxTotalConnections = ncc.getOrDefault(CommonClientConfigKey.MaxTotalHttpConnections);
            ClientConnectionManager connMgr = httpClient4.getConnectionManager();
            if (connMgr instanceof ThreadSafeClientConnManager) {
                ((ThreadSafeClientConnManager) connMgr)
                .setMaxTotal(maxTotalConnections);
            }
        } catch (Exception e1) {
            throwInvalidValue(CommonClientConfigKey.MaxTotalHttpConnections, e1);
        }

        try {
            connectionTimeout = ncc.getOrDefault(CommonClientConfigKey.ConnectTimeout);
            HttpConnectionParams.setConnectionTimeout(httpClientParams,
                    connectionTimeout);
        } catch (Exception e1) {
            throwInvalidValue(CommonClientConfigKey.ConnectTimeout, e1);
        }

        try {
            readTimeout = ncc.getOrDefault(CommonClientConfigKey.ReadTimeout);
            HttpConnectionParams.setSoTimeout(httpClientParams, readTimeout);
        } catch (Exception e1) {
            throwInvalidValue(CommonClientConfigKey.ReadTimeout, e1);
        }

        // httpclient 4 seems to only have one buffer size controlling both
        // send/receive - so let's take the bigger of the two values and use
        // it as buffer size
        int bufferSize = Integer.MIN_VALUE;
        if (ncc.get(CommonClientConfigKey.ReceiveBufferSize) != null) {
            try {
                bufferSize = ncc.getOrDefault(CommonClientConfigKey.ReceiveBufferSize);
            } catch (Exception e) {
                throwInvalidValue(CommonClientConfigKey.ReceiveBufferSize, e);
            }
            if (ncc.get(CommonClientConfigKey.SendBufferSize) != null) {
                try {
                    int sendBufferSize = ncc.getOrDefault(CommonClientConfigKey.SendBufferSize);
                    if (sendBufferSize > bufferSize) {
                        bufferSize = sendBufferSize;
                    }
                } catch (Exception e) {
                    throwInvalidValue(CommonClientConfigKey.SendBufferSize,e);
                }
            }
        }
        if (bufferSize != Integer.MIN_VALUE) {
            HttpConnectionParams.setSocketBufferSize(httpClientParams,
                    bufferSize);
        }

        if (ncc.get(CommonClientConfigKey.StaleCheckingEnabled) != null) {
            try {
                HttpConnectionParams.setStaleCheckingEnabled(
                        httpClientParams, ncc.getOrDefault(CommonClientConfigKey.StaleCheckingEnabled));
            } catch (Exception e) {
                throwInvalidValue(CommonClientConfigKey.StaleCheckingEnabled, e);
            }
        }

        if (ncc.get(CommonClientConfigKey.Linger) != null) {
            try {
                HttpConnectionParams.setLinger(httpClientParams, ncc.getOrDefault(CommonClientConfigKey.Linger));
            } catch (Exception e) {
                throwInvalidValue(CommonClientConfigKey.Linger, e);
            }
        }

        if (ncc.get(CommonClientConfigKey.ProxyHost) != null) {
            try {
                proxyHost = (String) ncc.getOrDefault(CommonClientConfigKey.ProxyHost);
                proxyPort = ncc.getOrDefault(CommonClientConfigKey.ProxyPort);
                HttpHost proxy = new HttpHost(proxyHost, proxyPort);
                httpClient4.getParams()
                    .setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
            } catch (Exception e) {
                throwInvalidValue(CommonClientConfigKey.ProxyHost, e);
            }
        }

        if (isSecure) {
            final URL trustStoreUrl = getResourceForOptionalProperty(CommonClientConfigKey.TrustStore);
            final URL keyStoreUrl = getResourceForOptionalProperty(CommonClientConfigKey.KeyStore);

        	final ClientConnectionManager currentManager = httpClient4.getConnectionManager();

            AbstractSslContextFactory abstractFactory = null;


            if (    // if client auth is required, need both a truststore and a keystore to warrant configuring
            		// if client is not is not required, we only need a keystore OR a truststore to warrant configuring
            		(isClientAuthRequired && (trustStoreUrl != null && keyStoreUrl != null))
            		    || (!isClientAuthRequired && (trustStoreUrl != null || keyStoreUrl != null))
            		) {

                try {
                	abstractFactory = new URLSslContextFactory(trustStoreUrl,
                            ncc.get(CommonClientConfigKey.TrustStorePassword),
                            keyStoreUrl,
                            ncc.get(CommonClientConfigKey.KeyStorePassword));

                } catch (ClientSslSocketFactoryException e) {
                    throw new IllegalArgumentException("Unable to configure custom secure socket factory", e);
                }
            }

        	KeyStoreAwareSocketFactory awareSocketFactory;
        	try {
        		awareSocketFactory = isHostnameValidationRequired ? new KeyStoreAwareSocketFactory(abstractFactory) :
        		    new KeyStoreAwareSocketFactory(abstractFactory, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        		currentManager.getSchemeRegistry().register(new Scheme(
                        "https",443, awareSocketFactory));

        	} catch (Exception e) {
        		throw new IllegalArgumentException("Unable to configure custom secure socket factory", e);
        	}
        }

        // Warning that if user tokens are used (i.e. ignoreUserToken == false) this may be prevent SSL connections from being
        // reused, which is generally not the intent for long-living proxy connections and the like.
        // See http://hc.apache.org/httpcomponents-client-ga/tutorial/html/advanced.html
        if (ignoreUserToken) {
            ((DefaultHttpClient) httpClient4).setUserTokenHandler(new UserTokenHandler() {
                @Override
                public Object getUserToken(HttpContext context) {
                    return null;
                }
            });
        }

        // custom SSL Factory handler
        String customSSLFactoryClassName = ncc.get(CommonClientConfigKey.CustomSSLSocketFactoryClassName);

        if (customSSLFactoryClassName != null){
            try{
                SSLSocketFactory customSocketFactory = (SSLSocketFactory) ClientFactory.instantiateInstanceWithClientConfig(customSSLFactoryClassName, ncc);

                httpClient4.getConnectionManager().getSchemeRegistry().register(new Scheme(
                        "https",443, customSocketFactory));

            } catch(Exception e){
                throwInvalidValue(CommonClientConfigKey.CustomSSLSocketFactoryClassName, e);
            }
        }

        ApacheHttpClient4Handler handler = new ApacheHttpClient4Handler(httpClient4, new BasicCookieStore(), false);

        return new ApacheHttpClient4(handler, config);
    }
A client that is essentially a wrapper around Jersey client. By default, it uses HttpClient for underlying HTTP communication.
Application can set its own Jersey client with this class, but doing so will void all client configurations set in {@link IClientConfig}.

@deprecated Please see ribbon-rxnetty module for the Netty based client. 

@author awang
ribbon-httpclient/src/main/java/com/netflix/niws/client/http/RestClient.java