// Path: easymvp-weaver/src/main/java/easymvp/weaver/JavassistUtils.java
// static String[] ctClassToString(CtClass[] params) {
//     String[] strings = new String[params.length];
//     for (int i = 0; i < params.length; i++) {
//         strings[i] = params[i].getName();
//     }
//     return strings;
// }
// 
// Path: easymvp-weaver/src/main/java/easymvp/weaver/JavassistUtils.java
// static boolean sameSignature(List<String> parameters, CtMethod method)
//         throws NotFoundException {
//     CtClass[] methodParameters = method.getParameterTypes();
//     if (methodParameters.length == 0 && parameters.size() == 0) return true;
//     if (methodParameters.length != 0 && parameters.size() == 0) return false;
//     if (methodParameters.length == 0 && parameters.size() != 0) return false;
//     for (CtClass clazz : method.getParameterTypes()) {
//         if (!parameters.contains(clazz.getName())) return false;
//     }
//     return true;
// }
// 
// Path: easymvp-weaver/src/main/java/easymvp/weaver/JavassistUtils.java
// static CtClass[] stringToCtClass(ClassPool pool, String[] params)
//         throws NotFoundException {
//     CtClass[] ctClasses = new CtClass[params.length];
//     for (int i = 0; i < params.length; i++) {
//         ctClasses[i] = pool.get(params[i]);
//     }
//     return ctClasses;
// }


