// Path: src/main/java/tv/ustream/yolo/config/ConfigException.java
// public class ConfigException extends Exception
// {
// 
//     public ConfigException(final String message)
//     {
//         super("Configuration error: " + message);
//     }
// 
// }
// 
// Path: src/main/java/tv/ustream/yolo/module/parser/IParser.java
// public interface IParser extends IModule
// {
// 
//     Map<String, Object> parse(String line);
// 
//     boolean runAlways();
// 
//     List<String> getOutputKeys();
// 
// }
// 
// Path: src/main/java/tv/ustream/yolo/module/processor/CompositeProcessor.java
// public class CompositeProcessor implements ICompositeProcessor
// {
// 
//     private final List<IProcessor> processors = new ArrayList<IProcessor>();
// 
//     @Override
//     public void process(final Map<String, Object> parserOutput, final Map<String, Object> processParams)
//     {
//         for (IProcessor processor : processors)
//         {
//             processor.process(parserOutput, processParams);
//         }
//     }
// 
//     @Override
//     public ConfigMap getProcessParamsConfig()
//     {
//         ConfigMap config = new ConfigMap();
//         for (IProcessor processor : processors)
//         {
//             config.merge(processor.getProcessParamsConfig());
//         }
//         return config;
//     }
// 
//     @Override
//     public void setUpModule(final Map<String, Object> parameters)
//     {
//     }
// 
//     @Override
//     public ConfigMap getModuleConfig()
//     {
//         ConfigMap config = new ConfigMap();
//         config.addConfigValue("processors", List.class);
//         return config;
//     }
// 
//     @Override
//     public String getModuleDescription()
//     {
//         return "runs multiple processors";
//     }
// 
//     @Override
//     public void addProcessor(final IProcessor processor)
//     {
//         processors.add(processor);
//     }
// 
//     @Override
//     public void stop()
//     {
//     }
// 
// }
// 
// Path: src/main/java/tv/ustream/yolo/module/processor/IProcessor.java
// public interface IProcessor extends IModule
// {
// 
//     ConfigMap getProcessParamsConfig();
// 
//     void process(Map<String, Object> parserOutput, Map<String, Object> processParams);
// 
//     void stop();
// 
// }


