// Path: src/main/java/io/jvoid/instrumentation/provider/ProviderCatalog.java
// @Singleton
// public class ProviderCatalog {
// 
//     private List<InstrumentationProvider> registeredProviders = new ArrayList<>();
// 
//     // This is still "hardcoded" providers. Make it discover the providers in
//     // the classpath automatically
//     @Inject
//     public void initializeProviders(AppInstrumentationProvider appInstrumentationProvider,
//             SpockInstrumentationProvider spockInstrumentationProvider,
//             JUnitInstrumentationProvider junitInstrumentationProvider) {
//         registeredProviders.add(appInstrumentationProvider);
//         registeredProviders.add(spockInstrumentationProvider);
//         registeredProviders.add(junitInstrumentationProvider);
//     }
// 
//     public void addProvider(InstrumentationProvider provider) {
//         registeredProviders.add(provider);
//     }
// 
//     public Set<InstrumentationProvider> getProvidersForClass(CtClass ctClass) {
//         Set<InstrumentationProvider> providers = new LinkedHashSet<>();
//         for (InstrumentationProvider provider : registeredProviders) {
//             if (provider.matches(ctClass)) {
//                 providers.add(provider);
//             }
//         }
//         return providers;
//     }
// 
// }
// 
// Path: src/main/java/io/jvoid/instrumentation/provider/api/ClassHandler.java
// public interface ClassHandler {
// 
//     void handleClass(CtClass ctClass) throws CannotCompileException;
// 
// }
// 
// Path: src/main/java/io/jvoid/instrumentation/provider/api/InstrumentationProvider.java
// public interface InstrumentationProvider {
// 
//     boolean matches(CtClass ctClass);
// 
//     List<ClassHandler> getClassHandlers(CtClass ctClass);
// 
//     List<MethodInstrumenter> getMethodInstrumenters(CtMethod ctMethod);
// 
// }
// 
// Path: src/main/java/io/jvoid/instrumentation/provider/api/MethodInstrumenter.java
// public interface MethodInstrumenter {
// 
//     void instrument(CtMethod ctMethod) throws CannotCompileException;
// 
//     boolean shouldInstrument(CtMethod ctMethod);
// 
// }
// 
// Path: src/test/java/io/jvoid/test/AbstractJVoidTest.java
// @UseModules({ JVoidModule.class })
// @RunWith(JVoidTestRunner.class)
// public abstract class AbstractJVoidTest {
// 
//     protected static final String DEFAULT_TEST_CONFIGURATION_FILE = "./src/test/resources/test-jvoid.config";
// 
//     private static ThreadLocal<Long> currentExecutionId = new ThreadLocal<>(); // Parallel tests?
// 
//     protected static final ClassPool classPool;
// 
//     @Inject
//     protected MetadataDatabase metadataDatabase;
// 
//     @Inject
//     protected JVoidInstrumentationHelper instrumentationHelper;
// 
//     @Inject
//     protected ExecutionsRepository executionsRepository;
// 
//     @Inject
//     protected JVoidExecutionContext jvoidExecutionContext;
// 
//     static {
//         // See ClassPool JavaDoc for memory consumption issues
//         ClassPool.doPruning = true;
//         classPool = ClassPool.getDefault();
//     }
// 
//     @Before
//     public void setUp() throws Exception {
//         // Make sure the database is initialized
//         metadataDatabase.startup();
// 
//         // Makes sure that the database is clean, then restarts it to apply the migrations.
//         // To be sure that each test runs in its own clean db environment.
//         // TODO: Can this be more elegant?
//         DbUtils.executeUpdate(metadataDatabase, "DROP ALL OBJECTS");
//         metadataDatabase.shutdown();
//         metadataDatabase.startup();
// 
//         currentExecutionId.set(0L);
//     }
// 
//     @After
//     public void tearDown() {
//         metadataDatabase.shutdown();
//         JVoidInstrumentationHelperHolder.getInstance().set(instrumentationHelper);
//     }
// 
//     /*
//      * Utility methods for current JExecution
//      */
//     protected Long getCurrentExecutionId() {
//         return currentExecutionId.get();
//     }
// 
//     protected synchronized JExecution setupCurrentExecution() {
//         return setupCurrentExecution(null);
//     }
// 
//     protected synchronized JExecution setupCurrentExecution(Long timestamp) {
//         JExecution currentExecution = new JExecution();
//         currentExecution.setTimestamp(timestamp == null ? System.currentTimeMillis() : timestamp);
//         currentExecution = executionsRepository.add(currentExecution);
//         currentExecutionId.set(currentExecution.getId());
//         jvoidExecutionContext.setCurrentExecution(currentExecution);
//         return currentExecution;
//     }
// }


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import io.jvoid.instrumentation.provider.ProviderCatalog;
import io.jvoid.instrumentation.provider.api.ClassHandler;
import io.jvoid.instrumentation.provider.api.InstrumentationProvider;
import io.jvoid.instrumentation.provider.api.MethodInstrumenter;
import io.jvoid.test.AbstractJVoidTest;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
package io.jvoid.test.instrumentation.provider;





public class ProviderCatalogTest extends AbstractJVoidTest {

    private CtClass ctTestClass1, ctTestClass2;

    private ProviderCatalog providerCatalog;

