// Path: examples/multi-db/key-gen/src/main/java/com/palominolabs/benchpress/example/multidb/key/KeyGeneratorFactoryFactoryRegistry.java
// public final class KeyGeneratorFactoryFactoryRegistry extends IdRegistry<KeyGeneratorFactoryFactory> {
// 
//     @Inject
//     KeyGeneratorFactoryFactoryRegistry(Set<KeyGeneratorFactoryFactory> instances) {
//         super(instances);
//     }
// }
// 
// Path: examples/multi-db/value-gen/src/main/java/com/palominolabs/benchpress/example/multidb/value/ValueGeneratorFactoryFactoryRegistry.java
// public final class ValueGeneratorFactoryFactoryRegistry extends IdRegistry<ValueGeneratorFactoryFactory> {
// 
//     @Inject
//     ValueGeneratorFactoryFactoryRegistry(Set<ValueGeneratorFactoryFactory> instances) {
//         super(instances);
//     }
// }
// 
// Path: job/src/main/java/com/palominolabs/benchpress/job/task/ComponentFactory.java
// public interface ComponentFactory {
//     /**
//      * Read config data out of the config node using the supplied ObjectReader and create a TaskFactory.
//      *
//      * @return a configured task factory
//      */
//     @Nonnull
//     TaskFactory getTaskFactory();
// }
// 
// Path: job/src/main/java/com/palominolabs/benchpress/job/task/ControllerComponentFactory.java
// public interface ControllerComponentFactory {
// 
//     @Nonnull
//     JobSlicer getJobSlicer();
// }
// 
// Path: job/src/main/java/com/palominolabs/benchpress/job/task/JobSlicer.java
// public interface JobSlicer {
// 
//     /**
//      * Split this job into slices, one for each worker.
//      *
//      * @param jobId        the job id being sliced
//      * @param workers      The number of slices to create
//      * @param progressUrl  The URL to send progress reports to
//      * @param finishedUrl  The URL to send finished report to
//      * @param objectReader objectReader configured like objectWriter
//      * @param objectWriter objectWriter to use to serialize slice task config
//      * @return List of the slices
//      * @throws IOException if slicing fails
//      */
//     @Nonnull
//     List<Task> slice(UUID jobId, int workers, String progressUrl, String finishedUrl,
//                      ObjectReader objectReader, ObjectWriter objectWriter) throws IOException;
// }
// 
// Path: job/src/main/java/com/palominolabs/benchpress/job/task/JobTypePlugin.java
// public interface JobTypePlugin extends Identifiable {
//     /**
//      * Get the components that are used by workers.
//      *
//      * Encapsulates the logic that reads implementation-specific config information from the task json. This way, a
//      * ComponentFactory is fully ready to use and never needs to access its configuration json again.
//      *
//      * @param objectReader the ObjectReader to use to deserialize configNode
//      * @param configNode   the config node for the task as split up by the JobSlicer
//      * @return a configured ComponentFactory
//      * @throws IOException if config parsing fails
//      */
//     @Nonnull
//     ComponentFactory getComponentFactory(ObjectReader objectReader, JsonNode configNode) throws IOException;
// 
//     /**
//      * Get the components that are used by the controller.
//      *
//      * @param objectReader the ObjectReader to use to deserialize configNode
//      * @param configNode   the config node for the job
//      * @return a configured ControllerComponentFactory
//      * @throws IOException if config parsing fails
//      */
//     @Nonnull
//     ControllerComponentFactory getControllerComponentFactory(ObjectReader objectReader, JsonNode configNode) throws
//             IOException;
// }


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectReader;
import com.google.inject.Inject;
import com.palominolabs.benchpress.example.multidb.key.KeyGeneratorFactoryFactoryRegistry;
import com.palominolabs.benchpress.example.multidb.value.ValueGeneratorFactoryFactoryRegistry;
import com.palominolabs.benchpress.job.task.ComponentFactory;
import com.palominolabs.benchpress.job.task.ControllerComponentFactory;
import com.palominolabs.benchpress.job.task.JobSlicer;
import com.palominolabs.benchpress.job.task.JobTypePlugin;
import java.io.IOException;
import javax.annotation.Nonnull;
package com.palominolabs.benchpress.example.multidb.hbaseasync;