import weaver.processor.WeaverProcessor;
import static easymvp.weaver.JavassistUtils.ctClassToString;
import static easymvp.weaver.JavassistUtils.sameSignature;
import static easymvp.weaver.JavassistUtils.stringToCtClass;
import easymvp.annotation.ActivityView;
import easymvp.annotation.CustomView;
import easymvp.annotation.FragmentView;
import easymvp.annotation.conductor.ConductorController;
import java.util.Arrays;
import java.util.Set;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import weaver.common.WeaveEnvironment;
import weaver.instrumentation.injection.ClassInjector;
        AfterSuper(classInjector, onAttachedToWindow,
                applied ? STATEMENT_CALL_INITIALIZE_WITH_FACTORY : STATEMENT_CALL_INITIALIZE);
        //        afterSuperWithReturnType(classInjector, onDetachedFromWindow, STATEMENT_CALL_DETACH);

    }

    private void injectDelegateLifeCycleIntoConductorController(CtClass ctClass,
            ClassInjector classInjector) throws Exception {
        CtMethod onCreateView =
                findBestMethod(ctClass, "onCreateView", LAYOUT_INFLATER_CLASS, VIEW_GROUP_CLASS);
        CtMethod onAttach = findBestMethod(ctClass, "onAttach", VIEW_CLASS);
        CtMethod onDetach = findBestMethod(ctClass, "onDetach", VIEW_CLASS);
        CtMethod onDestroy = findBestMethod(ctClass, "onDestroy");
        boolean applied = dagger2Extension.apply(ctClass);
        afterSuperWithReturnType(classInjector, onCreateView,
                applied ? STATEMENT_CALL_INITIALIZE_WITH_FACTORY : STATEMENT_CALL_INITIALIZE, true);
        AfterSuper(classInjector, onAttach, STATEMENT_CALL_ATTACH);
        beforeSuper(classInjector, onDetach, STATEMENT_CALL_DETACH);
        beforeSuper(classInjector, onDestroy, STATEMENT_CALL_DESTROY);
    }

    /**
     * It is possible that aspectj already manipulated this method, so in this case we should inject
     * our code into {@code methodName_aroundBodyX()} which X is the lowest number of all similar
     * methods to {@code methodName_aroundBody}.
     */
    private CtMethod findBestMethod(CtClass ctClass, String methodName, String... params)
            throws NotFoundException {
        CtMethod baseMethod = null;
        try {
// Path: easymvp-weaver/src/main/java/easymvp/weaver/JavassistUtils.java
// static String[] ctClassToString(CtClass[] params) {
//     String[] strings = new String[params.length];
//     for (int i = 0; i < params.length; i++) {
//         strings[i] = params[i].getName();
//     }
//     return strings;
// }
// 
// Path: easymvp-weaver/src/main/java/easymvp/weaver/JavassistUtils.java
// static boolean sameSignature(List<String> parameters, CtMethod method)
//         throws NotFoundException {
//     CtClass[] methodParameters = method.getParameterTypes();
//     if (methodParameters.length == 0 && parameters.size() == 0) return true;
//     if (methodParameters.length != 0 && parameters.size() == 0) return false;
//     if (methodParameters.length == 0 && parameters.size() != 0) return false;
//     for (CtClass clazz : method.getParameterTypes()) {
//         if (!parameters.contains(clazz.getName())) return false;
//     }
//     return true;
// }
// 
// Path: easymvp-weaver/src/main/java/easymvp/weaver/JavassistUtils.java
// static CtClass[] stringToCtClass(ClassPool pool, String[] params)
//         throws NotFoundException {
//     CtClass[] ctClasses = new CtClass[params.length];
//     for (int i = 0; i < params.length; i++) {
//         ctClasses[i] = pool.get(params[i]);
//     }
//     return ctClasses;
// }


// Path: easymvp-weaver/src/main/java/easymvp/weaver/ViewDelegateBinder.java
import weaver.processor.WeaverProcessor;
import static easymvp.weaver.JavassistUtils.ctClassToString;
import static easymvp.weaver.JavassistUtils.sameSignature;
import static easymvp.weaver.JavassistUtils.stringToCtClass;
import easymvp.annotation.ActivityView;
import easymvp.annotation.CustomView;
import easymvp.annotation.FragmentView;
import easymvp.annotation.conductor.ConductorController;
import java.util.Arrays;
import java.util.Set;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import weaver.common.WeaveEnvironment;
import weaver.instrumentation.injection.ClassInjector;

        AfterSuper(classInjector, onAttachedToWindow,
                applied ? STATEMENT_CALL_INITIALIZE_WITH_FACTORY : STATEMENT_CALL_INITIALIZE);
        //        afterSuperWithReturnType(classInjector, onDetachedFromWindow, STATEMENT_CALL_DETACH);

    }

    private void injectDelegateLifeCycleIntoConductorController(CtClass ctClass,
            ClassInjector classInjector) throws Exception {
        CtMethod onCreateView =
                findBestMethod(ctClass, "onCreateView", LAYOUT_INFLATER_CLASS, VIEW_GROUP_CLASS);
        CtMethod onAttach = findBestMethod(ctClass, "onAttach", VIEW_CLASS);
        CtMethod onDetach = findBestMethod(ctClass, "onDetach", VIEW_CLASS);
        CtMethod onDestroy = findBestMethod(ctClass, "onDestroy");
        boolean applied = dagger2Extension.apply(ctClass);
        afterSuperWithReturnType(classInjector, onCreateView,
                applied ? STATEMENT_CALL_INITIALIZE_WITH_FACTORY : STATEMENT_CALL_INITIALIZE, true);
        AfterSuper(classInjector, onAttach, STATEMENT_CALL_ATTACH);
        beforeSuper(classInjector, onDetach, STATEMENT_CALL_DETACH);
        beforeSuper(classInjector, onDestroy, STATEMENT_CALL_DESTROY);
    }

    /**
     * It is possible that aspectj already manipulated this method, so in this case we should inject
     * our code into {@code methodName_aroundBodyX()} which X is the lowest number of all similar
     * methods to {@code methodName_aroundBody}.
     */
    private CtMethod findBestMethod(CtClass ctClass, String methodName, String... params)
            throws NotFoundException {
        CtMethod baseMethod = null;
        try {
            baseMethod = ctClass.getDeclaredMethod(methodName, stringToCtClass(pool, params));