    @Override
    @Before
    public void setUp() throws NotFoundException {
        ctTestClass1 = classPool.get(TestClass1.class.getName());
        ctTestClass2 = classPool.get(TestClass2.class.getName());
// Path: src/main/java/io/jvoid/instrumentation/provider/ProviderCatalog.java
// @Singleton
// public class ProviderCatalog {
// 
//     private List<InstrumentationProvider> registeredProviders = new ArrayList<>();
// 
//     // This is still "hardcoded" providers. Make it discover the providers in
//     // the classpath automatically
//     @Inject
//     public void initializeProviders(AppInstrumentationProvider appInstrumentationProvider,
//             SpockInstrumentationProvider spockInstrumentationProvider,
//             JUnitInstrumentationProvider junitInstrumentationProvider) {
//         registeredProviders.add(appInstrumentationProvider);
//         registeredProviders.add(spockInstrumentationProvider);
//         registeredProviders.add(junitInstrumentationProvider);
//     }
// 
//     public void addProvider(InstrumentationProvider provider) {
//         registeredProviders.add(provider);
//     }
// 
//     public Set<InstrumentationProvider> getProvidersForClass(CtClass ctClass) {
//         Set<InstrumentationProvider> providers = new LinkedHashSet<>();
//         for (InstrumentationProvider provider : registeredProviders) {
//             if (provider.matches(ctClass)) {
//                 providers.add(provider);
//             }
//         }
//         return providers;
//     }
// 
// }
// 
// Path: src/main/java/io/jvoid/instrumentation/provider/api/ClassHandler.java
// public interface ClassHandler {
// 
//     void handleClass(CtClass ctClass) throws CannotCompileException;
// 
// }
// 
// Path: src/main/java/io/jvoid/instrumentation/provider/api/InstrumentationProvider.java
// public interface InstrumentationProvider {
// 
//     boolean matches(CtClass ctClass);
// 
//     List<ClassHandler> getClassHandlers(CtClass ctClass);
// 
//     List<MethodInstrumenter> getMethodInstrumenters(CtMethod ctMethod);
// 
// }
// 
// Path: src/main/java/io/jvoid/instrumentation/provider/api/MethodInstrumenter.java
// public interface MethodInstrumenter {
// 
//     void instrument(CtMethod ctMethod) throws CannotCompileException;
// 
//     boolean shouldInstrument(CtMethod ctMethod);
// 
// }
// 
// Path: src/test/java/io/jvoid/test/AbstractJVoidTest.java
// @UseModules({ JVoidModule.class })
// @RunWith(JVoidTestRunner.class)
// public abstract class AbstractJVoidTest {
// 
//     protected static final String DEFAULT_TEST_CONFIGURATION_FILE = "./src/test/resources/test-jvoid.config";
// 
//     private static ThreadLocal<Long> currentExecutionId = new ThreadLocal<>(); // Parallel tests?
// 
//     protected static final ClassPool classPool;
// 
//     @Inject
//     protected MetadataDatabase metadataDatabase;
// 
//     @Inject
//     protected JVoidInstrumentationHelper instrumentationHelper;
// 
//     @Inject
//     protected ExecutionsRepository executionsRepository;
// 
//     @Inject
//     protected JVoidExecutionContext jvoidExecutionContext;
// 
//     static {
//         // See ClassPool JavaDoc for memory consumption issues
//         ClassPool.doPruning = true;
//         classPool = ClassPool.getDefault();
//     }
// 
//     @Before
//     public void setUp() throws Exception {
//         // Make sure the database is initialized
//         metadataDatabase.startup();
// 
//         // Makes sure that the database is clean, then restarts it to apply the migrations.
//         // To be sure that each test runs in its own clean db environment.
//         // TODO: Can this be more elegant?
//         DbUtils.executeUpdate(metadataDatabase, "DROP ALL OBJECTS");
//         metadataDatabase.shutdown();
//         metadataDatabase.startup();
// 
//         currentExecutionId.set(0L);
//     }
// 
//     @After
//     public void tearDown() {
//         metadataDatabase.shutdown();
//         JVoidInstrumentationHelperHolder.getInstance().set(instrumentationHelper);
//     }
// 
//     /*
//      * Utility methods for current JExecution
//      */
//     protected Long getCurrentExecutionId() {
//         return currentExecutionId.get();
//     }
// 
//     protected synchronized JExecution setupCurrentExecution() {
//         return setupCurrentExecution(null);
//     }
// 
//     protected synchronized JExecution setupCurrentExecution(Long timestamp) {
//         JExecution currentExecution = new JExecution();
//         currentExecution.setTimestamp(timestamp == null ? System.currentTimeMillis() : timestamp);
//         currentExecution = executionsRepository.add(currentExecution);
//         currentExecutionId.set(currentExecution.getId());
//         jvoidExecutionContext.setCurrentExecution(currentExecution);
//         return currentExecution;
//     }
// }


// Path: src/test/java/io/jvoid/test/instrumentation/provider/ProviderCatalogTest.java
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import io.jvoid.instrumentation.provider.ProviderCatalog;
import io.jvoid.instrumentation.provider.api.ClassHandler;
import io.jvoid.instrumentation.provider.api.InstrumentationProvider;
import io.jvoid.instrumentation.provider.api.MethodInstrumenter;
import io.jvoid.test.AbstractJVoidTest;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

package io.jvoid.test.instrumentation.provider;





public class ProviderCatalogTest extends AbstractJVoidTest {

    private CtClass ctTestClass1, ctTestClass2;

    private ProviderCatalog providerCatalog;

    @Override
    @Before
    public void setUp() throws NotFoundException {
        ctTestClass1 = classPool.get(TestClass1.class.getName());
        ctTestClass2 = classPool.get(TestClass2.class.getName());
        providerCatalog = new ProviderCatalog();