package com.windowsazure.messaging;

import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.client.config.RequestConfig;

public class HttpClientManager {

    private static CloseableHttpAsyncClient httpAsyncClient;

    // A timeout value of zero is interpreted as an infinite timeout.
    // A negative value is interpreted as undefined (system default).
    // https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/config/RequestConfig.html#getConnectionRequestTimeout()

    // The timeout in milliseconds used when requesting a connection from the connection manager.
    private static int connectionRequestTimeout = -1;

    // The timeout in milliseconds until a connection is established.
    private static int connectionTimeout = -1;

    // The socket timeout in milliseconds, which is the timeout for waiting for data or,
    // put differently, a maximum period inactivity between two consecutive data packets.
    private static int socketTimeout = -1;

    public static CloseableHttpAsyncClient initializeHttpAsyncClient() {
        synchronized (HttpClientManager.class) {
            if (httpAsyncClient == null) {
                RequestConfig config = RequestConfig.custom()
                        .setConnectionRequestTimeout(connectionRequestTimeout)
                        .setConnectTimeout(connectionTimeout)
                        .setSocketTimeout(socketTimeout)
                        .build();
                CloseableHttpAsyncClient client = HttpAsyncClientBuilder.create()
                        .setDefaultRequestConfig(config)
                        .build();
                client.start();
                httpAsyncClient = client;
            } else {
                throw new RuntimeException("initializeHttpAsyncClient cannot be called twice or after setHttpAsyncClient.");
            }
        }
        return httpAsyncClient;
    }

    public static CloseableHttpAsyncClient getHttpAsyncClient() {
        return httpAsyncClient;
    }

    public static void setHttpAsyncClient(CloseableHttpAsyncClient httpAsyncClient) {
        synchronized (HttpClientManager.class) {
            if (HttpClientManager.httpAsyncClient == null) {
                HttpClientManager.httpAsyncClient = httpAsyncClient;
            } else {
                throw new RuntimeException("Cannot setHttpAsyncClient after having previously set, or after default already initialized.");
            }
        }
    }

    // Sets the timeout in milliseconds used when requesting a connection from the connection manager.
    public static void setConnectionRequestTimeout(int timeout) {
        if (HttpClientManager.httpAsyncClient == null) {
            connectionRequestTimeout = timeout;
        } else {
            throw new RuntimeException("Set timeout preference only before initializeHttpAsyncClient.");
        }
    }

    // Sets the timeout in milliseconds until a connection is established.
    public static void setConnectTimeout(int timeout) {
        if (HttpClientManager.httpAsyncClient == null) {
            connectionTimeout = timeout;
        } else {
            throw new RuntimeException("Set timeout preference only before initializeHttpAsyncClient.");
        }
    }

    // Sets the timeout in milliseconds for waiting for data or,
    // put differently, a maximum period inactivity between two consecutive data packets.
    public static void setSocketTimeout(int timeout) {
        if (HttpClientManager.httpAsyncClient == null) {
            socketTimeout = timeout;
        } else {
            throw new RuntimeException("Set timeout preference only before initializeHttpAsyncClient.");
        }
    }
}

@@ -1095,37 +1095,38 @@
 = -1;%0A%0A    p
-ublic
+rivate
  static 
 CloseableHtt
@@ -1117,32 +1117,12 @@
 tic 
-CloseableHttpAsyncClient
+void
  ini
@@ -1786,39 +1786,32 @@
 t;%0A            %7D
- else %7B
 %0A               
@@ -1807,164 +1807,95 @@
     
+%7D%0A
     
+%7D%0A%0A
     
-throw new RuntimeException(%22initializeHttpAsyncClient cannot be called twice or after setHttpAsyncClient.%22);%0A            %7D%0A        %7D%0A        return 
+public static CloseableHttpAsyncClient getHttpAsyncClient() %7B%0A        if (
 http
@@ -1909,63 +1909,42 @@
 ient
-;
+ == null) %7B
 %0A    
-%7D%0A%0A
+  
     
-public static CloseableHttpAsyncClient get
+  initialize
 Http
@@ -1948,34 +1948,43 @@
 ttpAsyncClient()
- %7B
+;%0A        %7D
 %0A        return 
@@ -2428,16 +2428,56 @@
 tialized
+ from earlier call to getHttpAsyncClient
 .%22);%0A   
@@ -2839,53 +2839,146 @@
 on(%22
-Set timeout preference only before initialize
+Cannot setConnectionRequestTimeout after previously setting httpAsyncClient, or after default already initialized from earlier call to get
 Http
@@ -3300,53 +3300,136 @@
 on(%22
-Set timeout preference only before initialize
+Cannot setConnectTimeout after previously setting httpAsyncClient, or after default already initialized from earlier call to get
 Http
@@ -3826,53 +3826,135 @@
 on(%22
-Set timeout preference only before initialize
+Cannot setSocketTimeout after previously setting httpAsyncClient, or after default already initialized from earlier call to get
 Http

Make changes as non-breaked