import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import tv.ustream.yolo.config.ConfigException;
import tv.ustream.yolo.module.parser.IParser;
import tv.ustream.yolo.module.processor.CompositeProcessor;
import tv.ustream.yolo.module.processor.IProcessor;
import static org.mockito.Mockito.anyMap;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
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;
    @Before
    public void setUp() throws Exception
    {
        ModuleFactory moduleFactory = mock(ModuleFactory.class);
        parser1 = mock(IParser.class);
        parser2 = mock(IParser.class);
        processor1 = mock(IProcessor.class);
        processor2 = mock(IProcessor.class);

        Map<String, Object> pr3Config = new HashMap<String, Object>();
        pr3Config.put("class", CompositeProcessor.class.getCanonicalName());
        pr3Config.put("processors", Arrays.asList("pr1", "pr2"));

        IProcessor processor3 = new ModuleFactory().createProcessor("pr3", pr3Config);

        when(moduleFactory.createParser(eq("pa1"), anyMap())).thenReturn(parser1);
        when(moduleFactory.createParser(eq("pa2"), anyMap())).thenReturn(parser2);
        when(moduleFactory.createParser(eq("pa3"), anyMap())).thenReturn(null);
        when(moduleFactory.createProcessor(eq("pr1"), anyMap())).thenReturn(processor1);
        when(moduleFactory.createProcessor(eq("pr2"), anyMap())).thenReturn(processor2);
        when(moduleFactory.createProcessor(eq("pr3"), anyMap())).thenReturn(processor3);

        moduleChain = new ModuleChain(moduleFactory);
    }

    @Test
    public void parserAndProcessorShouldBeAdded() throws Exception
    {
        Map<String, Object> config = new HashMap<String, Object>();

// Path: src/main/java/tv/ustream/yolo/config/ConfigException.java
// public class ConfigException extends Exception
// {
// 
//     public ConfigException(final String message)
//     {
//         super("Configuration error: " + message);
//     }
// 
// }
// 
// Path: src/main/java/tv/ustream/yolo/module/parser/IParser.java
// public interface IParser extends IModule
// {
// 
//     Map<String, Object> parse(String line);
// 
//     boolean runAlways();
// 
//     List<String> getOutputKeys();
// 
// }
// 
// Path: src/main/java/tv/ustream/yolo/module/processor/CompositeProcessor.java
// public class CompositeProcessor implements ICompositeProcessor
// {
// 
//     private final List<IProcessor> processors = new ArrayList<IProcessor>();
// 
//     @Override
//     public void process(final Map<String, Object> parserOutput, final Map<String, Object> processParams)
//     {
//         for (IProcessor processor : processors)
//         {
//             processor.process(parserOutput, processParams);
//         }
//     }
// 
//     @Override
//     public ConfigMap getProcessParamsConfig()
//     {
//         ConfigMap config = new ConfigMap();
//         for (IProcessor processor : processors)
//         {
//             config.merge(processor.getProcessParamsConfig());
//         }
//         return config;
//     }
// 
//     @Override
//     public void setUpModule(final Map<String, Object> parameters)
//     {
//     }
// 
//     @Override
//     public ConfigMap getModuleConfig()
//     {
//         ConfigMap config = new ConfigMap();
//         config.addConfigValue("processors", List.class);
//         return config;
//     }
// 
//     @Override
//     public String getModuleDescription()
//     {
//         return "runs multiple processors";
//     }
// 
//     @Override
//     public void addProcessor(final IProcessor processor)
//     {
//         processors.add(processor);
//     }
// 
//     @Override
//     public void stop()
//     {
//     }
// 
// }
// 
// Path: src/main/java/tv/ustream/yolo/module/processor/IProcessor.java
// public interface IProcessor extends IModule
// {
// 
//     ConfigMap getProcessParamsConfig();
// 
//     void process(Map<String, Object> parserOutput, Map<String, Object> processParams);
// 
//     void stop();
// 
// }


// Path: src/test/java/tv/ustream/yolo/module/ModuleChainTest.java
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import tv.ustream.yolo.config.ConfigException;
import tv.ustream.yolo.module.parser.IParser;
import tv.ustream.yolo.module.processor.CompositeProcessor;
import tv.ustream.yolo.module.processor.IProcessor;
import static org.mockito.Mockito.anyMap;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
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;

    @Before
    public void setUp() throws Exception
    {
        ModuleFactory moduleFactory = mock(ModuleFactory.class);
        parser1 = mock(IParser.class);
        parser2 = mock(IParser.class);
        processor1 = mock(IProcessor.class);
        processor2 = mock(IProcessor.class);

        Map<String, Object> pr3Config = new HashMap<String, Object>();
        pr3Config.put("class", CompositeProcessor.class.getCanonicalName());
        pr3Config.put("processors", Arrays.asList("pr1", "pr2"));

        IProcessor processor3 = new ModuleFactory().createProcessor("pr3", pr3Config);

        when(moduleFactory.createParser(eq("pa1"), anyMap())).thenReturn(parser1);
        when(moduleFactory.createParser(eq("pa2"), anyMap())).thenReturn(parser2);
        when(moduleFactory.createParser(eq("pa3"), anyMap())).thenReturn(null);
        when(moduleFactory.createProcessor(eq("pr1"), anyMap())).thenReturn(processor1);
        when(moduleFactory.createProcessor(eq("pr2"), anyMap())).thenReturn(processor2);
        when(moduleFactory.createProcessor(eq("pr3"), anyMap())).thenReturn(processor3);

        moduleChain = new ModuleChain(moduleFactory);
    }

    @Test
    public void parserAndProcessorShouldBeAdded() throws Exception
    {
        Map<String, Object> config = new HashMap<String, Object>();

        addModule(config, "processors", "pr1", createProcessorConfig("processor1"));