/*
 * Copyright (c) 2013-2016 Cinchapi Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.cinchapi.concourse.server.plugin;

import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import com.cinchapi.concourse.server.plugin.io.SharedMemory;
import com.cinchapi.concourse.thrift.AccessToken;

/**
 * Factory and utility methods for creating executors that are specifically
 * designed for {@link Plugin} implementations.
 * 
 * @author Jeff Nelson
 */
public final class PluginExecutors {

    /**
     * Return a new {@link BackgroundExecutor} that uses a cached thread pool.
     * 
     * @param outgoing the {@link SharedMemory} channel on which outgoing
     *            requests to the upstream service are placed
     * @param responses a queue where responses from the upstream service may be
     *            placed
     * @return the {@link BackgroundExecutor}
     */
    public static BackgroundExecutor newCachedBackgroundExecutor(
            SharedMemory outgoing,
            ConcurrentMap<AccessToken, RemoteMethodResponse> responses) {
        return new CachedBackgroundExecutor("", outgoing, responses);
    }

    private PluginExecutors() {/* no-op */}

    /**
     * Default and simple implementation of the {@link BackgroundExecutor}
     * interface that uses a cached thread pool.
     * 
     * @author Jeff Nelson
     */
    private static class CachedBackgroundExecutor implements BackgroundExecutor {

        /**
         * The {@link ExecutorService} to which requests are delegated.
         */
        private final ExecutorService delegate;

        /**
         * Construct a new instance.
         * 
         * @param environment
         * @param outgoing
         * @param responses
         */
        public CachedBackgroundExecutor(String environment,
                SharedMemory outgoing,
                ConcurrentMap<AccessToken, RemoteMethodResponse> responses) {
            ThreadFactory factory = new ThreadFactory() {

                @Override
                public Thread newThread(Runnable runnable) {
                    BackgroundThread thread = new BackgroundThread(runnable,
                            environment, outgoing, responses);
                    return thread;
                }
            };
            delegate = Executors.newCachedThreadPool(factory);
        }

        @Override
        public void execute(String environment, Runnable runnable) {
            delegate.execute(() -> {
                BackgroundThread thread = (BackgroundThread) Thread
                        .currentThread();
                thread.environment(environment);
                runnable.run();
            });
        }
    }

}

@@ -816,16 +816,90 @@
 ctory;%0A%0A
+import com.cinchapi.concourse.server.plugin.Plugin.BackgroundInformation;%0A
 import c
@@ -1000,16 +1000,72 @@
 ssToken;
+%0Aimport com.google.common.annotations.VisibleForTesting;
 %0A%0A/**%0A *
@@ -1251,24 +1251,503 @@
 xecutors %7B%0A%0A
+    /**%0A     * Return a new %7B@link BackgroundExecutor%7D that uses a cached thread pool.%0A     * %0A     * @param info retrieved from%0A     *            %7B@link com.cinchapi.concourse.server.plugin.Plugin#backgroundInformation()%7D%0A     * %0A     * @return the %7B@link BackgroundExecutor%7D%0A     */%0A    public static BackgroundExecutor newCachedBackgroundExecutor(%0A            BackgroundInformation info) %7B%0A        return newCachedBackgroundExecutor(info.outgoing(), info.responses());%0A    %7D%0A%0A
     /**%0A    
@@ -2121,38 +2121,64 @@
 or%7D%0A     */%0A    
-public
+@VisibleForTesting%0A    protected
  static Backgrou

add public static factory for creating CachedBackgroundExecutor that takes in single BackgroundInformation as a parameter