// Path: src/main/java/info/blockchain/api/APIException.java
// public class APIException extends Exception {
//     private static final long serialVersionUID = -7731961787745059713L;
// 
//     public APIException (String message) {
//         super(message);
//     }
// }
// 
// Path: src/main/java/info/blockchain/api/HttpClient.java
// public class HttpClient implements HttpClientInterface {
//     private static final String BASE_URL = "https://blockchain.info/";
// 
//     public volatile static int TIMEOUT_MS = 10000;
// 
//     private static HttpClientInterface instance;
// 
//     public synchronized static HttpClientInterface getInstance () {
//         if (instance == null) {
//             // Thread Safe. Might be costly operation in some case
//             synchronized (HttpClient.class) {
//                 if (instance == null) {
//                     instance = new HttpClient();
//                 }
//             }
//         }
//         return instance;
//     }
// 
//     public static void setCustomHttpClient (HttpClientInterface httpClient) {
//         instance = httpClient;
//     }
// 
//     /**
//      * Perform a GET request on a Blockchain.info API resource.
//      *
//      * @param resource Resource path after https://blockchain.info/api/
//      * @param params   Map containing request parameters
//      * @return String response
//      * @throws APIException If the server returns an error
//      */
//     public String get (String resource, Map<String, String> params) throws APIException, IOException {
//         return openURL(BASE_URL, resource, params, "GET");
//     }
// 
//     public String get (String baseURL, String resource, Map<String, String> params) throws APIException, IOException {
//         return openURL(baseURL, resource, params, "GET");
//     }
// 
//     /**
//      * Perform a POST request on a Blockchain.info API resource.
//      *
//      * @param resource Resource path after https://blockchain.info/api/
//      * @param params   Map containing request parameters
//      * @return String response
//      * @throws APIException If the server returns an error
//      * @throws IOException  If the server is not reachable
//      */
//     public String post (String resource, Map<String, String> params) throws APIException, IOException {
//         return openURL(BASE_URL, resource, params, "POST");
//     }
// 
//     public String post (String baseURL, String resource, Map<String, String> params) throws APIException, IOException {
//         return openURL(baseURL, resource, params, "POST");
//     }
// 
//     private static String openURL (String baseURL, String resource, Map<String, String> params, String requestMethod) throws APIException, IOException {
//         String encodedParams = urlEncodeParams(params);
//         URL url = null;
//         APIException apiException = null;
//         IOException ioException = null;
// 
//         String responseStr = null;
// 
//         if (requestMethod.equals("GET")) {
//             if (encodedParams.isEmpty()) {
//                 url = new URL(baseURL + resource);
//             } else {
//                 url = new URL(baseURL + resource + '?' + encodedParams);
//             }            
//         } else if (requestMethod.equals("POST")) {
//             url = new URL(baseURL + resource);
//         }
// 
//         HttpURLConnection conn = null;
// 
//         try {
//             conn = (HttpURLConnection) url.openConnection();
//             conn.setRequestMethod(requestMethod);
//             conn.setConnectTimeout(TIMEOUT_MS);
// 
//             if (requestMethod.equals("POST")) {
//                 byte[] postBytes = encodedParams.getBytes("UTF-8");
//                 conn.setDoOutput(true);
//                 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//                 conn.setRequestProperty("Content-Length", String.valueOf(postBytes.length));
//                 conn.getOutputStream().write(postBytes);
//                 conn.getOutputStream().close();
//             }
// 
//             if (conn.getResponseCode() != 200) {
//                 apiException = new APIException(inputStreamToString(conn.getErrorStream()));
//             } else {
//                 responseStr = inputStreamToString(conn.getInputStream());
//             }
//         } catch (IOException e) {
//             ioException = e;
//         } finally {
//             try {
//                 if (apiException != null) {
//                     conn.getErrorStream().close();
//                 }
//                 conn.getInputStream().close();
//             } catch (Exception ex) {
//             }
// 
//             if (ioException != null) {
//                 throw ioException;
//             }
// 
//             if (apiException != null) {
//                 throw apiException;
//             }
//         }
// 
//         return responseStr;
//     }
// 
//     private static String urlEncodeParams (Map<String, String> params) {
//         String result = "";
// 
//         if (params != null && params.size() > 0) {
//             try {
//                 StringBuilder data = new StringBuilder();
//                 for (Entry<String, String> kvp : params.entrySet()) {
//                     if (data.length() > 0) {
//                         data.append('&');
//                     }
// 
//                     data.append(URLEncoder.encode(kvp.getKey(), "UTF-8"));
//                     data.append('=');
//                     data.append(URLEncoder.encode(kvp.getValue(), "UTF-8"));
//                 }
//                 result = data.toString();
//             } catch (UnsupportedEncodingException e) {
//             }
//         }
// 
//         return result;
//     }
// 
//     private static String inputStreamToString (InputStream is) throws IOException {
//         BufferedReader reader = new BufferedReader(new InputStreamReader(is));
// 
//         StringBuilder responseStringBuilder = new StringBuilder();
//         String line = "";
// 
//         while ((line = reader.readLine()) != null) {
//             responseStringBuilder.append(line);
//         }
// 
//         reader.close();
// 
//         return responseStringBuilder.toString();
//     }
// }


