// Path: src/main/java/io/jvoid/instrumentation/provider/app/AppHeuristicHelper.java
// public class AppHeuristicHelper {
// 
//     public static boolean isCGLIBProxy(CtClass ctClass) {
//         String name = ctClass.getName();
//         return name.contains("$$") || name.contains("CGLIB");
//         
//     }
//     public static boolean isCGLIBProxy(CtMethod ctMethod) {
//         String methodName = ctMethod.getLongName();
//         return methodName.contains("$$") || methodName.contains("CGLIB");
//     }
// 
//     public static boolean isGroovyCallSite(CtClass ctClass) {
//         try {
//             CtClass superclass = ctClass.getSuperclass();
//             return superclass != null && superclass.getName().startsWith("org.codehaus.groovy.runtime.callsite");
//         } catch (Exception e) {
//             return false; // Being conservative here...
//         }
//     }
// 
//     public static boolean isJacocoField(CtField ctField) {
//         String methodName = ctField.getName();
//         return methodName.startsWith("$jacoco");
//     }
//     
//     public static boolean isGeneratedField(CtField ctField) {
//         String methodName = ctField.getName();
//         return methodName.startsWith("$$");
//     }
// 
//     public static boolean isJacocoMethod(CtMethod ctMethod) {
//         String methodName = ctMethod.getLongName();
//         return methodName.contains("$jacoco");
//     }
// 
// }
// 
// 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.assertFalse;
import static org.junit.Assert.assertTrue;
import org.codehaus.groovy.runtime.callsite.CallSiteArray;
import org.junit.Test;
import io.jvoid.instrumentation.provider.app.AppHeuristicHelper;
import io.jvoid.test.AbstractJVoidTest;
import javassist.CtClass;
package io.jvoid.test.instrumentation.provider.app;




public class AppHeuristicHelperTest extends AbstractJVoidTest {

    @Test
    public void testHeuristicCglib() throws Exception {
        CtClass cglibMock = classPool.get(ClassWithCglibMethods.class.getName());
        assertTrue(AppHeuristicHelper.isCGLIBProxy(cglibMock.getDeclaredMethod("this$$ShouldBeCaught")));
        assertTrue(AppHeuristicHelper.isCGLIBProxy(cglibMock.getDeclaredMethod("thatOneWithCGLIBShouldBeCaught")));
        assertFalse(AppHeuristicHelper.isCGLIBProxy(cglibMock.getDeclaredMethod("this$Should$Be$Fine")));
        cglibMock.prune();
    }

    @Test
    public void testHeuristicGroovyCallsite() throws Exception {
        CtClass groovyCallsiteMock = classPool.get(MockGroovyCallsite.class.getName());
        CtClass cglibMock = classPool.get(ClassWithCglibMethods.class.getName());
        assertTrue(AppHeuristicHelper.isGroovyCallSite(groovyCallsiteMock));
        assertFalse(AppHeuristicHelper.isGroovyCallSite(cglibMock));
        groovyCallsiteMock.prune();
        cglibMock.prune();
    }

    @Test
    public void testHeuristicJacoco() throws Exception {
        CtClass cglibMock = classPool.get(ClassWithCglibMethods.class.getName());
        assertTrue(AppHeuristicHelper.isJacocoMethod(cglibMock.getDeclaredMethod("hey$jacocoInit")));
        assertFalse(AppHeuristicHelper.isJacocoMethod(cglibMock.getDeclaredMethod("this$Should$Be$Fine")));
        cglibMock.prune();
    }

    // NOTE That if you put "CGLIB" capitalized, all methods match!
    protected static class ClassWithCglibMethods {
        public void this$$ShouldBeCaught() { }
        public void thatOneWithCGLIBShouldBeCaught() { }
// Path: src/main/java/io/jvoid/instrumentation/provider/app/AppHeuristicHelper.java
// public class AppHeuristicHelper {
// 
//     public static boolean isCGLIBProxy(CtClass ctClass) {
//         String name = ctClass.getName();
//         return name.contains("$$") || name.contains("CGLIB");
//         
//     }
//     public static boolean isCGLIBProxy(CtMethod ctMethod) {
//         String methodName = ctMethod.getLongName();
//         return methodName.contains("$$") || methodName.contains("CGLIB");
//     }
// 
//     public static boolean isGroovyCallSite(CtClass ctClass) {
//         try {
//             CtClass superclass = ctClass.getSuperclass();
//             return superclass != null && superclass.getName().startsWith("org.codehaus.groovy.runtime.callsite");
//         } catch (Exception e) {
//             return false; // Being conservative here...
//         }
//     }
// 
//     public static boolean isJacocoField(CtField ctField) {
//         String methodName = ctField.getName();
//         return methodName.startsWith("$jacoco");
//     }
//     
//     public static boolean isGeneratedField(CtField ctField) {
//         String methodName = ctField.getName();
//         return methodName.startsWith("$$");
//     }
// 
//     public static boolean isJacocoMethod(CtMethod ctMethod) {
//         String methodName = ctMethod.getLongName();
//         return methodName.contains("$jacoco");
//     }
// 
// }
// 
// 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/app/AppHeuristicHelperTest.java
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.codehaus.groovy.runtime.callsite.CallSiteArray;
import org.junit.Test;
import io.jvoid.instrumentation.provider.app.AppHeuristicHelper;
import io.jvoid.test.AbstractJVoidTest;
import javassist.CtClass;

package io.jvoid.test.instrumentation.provider.app;




public class AppHeuristicHelperTest extends AbstractJVoidTest {

    @Test
    public void testHeuristicCglib() throws Exception {
        CtClass cglibMock = classPool.get(ClassWithCglibMethods.class.getName());
        assertTrue(AppHeuristicHelper.isCGLIBProxy(cglibMock.getDeclaredMethod("this$$ShouldBeCaught")));
        assertTrue(AppHeuristicHelper.isCGLIBProxy(cglibMock.getDeclaredMethod("thatOneWithCGLIBShouldBeCaught")));
        assertFalse(AppHeuristicHelper.isCGLIBProxy(cglibMock.getDeclaredMethod("this$Should$Be$Fine")));
        cglibMock.prune();
    }

    @Test
    public void testHeuristicGroovyCallsite() throws Exception {
        CtClass groovyCallsiteMock = classPool.get(MockGroovyCallsite.class.getName());
        CtClass cglibMock = classPool.get(ClassWithCglibMethods.class.getName());
        assertTrue(AppHeuristicHelper.isGroovyCallSite(groovyCallsiteMock));
        assertFalse(AppHeuristicHelper.isGroovyCallSite(cglibMock));
        groovyCallsiteMock.prune();
        cglibMock.prune();
    }

    @Test
    public void testHeuristicJacoco() throws Exception {
        CtClass cglibMock = classPool.get(ClassWithCglibMethods.class.getName());
        assertTrue(AppHeuristicHelper.isJacocoMethod(cglibMock.getDeclaredMethod("hey$jacocoInit")));
        assertFalse(AppHeuristicHelper.isJacocoMethod(cglibMock.getDeclaredMethod("this$Should$Be$Fine")));
        cglibMock.prune();
    }

    // NOTE That if you put "CGLIB" capitalized, all methods match!
    protected static class ClassWithCglibMethods {
        public void this$$ShouldBeCaught() { }
        public void thatOneWithCGLIBShouldBeCaught() { }
        public void this$Should$Be$Fine() { }