// Path: algoliasearch/src/main/java/com/algolia/search/saas/helpers/HandlerExecutor.java
// public class HandlerExecutor implements Executor {
//     /** Handler wrapped by this executor. */
//     private Handler handler;
// 
//     /**
//      * Construct a new executor wrapping the specified handler.
//      *
//      * @param handler Handler to wrap.
//      */
//     public HandlerExecutor(@NonNull Handler handler) {
//         this.handler = handler;
//     }
// 
//     /**
//      * Execute a command, by posting it to the underlying handler.
//      *
//      * @param command Command to execute.
//      */
//     public void execute(Runnable command) {
//         handler.post(command);
//     }
// }


import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.algolia.search.saas.android.BuildConfig;
import com.algolia.search.saas.helpers.HandlerExecutor;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.GZIPInputStream;
    private List<LibraryVersion> userAgents = new ArrayList<>();

    /** Connect timeout (ms). */
    private int connectTimeout = 2000;

    /** Default read (receive) timeout (ms). */
    private int readTimeout = 30000;

    /** Read timeout for search requests (ms). */
    private int searchTimeout = 5000;

    /** Delay to wait when a host is down before retrying it (ms). */
    private int hostDownDelay = 5000;

    private final String applicationID;
    private final String apiKey;
    private List<String> readHosts;
    private List<String> writeHosts;
    private HashMap<String, HostStatus> hostStatuses = new HashMap<>();

    /**
     * HTTP headers that will be sent with every request.
     */
    private HashMap<String, String> headers = new HashMap<String, String>();

    /** Thread pool used to run asynchronous requests. */
    protected ExecutorService searchExecutorService = Executors.newFixedThreadPool(4);

    /** Executor used to run completion handlers. By default, runs on the main thread. */
    protected @NonNull
// Path: algoliasearch/src/main/java/com/algolia/search/saas/helpers/HandlerExecutor.java
// public class HandlerExecutor implements Executor {
//     /** Handler wrapped by this executor. */
//     private Handler handler;
// 
//     /**
//      * Construct a new executor wrapping the specified handler.
//      *
//      * @param handler Handler to wrap.
//      */
//     public HandlerExecutor(@NonNull Handler handler) {
//         this.handler = handler;
//     }
// 
//     /**
//      * Execute a command, by posting it to the underlying handler.
//      *
//      * @param command Command to execute.
//      */
//     public void execute(Runnable command) {
//         handler.post(command);
//     }
// }


// Path: algoliasearch/src/main/java/com/algolia/search/saas/AbstractClient.java
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.algolia.search.saas.android.BuildConfig;
import com.algolia.search.saas.helpers.HandlerExecutor;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.GZIPInputStream;

    private List<LibraryVersion> userAgents = new ArrayList<>();

    /** Connect timeout (ms). */
    private int connectTimeout = 2000;

    /** Default read (receive) timeout (ms). */
    private int readTimeout = 30000;

    /** Read timeout for search requests (ms). */
    private int searchTimeout = 5000;

    /** Delay to wait when a host is down before retrying it (ms). */
    private int hostDownDelay = 5000;

    private final String applicationID;
    private final String apiKey;
    private List<String> readHosts;
    private List<String> writeHosts;
    private HashMap<String, HostStatus> hostStatuses = new HashMap<>();

    /**
     * HTTP headers that will be sent with every request.
     */
    private HashMap<String, String> headers = new HashMap<String, String>();

    /** Thread pool used to run asynchronous requests. */
    protected ExecutorService searchExecutorService = Executors.newFixedThreadPool(4);

    /** Executor used to run completion handlers. By default, runs on the main thread. */
    protected @NonNull
    Executor completionExecutor = new HandlerExecutor(new Handler(Looper.getMainLooper()));