import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import info.blockchain.api.APIException;
import info.blockchain.api.HttpClient;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
package info.blockchain.api.statistics;



/**
 * This class reflects the functionality documented
 * at https://blockchain.info/api/charts_api
 */
public class Statistics {
    private final String apiCode;

    public Statistics () {
        this(null);
    }

    public Statistics (String apiCode) {
        this.apiCode = apiCode;
    }

    /**
     * Gets the network statistics.
     *
     * @return An instance of the StatisticsResponse class
     * @throws APIException If the server returns an error
     */
// Path: src/main/java/info/blockchain/api/APIException.java
// public class APIException extends Exception {
//     private static final long serialVersionUID = -7731961787745059713L;
// 
//     public APIException (String message) {
//         super(message);
//     }
// }
// 
// Path: src/main/java/info/blockchain/api/HttpClient.java
// public class HttpClient implements HttpClientInterface {
//     private static final String BASE_URL = "https://blockchain.info/";
// 
//     public volatile static int TIMEOUT_MS = 10000;
// 
//     private static HttpClientInterface instance;
// 
//     public synchronized static HttpClientInterface getInstance () {
//         if (instance == null) {
//             // Thread Safe. Might be costly operation in some case
//             synchronized (HttpClient.class) {
//                 if (instance == null) {
//                     instance = new HttpClient();
//                 }
//             }
//         }
//         return instance;
//     }
// 
//     public static void setCustomHttpClient (HttpClientInterface httpClient) {
//         instance = httpClient;
//     }
// 
//     /**
//      * Perform a GET request on a Blockchain.info API resource.
//      *
//      * @param resource Resource path after https://blockchain.info/api/
//      * @param params   Map containing request parameters
//      * @return String response
//      * @throws APIException If the server returns an error
//      */
//     public String get (String resource, Map<String, String> params) throws APIException, IOException {
//         return openURL(BASE_URL, resource, params, "GET");
//     }
// 
//     public String get (String baseURL, String resource, Map<String, String> params) throws APIException, IOException {
//         return openURL(baseURL, resource, params, "GET");
//     }
// 
//     /**
//      * Perform a POST request on a Blockchain.info API resource.
//      *
//      * @param resource Resource path after https://blockchain.info/api/
//      * @param params   Map containing request parameters
//      * @return String response
//      * @throws APIException If the server returns an error
//      * @throws IOException  If the server is not reachable
//      */
//     public String post (String resource, Map<String, String> params) throws APIException, IOException {
//         return openURL(BASE_URL, resource, params, "POST");
//     }
// 
//     public String post (String baseURL, String resource, Map<String, String> params) throws APIException, IOException {
//         return openURL(baseURL, resource, params, "POST");
//     }
// 
//     private static String openURL (String baseURL, String resource, Map<String, String> params, String requestMethod) throws APIException, IOException {
//         String encodedParams = urlEncodeParams(params);
//         URL url = null;
//         APIException apiException = null;
//         IOException ioException = null;
// 
//         String responseStr = null;
// 
//         if (requestMethod.equals("GET")) {
//             if (encodedParams.isEmpty()) {
//                 url = new URL(baseURL + resource);
//             } else {
//                 url = new URL(baseURL + resource + '?' + encodedParams);
//             }            
//         } else if (requestMethod.equals("POST")) {
//             url = new URL(baseURL + resource);
//         }
// 
//         HttpURLConnection conn = null;
// 
//         try {
//             conn = (HttpURLConnection) url.openConnection();
//             conn.setRequestMethod(requestMethod);
//             conn.setConnectTimeout(TIMEOUT_MS);
// 
//             if (requestMethod.equals("POST")) {
//                 byte[] postBytes = encodedParams.getBytes("UTF-8");
//                 conn.setDoOutput(true);
//                 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//                 conn.setRequestProperty("Content-Length", String.valueOf(postBytes.length));
//                 conn.getOutputStream().write(postBytes);
//                 conn.getOutputStream().close();
//             }
// 
//             if (conn.getResponseCode() != 200) {
//                 apiException = new APIException(inputStreamToString(conn.getErrorStream()));
//             } else {
//                 responseStr = inputStreamToString(conn.getInputStream());
//             }
//         } catch (IOException e) {
//             ioException = e;
//         } finally {
//             try {
//                 if (apiException != null) {
//                     conn.getErrorStream().close();
//                 }
//                 conn.getInputStream().close();
//             } catch (Exception ex) {
//             }
// 
//             if (ioException != null) {
//                 throw ioException;
//             }
// 
//             if (apiException != null) {
//                 throw apiException;
//             }
//         }
// 
//         return responseStr;
//     }
// 
//     private static String urlEncodeParams (Map<String, String> params) {
//         String result = "";
// 
//         if (params != null && params.size() > 0) {
//             try {
//                 StringBuilder data = new StringBuilder();
//                 for (Entry<String, String> kvp : params.entrySet()) {
//                     if (data.length() > 0) {
//                         data.append('&');
//                     }
// 
//                     data.append(URLEncoder.encode(kvp.getKey(), "UTF-8"));
//                     data.append('=');
//                     data.append(URLEncoder.encode(kvp.getValue(), "UTF-8"));
//                 }
//                 result = data.toString();
//             } catch (UnsupportedEncodingException e) {
//             }
//         }
// 
//         return result;
//     }
// 
//     private static String inputStreamToString (InputStream is) throws IOException {
//         BufferedReader reader = new BufferedReader(new InputStreamReader(is));
// 
//         StringBuilder responseStringBuilder = new StringBuilder();
//         String line = "";
// 
//         while ((line = reader.readLine()) != null) {
//             responseStringBuilder.append(line);
//         }
// 
//         reader.close();
// 
//         return responseStringBuilder.toString();
//     }
// }


// Path: src/main/java/info/blockchain/api/statistics/Statistics.java
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import info.blockchain.api.APIException;
import info.blockchain.api.HttpClient;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

package info.blockchain.api.statistics;



/**
 * This class reflects the functionality documented
 * at https://blockchain.info/api/charts_api
 */
public class Statistics {
    private final String apiCode;

    public Statistics () {
        this(null);
    }

    public Statistics (String apiCode) {
        this.apiCode = apiCode;
    }

    /**
     * Gets the network statistics.
     *
     * @return An instance of the StatisticsResponse class
     * @throws APIException If the server returns an error
     */
    public StatisticsResponse getStats () throws APIException, IOException {