final class HbaseAsyncJobTypePlugin implements JobTypePlugin {
    static final String TASK_TYPE = "HBASE_ASYNC";

    private final KeyGeneratorFactoryFactoryRegistry keyGeneratorFactoryFactoryRegistry;
    private final ValueGeneratorFactoryFactoryRegistry valueGeneratorFactoryFactoryRegistry;

    @Inject
    HbaseAsyncJobTypePlugin(KeyGeneratorFactoryFactoryRegistry keyGeneratorFactoryFactoryRegistry,
        ValueGeneratorFactoryFactoryRegistry valueGeneratorFactoryFactoryRegistry) {
        this.keyGeneratorFactoryFactoryRegistry = keyGeneratorFactoryFactoryRegistry;
        this.valueGeneratorFactoryFactoryRegistry = valueGeneratorFactoryFactoryRegistry;
    }

    @Nonnull
    @Override
    public ComponentFactory getComponentFactory(ObjectReader objectReader, JsonNode configNode) throws IOException {
        return new HbaseAsyncComponentFactory(keyGeneratorFactoryFactoryRegistry, valueGeneratorFactoryFactoryRegistry,
            objectReader.forType(HbaseAsyncConfig.class).readValue(configNode));
    }

    @Nonnull
    @Override
    public ControllerComponentFactory getControllerComponentFactory(ObjectReader objectReader,
        JsonNode configNode) throws IOException {
        final HbaseAsyncConfig config = getConfig(objectReader, configNode);
// Path: examples/multi-db/key-gen/src/main/java/com/palominolabs/benchpress/example/multidb/key/KeyGeneratorFactoryFactoryRegistry.java
// public final class KeyGeneratorFactoryFactoryRegistry extends IdRegistry<KeyGeneratorFactoryFactory> {
// 
//     @Inject
//     KeyGeneratorFactoryFactoryRegistry(Set<KeyGeneratorFactoryFactory> instances) {
//         super(instances);
//     }
// }
// 
// Path: examples/multi-db/value-gen/src/main/java/com/palominolabs/benchpress/example/multidb/value/ValueGeneratorFactoryFactoryRegistry.java
// public final class ValueGeneratorFactoryFactoryRegistry extends IdRegistry<ValueGeneratorFactoryFactory> {
// 
//     @Inject
//     ValueGeneratorFactoryFactoryRegistry(Set<ValueGeneratorFactoryFactory> instances) {
//         super(instances);
//     }
// }
// 
// Path: job/src/main/java/com/palominolabs/benchpress/job/task/ComponentFactory.java
// public interface ComponentFactory {
//     /**
//      * Read config data out of the config node using the supplied ObjectReader and create a TaskFactory.
//      *
//      * @return a configured task factory
//      */
//     @Nonnull
//     TaskFactory getTaskFactory();
// }
// 
// Path: job/src/main/java/com/palominolabs/benchpress/job/task/ControllerComponentFactory.java
// public interface ControllerComponentFactory {
// 
//     @Nonnull
//     JobSlicer getJobSlicer();
// }
// 
// Path: job/src/main/java/com/palominolabs/benchpress/job/task/JobSlicer.java
// public interface JobSlicer {
// 
//     /**
//      * Split this job into slices, one for each worker.
//      *
//      * @param jobId        the job id being sliced
//      * @param workers      The number of slices to create
//      * @param progressUrl  The URL to send progress reports to
//      * @param finishedUrl  The URL to send finished report to
//      * @param objectReader objectReader configured like objectWriter
//      * @param objectWriter objectWriter to use to serialize slice task config
//      * @return List of the slices
//      * @throws IOException if slicing fails
//      */
//     @Nonnull
//     List<Task> slice(UUID jobId, int workers, String progressUrl, String finishedUrl,
//                      ObjectReader objectReader, ObjectWriter objectWriter) throws IOException;
// }
// 
// Path: job/src/main/java/com/palominolabs/benchpress/job/task/JobTypePlugin.java
// public interface JobTypePlugin extends Identifiable {
//     /**
//      * Get the components that are used by workers.
//      *
//      * Encapsulates the logic that reads implementation-specific config information from the task json. This way, a
//      * ComponentFactory is fully ready to use and never needs to access its configuration json again.
//      *
//      * @param objectReader the ObjectReader to use to deserialize configNode
//      * @param configNode   the config node for the task as split up by the JobSlicer
//      * @return a configured ComponentFactory
//      * @throws IOException if config parsing fails
//      */
//     @Nonnull
//     ComponentFactory getComponentFactory(ObjectReader objectReader, JsonNode configNode) throws IOException;
// 
//     /**
//      * Get the components that are used by the controller.
//      *
//      * @param objectReader the ObjectReader to use to deserialize configNode
//      * @param configNode   the config node for the job
//      * @return a configured ControllerComponentFactory
//      * @throws IOException if config parsing fails
//      */
//     @Nonnull
//     ControllerComponentFactory getControllerComponentFactory(ObjectReader objectReader, JsonNode configNode) throws
//             IOException;
// }


// Path: examples/multi-db/hbase-async/src/main/java/com/palominolabs/benchpress/example/multidb/hbaseasync/HbaseAsyncJobTypePlugin.java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectReader;
import com.google.inject.Inject;
import com.palominolabs.benchpress.example.multidb.key.KeyGeneratorFactoryFactoryRegistry;
import com.palominolabs.benchpress.example.multidb.value.ValueGeneratorFactoryFactoryRegistry;
import com.palominolabs.benchpress.job.task.ComponentFactory;
import com.palominolabs.benchpress.job.task.ControllerComponentFactory;
import com.palominolabs.benchpress.job.task.JobSlicer;
import com.palominolabs.benchpress.job.task.JobTypePlugin;
import java.io.IOException;
import javax.annotation.Nonnull;

package com.palominolabs.benchpress.example.multidb.hbaseasync;


final class HbaseAsyncJobTypePlugin implements JobTypePlugin {
    static final String TASK_TYPE = "HBASE_ASYNC";

    private final KeyGeneratorFactoryFactoryRegistry keyGeneratorFactoryFactoryRegistry;
    private final ValueGeneratorFactoryFactoryRegistry valueGeneratorFactoryFactoryRegistry;

    @Inject
    HbaseAsyncJobTypePlugin(KeyGeneratorFactoryFactoryRegistry keyGeneratorFactoryFactoryRegistry,
        ValueGeneratorFactoryFactoryRegistry valueGeneratorFactoryFactoryRegistry) {
        this.keyGeneratorFactoryFactoryRegistry = keyGeneratorFactoryFactoryRegistry;
        this.valueGeneratorFactoryFactoryRegistry = valueGeneratorFactoryFactoryRegistry;
    }

    @Nonnull
    @Override
    public ComponentFactory getComponentFactory(ObjectReader objectReader, JsonNode configNode) throws IOException {
        return new HbaseAsyncComponentFactory(keyGeneratorFactoryFactoryRegistry, valueGeneratorFactoryFactoryRegistry,
            objectReader.forType(HbaseAsyncConfig.class).readValue(configNode));
    }

    @Nonnull
    @Override
    public ControllerComponentFactory getControllerComponentFactory(ObjectReader objectReader,
        JsonNode configNode) throws IOException {
        final HbaseAsyncConfig config = getConfig(objectReader, configNode);
        return new ControllerComponentFactory() {