// Path: core/src/main/java/io/keen/client/java/http/Request.java
// public final class Request {
// 
//     ///// PROPERTIES /////
// 
//     public final URL url;
//     public final String method;
//     public final String authorization;
//     public final OutputSource body;
//     public final Proxy proxy;
//     public final int connectTimeout;
//     public final int readTimeout;
// 
//     ///// PUBLIC CONSTRUCTORS /////
// 
//     @Deprecated
//     public Request(URL url, String method, String authorization, OutputSource body) {
//         this(url, method, authorization, body, null, 30000, 30000);
//     }
// 
//     public Request(URL url, String method, String authorization, OutputSource body, Proxy proxy, int connectTimeout, int readTimeout) {
//         this.url = url;
//         this.method = method;
//         this.authorization = authorization;
//         this.body = body;
//         this.proxy = proxy;
//         this.connectTimeout = connectTimeout;
//         this.readTimeout = readTimeout;
//     }
// 
// }
// 
// Path: core/src/main/java/io/keen/client/java/http/Response.java
// public final class Response {
// 
//     ///// PROPERTIES /////
// 
//     public final int statusCode;
//     public final String body;
// 
//     ///// PUBLIC CONSTRUCTORS /////
// 
//     public Response(int statusCode, String body) {
//         this.statusCode = statusCode;
//         this.body = body;
//     }
// 
//     ///// PUBLIC METHODS /////
// 
//     public boolean isSuccess() {
//         return isSuccessCode(statusCode);
//     }
// 
//     ///// PRIVATE STATIC METHODS /////
// 
//     /**
//      * Checks whether an HTTP status code indicates success.
//      *
//      * @param statusCode The HTTP status code.
//      * @return {@code true} if the status code indicates success (2xx), otherwise {@code false}.
//      */
//     private static boolean isSuccessCode(int statusCode) {
//         return (statusCode / 100 == 2);
//     }
// 
// }


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.keen.client.java.http.HttpHandler;
import io.keen.client.java.http.Request;
import io.keen.client.java.http.Response;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

    // Set responses such that that number of requests are expected and fulfilled with the
    // responses in the order given.
    void setMockResponses(List<Response> responses) throws IOException {
        numExecuteCalls = responses.size();

        if (numExecuteCalls < 2) {
            throw new IllegalArgumentException("Should have at least 2 responses.");
        }

        List<Response> remainingResponses = responses.subList(1, numExecuteCalls);
        Response[] remaining = remainingResponses.toArray(new Response[numExecuteCalls - 1]);
        Response first = responses.get(0);
        when(mockHttpHandler.execute(any(Request.class))).thenReturn(first, remaining);
    }

    String mockCaptureCountQueryRequest(KeenQueryRequest inputParams) throws Exception {
        executeRequest(inputParams);

        return executeCapturedRequest();
    }

    String executeCapturedRequest() throws IOException {
        verify(mockHttpHandler, times(numExecuteCalls)).execute(requestArgumentCaptor.capture());

        // We're only returning the most recently captured Request. If we ever want to get all the
        // Requests for all invocations, we'll need to refactor a bit.
        return requestToString(requestArgumentCaptor.getValue());
    }

// Path: core/src/main/java/io/keen/client/java/http/Request.java
// public final class Request {
// 
//     ///// PROPERTIES /////
// 
//     public final URL url;
//     public final String method;
//     public final String authorization;
//     public final OutputSource body;
//     public final Proxy proxy;
//     public final int connectTimeout;
//     public final int readTimeout;
// 
//     ///// PUBLIC CONSTRUCTORS /////
// 
//     @Deprecated
//     public Request(URL url, String method, String authorization, OutputSource body) {
//         this(url, method, authorization, body, null, 30000, 30000);
//     }
// 
//     public Request(URL url, String method, String authorization, OutputSource body, Proxy proxy, int connectTimeout, int readTimeout) {
//         this.url = url;
//         this.method = method;
//         this.authorization = authorization;
//         this.body = body;
//         this.proxy = proxy;
//         this.connectTimeout = connectTimeout;
//         this.readTimeout = readTimeout;
//     }
// 
// }
// 
// Path: core/src/main/java/io/keen/client/java/http/Response.java
// public final class Response {
// 
//     ///// PROPERTIES /////
// 
//     public final int statusCode;
//     public final String body;
// 
//     ///// PUBLIC CONSTRUCTORS /////
// 
//     public Response(int statusCode, String body) {
//         this.statusCode = statusCode;
//         this.body = body;
//     }
// 
//     ///// PUBLIC METHODS /////
// 
//     public boolean isSuccess() {
//         return isSuccessCode(statusCode);
//     }
// 
//     ///// PRIVATE STATIC METHODS /////
// 
//     /**
//      * Checks whether an HTTP status code indicates success.
//      *
//      * @param statusCode The HTTP status code.
//      * @return {@code true} if the status code indicates success (2xx), otherwise {@code false}.
//      */
//     private static boolean isSuccessCode(int statusCode) {
//         return (statusCode / 100 == 2);
//     }
// 
// }


// Path: query/src/test/java/io/keen/client/java/KeenQueryTestBase.java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.keen.client.java.http.HttpHandler;
import io.keen.client.java.http.Request;
import io.keen.client.java.http.Response;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


    // Set responses such that that number of requests are expected and fulfilled with the
    // responses in the order given.
    void setMockResponses(List<Response> responses) throws IOException {
        numExecuteCalls = responses.size();

        if (numExecuteCalls < 2) {
            throw new IllegalArgumentException("Should have at least 2 responses.");
        }

        List<Response> remainingResponses = responses.subList(1, numExecuteCalls);
        Response[] remaining = remainingResponses.toArray(new Response[numExecuteCalls - 1]);
        Response first = responses.get(0);
        when(mockHttpHandler.execute(any(Request.class))).thenReturn(first, remaining);
    }

    String mockCaptureCountQueryRequest(KeenQueryRequest inputParams) throws Exception {
        executeRequest(inputParams);

        return executeCapturedRequest();
    }

    String executeCapturedRequest() throws IOException {
        verify(mockHttpHandler, times(numExecuteCalls)).execute(requestArgumentCaptor.capture());

        // We're only returning the most recently captured Request. If we ever want to get all the
        // Requests for all invocations, we'll need to refactor a bit.
        return requestToString(requestArgumentCaptor.getValue());
    }

    String requestToString(Request request) throws IOException {