// Path: core/src/main/java/com/bazaarvoice/ostrich/PartitionContext.java
// public interface PartitionContext {
//     /**
//      * Gets the default piece of context. In many cases, there is only a single piece of relevant context, which this
//      * method should provide.
//      *
//      * @return The default context data.
//      */
//     Object get();
// 
//     /**
//      * Gets the context for the specified key.
//      * @param key The key for the desired context data.
//      * @return The context data.
//      */
//     Object get(String key);
// 
//     /**
//      * Gets a {@code Map} version of the context. The Map should be immutable.
//      * @return A {@code Map} with the same key/value pairs as this context.
//      */
//     Map<String, Object> asMap();
// }


import com.bazaarvoice.ostrich.PartitionContext;
import com.bazaarvoice.ostrich.RetryPolicy;
import com.bazaarvoice.ostrich.ServiceCallback;
import com.bazaarvoice.ostrich.ServiceEndPoint;
import com.bazaarvoice.ostrich.ServiceEndPointPredicate;
import com.bazaarvoice.ostrich.exceptions.MaxRetriesException;
import com.codahale.metrics.MetricRegistry;
import com.google.common.base.Ticker;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Closeables;
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.RETURNS_MOCKS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
        new AsyncServicePool<>(_mockTicker, _mockPool, true, null, true, _metricRegistry);
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testSubmitsCallableToExecutor() {
        AsyncServicePool<Service> pool = newAsyncPool();
        pool.execute(NEVER_RETRY, mock(ServiceCallback.class));

        verify(_mockExecutor).submit(any(Callable.class));
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testExecutesCallbackInPool() {
        // Use a real executor so that it can actually call into the callback
        AsyncServicePool<Service> pool = newAsyncPool(MoreExecutors.newDirectExecutorService());

        ServiceCallback<Service, Void> callback = (ServiceCallback<Service, Void>) mock(ServiceCallback.class);
        pool.execute(NEVER_RETRY, callback);

        verify(_mockPool).execute(same(NEVER_RETRY), same(callback));
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testExecutesPartitionContextInPool() {
        AsyncServicePool<Service> pool = newAsyncPool(MoreExecutors.newDirectExecutorService());

        ServiceCallback<Service, Void> callback = (ServiceCallback<Service, Void>) mock(ServiceCallback.class);
// Path: core/src/main/java/com/bazaarvoice/ostrich/PartitionContext.java
// public interface PartitionContext {
//     /**
//      * Gets the default piece of context. In many cases, there is only a single piece of relevant context, which this
//      * method should provide.
//      *
//      * @return The default context data.
//      */
//     Object get();
// 
//     /**
//      * Gets the context for the specified key.
//      * @param key The key for the desired context data.
//      * @return The context data.
//      */
//     Object get(String key);
// 
//     /**
//      * Gets a {@code Map} version of the context. The Map should be immutable.
//      * @return A {@code Map} with the same key/value pairs as this context.
//      */
//     Map<String, Object> asMap();
// }


// Path: core/src/test/java/com/bazaarvoice/ostrich/pool/AsyncServicePoolTest.java
import com.bazaarvoice.ostrich.PartitionContext;
import com.bazaarvoice.ostrich.RetryPolicy;
import com.bazaarvoice.ostrich.ServiceCallback;
import com.bazaarvoice.ostrich.ServiceEndPoint;
import com.bazaarvoice.ostrich.ServiceEndPointPredicate;
import com.bazaarvoice.ostrich.exceptions.MaxRetriesException;
import com.codahale.metrics.MetricRegistry;
import com.google.common.base.Ticker;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Closeables;
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.RETURNS_MOCKS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

        new AsyncServicePool<>(_mockTicker, _mockPool, true, null, true, _metricRegistry);
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testSubmitsCallableToExecutor() {
        AsyncServicePool<Service> pool = newAsyncPool();
        pool.execute(NEVER_RETRY, mock(ServiceCallback.class));

        verify(_mockExecutor).submit(any(Callable.class));
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testExecutesCallbackInPool() {
        // Use a real executor so that it can actually call into the callback
        AsyncServicePool<Service> pool = newAsyncPool(MoreExecutors.newDirectExecutorService());

        ServiceCallback<Service, Void> callback = (ServiceCallback<Service, Void>) mock(ServiceCallback.class);
        pool.execute(NEVER_RETRY, callback);

        verify(_mockPool).execute(same(NEVER_RETRY), same(callback));
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testExecutesPartitionContextInPool() {
        AsyncServicePool<Service> pool = newAsyncPool(MoreExecutors.newDirectExecutorService());

        ServiceCallback<Service, Void> callback = (ServiceCallback<Service, Void>) mock(ServiceCallback.class);
        PartitionContext context = mock(PartitionContext.class);