// Path: core/src/main/java/io/keen/client/java/exceptions/NoWriteKeyException.java
// public class NoWriteKeyException extends KeenException {
//     private static final long serialVersionUID = -8199471518510440670L;
// 
//     public NoWriteKeyException() {
//         super();
//     }
// 
//     public NoWriteKeyException(Throwable cause) {
//         super(cause);
//     }
// 
//     public NoWriteKeyException(String message) {
//         super(message);
//     }
// 
//     public NoWriteKeyException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// 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.SerializationFeature;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import io.keen.client.java.exceptions.KeenException;
import io.keen.client.java.exceptions.NoWriteKeyException;
import io.keen.client.java.exceptions.ServerException;
import io.keen.client.java.http.HttpHandler;
import io.keen.client.java.http.Request;
import io.keen.client.java.http.Response;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
        event.put("valid key", "valid value");
        Map<String, Object> keenProperties = new HashMap<String, Object>();
        keenProperties.put("keen key", "keen value");
        Map<String, Object> result = client.validateAndBuildEvent(client.getDefaultProject(), "foo", event, keenProperties);
        @SuppressWarnings("unchecked")
        Map<String, Object> keenPropResult = (Map<String, Object>)result.get("keen");
        assertNotNull(keenPropResult.get("timestamp"));
        assertNull(keenProperties.get("timestamp"));
        assertEquals(keenProperties.get("keen key"), "keen value");
        assertEquals(keenPropResult.get("keen key"), "keen value");
        assertEquals(keenProperties.get("keen key"), keenPropResult.get("keen key"));
    }

    @Test
    public void validEventWithNestedKeenProperty() throws Exception {
        Map<String, Object> event = TestUtils.getSimpleEvent();
        Map<String, Object> nested = new HashMap<String, Object>();
        nested.put("keen", "value");
        event.put("nested", nested);
        client.validateAndBuildEvent(client.getDefaultProject(), "foo", event, null);
    }

    @Test
    public void testAddEventNoWriteKey() throws KeenException, IOException {
        client.setDefaultProject(new KeenProject("508339b0897a2c4282000000", null, "<read key>"));
        Map<String, Object> event = new HashMap<String, Object>();
        event.put("test key", "test value");
        try {
            client.addEvent("foo", event);
            fail("add event without write key should fail");
// Path: core/src/main/java/io/keen/client/java/exceptions/NoWriteKeyException.java
// public class NoWriteKeyException extends KeenException {
//     private static final long serialVersionUID = -8199471518510440670L;
// 
//     public NoWriteKeyException() {
//         super();
//     }
// 
//     public NoWriteKeyException(Throwable cause) {
//         super(cause);
//     }
// 
//     public NoWriteKeyException(String message) {
//         super(message);
//     }
// 
//     public NoWriteKeyException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// 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: core/src/test/java/io/keen/client/java/KeenClientTest.java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import io.keen.client.java.exceptions.KeenException;
import io.keen.client.java.exceptions.NoWriteKeyException;
import io.keen.client.java.exceptions.ServerException;
import io.keen.client.java.http.HttpHandler;
import io.keen.client.java.http.Request;
import io.keen.client.java.http.Response;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

        event.put("valid key", "valid value");
        Map<String, Object> keenProperties = new HashMap<String, Object>();
        keenProperties.put("keen key", "keen value");
        Map<String, Object> result = client.validateAndBuildEvent(client.getDefaultProject(), "foo", event, keenProperties);
        @SuppressWarnings("unchecked")
        Map<String, Object> keenPropResult = (Map<String, Object>)result.get("keen");
        assertNotNull(keenPropResult.get("timestamp"));
        assertNull(keenProperties.get("timestamp"));
        assertEquals(keenProperties.get("keen key"), "keen value");
        assertEquals(keenPropResult.get("keen key"), "keen value");
        assertEquals(keenProperties.get("keen key"), keenPropResult.get("keen key"));
    }

    @Test
    public void validEventWithNestedKeenProperty() throws Exception {
        Map<String, Object> event = TestUtils.getSimpleEvent();
        Map<String, Object> nested = new HashMap<String, Object>();
        nested.put("keen", "value");
        event.put("nested", nested);
        client.validateAndBuildEvent(client.getDefaultProject(), "foo", event, null);
    }

    @Test
    public void testAddEventNoWriteKey() throws KeenException, IOException {
        client.setDefaultProject(new KeenProject("508339b0897a2c4282000000", null, "<read key>"));
        Map<String, Object> event = new HashMap<String, Object>();
        event.put("test key", "test value");
        try {
            client.addEvent("foo", event);
            fail("add event without write key should fail");
        } catch (NoWriteKeyException e) {