// Path: aircycle-compiler/src/main/java/com/github/simonpercic/aircycle/exception/MethodArgumentsException.java
// public class MethodArgumentsException extends Exception {
// 
//     public MethodArgumentsException(String message) {
//         super(message);
//     }
// }
// 
// Path: aircycle-compiler/src/main/java/com/github/simonpercic/aircycle/model/ListenerMethod.java
// public class ListenerMethod {
// 
//     private final String methodName;
//     private final List<ListenerArgType> args;
// 
//     public ListenerMethod(String methodName, List<ListenerArgType> args) {
//         this.methodName = methodName;
//         this.args = ImmutableList.copyOf(args);
//     }
// 
//     public String getMethodName() {
//         return methodName;
//     }
// 
//     public List<ListenerArgType> getArgs() {
//         return args;
//     }
// 
//     public static Builder builder(ActivityLifecycleType activityLifecycle, String methodName) {
//         if (activityLifecycle == null) {
//             throw new IllegalArgumentException("activityLifecycle is null");
//         }
// 
//         if (StringUtils.isEmpty(methodName)) {
//             throw new IllegalArgumentException("methodName is empty");
//         }
// 
//         return new Builder(activityLifecycle, methodName);
//     }
// 
//     public static class Builder {
// 
//         private final ActivityLifecycleType lifecycleType;
//         private final String methodName;
//         private final List<ListenerArgType> args;
// 
//         private Builder(ActivityLifecycleType lifecycleType, String methodName) {
//             this.lifecycleType = lifecycleType;
//             this.methodName = methodName;
//             this.args = new ArrayList<>(2);
//         }
// 
//         public Builder addBundleArg() throws MethodArgumentsException {
//             if (args.contains(ListenerArgType.BUNDLE)) {
//                 String message = String.format("`bundle` arg already present in `%s`", methodName);
//                 throw new MethodArgumentsException(message);
//             }
// 
//             if (lifecycleType != ActivityLifecycleType.CREATE && lifecycleType != ActivityLifecycleType.SAVE_INSTANCE_STATE) {
//                 String message = String.format(
//                         "`bundle` arg can only be added for `onCreate` or `onSaveInstanceState` in `%s`",
//                         methodName);
// 
//                 throw new MethodArgumentsException(message);
//             }
// 
//             args.add(ListenerArgType.BUNDLE);
// 
//             return this;
//         }
// 
//         public Builder addActivityArg() throws MethodArgumentsException {
//             if (args.contains(ListenerArgType.ACTIVITY)) {
//                 String message = String.format("`activity` arg already present in `%s`", methodName);
//                 throw new MethodArgumentsException(message);
//             }
// 
//             args.add(ListenerArgType.ACTIVITY);
// 
//             return this;
//         }
// 
//         public ListenerMethod build() {
//             return new ListenerMethod(methodName, args);
//         }
//     }
// }
// 
// Path: aircycle-compiler/src/main/java/com/github/simonpercic/aircycle/model/type/ActivityLifecycleType.java
// public enum ActivityLifecycleType {
//     CREATE,
//     START,
//     RESUME,
//     PAUSE,
//     STOP,
//     SAVE_INSTANCE_STATE,
//     DESTROY
// }
// 
// Path: aircycle-compiler/src/main/java/com/github/simonpercic/aircycle/utils/ElementValidator.java
// public final class ElementValidator {
// 
//     private ElementValidator() {
//         // no instance
//     }
// 
//     public static boolean isPublic(Element element) {
//         return hasModifier(element, Modifier.PUBLIC);
//     }
// 
//     public static boolean isPrivate(Element element) {
//         return hasModifier(element, Modifier.PRIVATE);
//     }
// 
//     private static boolean hasModifier(Element element, Modifier modifier) {
//         return element.getModifiers().contains(modifier);
//     }
// }


import android.app.Activity;
import android.os.Bundle;
import com.github.simonpercic.aircycle.exception.MethodArgumentsException;
import com.github.simonpercic.aircycle.model.ListenerMethod;
import com.github.simonpercic.aircycle.model.type.ActivityLifecycleType;
import com.github.simonpercic.aircycle.utils.ElementValidator;
import com.github.simonpercic.collectionhelper.CollectionHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
                    enclosingElement.getQualifiedName());

            logger.e(message, enclosingElement);
            return null;
        }

        ListenerMethod.Builder builder = ListenerMethod.builder(activityLifecycle, methodName);

        List<? extends VariableElement> parameters = method.getParameters();

        if (!CollectionHelper.isEmpty(parameters)) {
            TypeMirror bundleType = elementUtils.getTypeElement(Bundle.class.getCanonicalName()).asType();
            TypeMirror activityType = elementUtils.getTypeElement(Activity.class.getCanonicalName()).asType();

            for (int i = 0; i < parameters.size(); i++) {
                VariableElement parameter = parameters.get(i);
                TypeMirror paramType = parameter.asType();

                try {
                    if (typeUtils.isSubtype(paramType, activityType)) {
                        builder.addActivityArg();
                    } else if (typeUtils.isSameType(paramType, bundleType)) {
                        builder.addBundleArg();
                    } else {
                        String message = String.format(
                                "Invalid method argument of type `%s` at index `%s` in `%s",
                                paramType.toString(), i, methodName);

                        logger.e(message, method);
                    }
// Path: aircycle-compiler/src/main/java/com/github/simonpercic/aircycle/exception/MethodArgumentsException.java
// public class MethodArgumentsException extends Exception {
// 
//     public MethodArgumentsException(String message) {
//         super(message);
//     }
// }
// 
// Path: aircycle-compiler/src/main/java/com/github/simonpercic/aircycle/model/ListenerMethod.java
// public class ListenerMethod {
// 
//     private final String methodName;
//     private final List<ListenerArgType> args;
// 
//     public ListenerMethod(String methodName, List<ListenerArgType> args) {
//         this.methodName = methodName;
//         this.args = ImmutableList.copyOf(args);
//     }
// 
//     public String getMethodName() {
//         return methodName;
//     }
// 
//     public List<ListenerArgType> getArgs() {
//         return args;
//     }
// 
//     public static Builder builder(ActivityLifecycleType activityLifecycle, String methodName) {
//         if (activityLifecycle == null) {
//             throw new IllegalArgumentException("activityLifecycle is null");
//         }
// 
//         if (StringUtils.isEmpty(methodName)) {
//             throw new IllegalArgumentException("methodName is empty");
//         }
// 
//         return new Builder(activityLifecycle, methodName);
//     }
// 
//     public static class Builder {
// 
//         private final ActivityLifecycleType lifecycleType;
//         private final String methodName;
//         private final List<ListenerArgType> args;
// 
//         private Builder(ActivityLifecycleType lifecycleType, String methodName) {
//             this.lifecycleType = lifecycleType;
//             this.methodName = methodName;
//             this.args = new ArrayList<>(2);
//         }
// 
//         public Builder addBundleArg() throws MethodArgumentsException {
//             if (args.contains(ListenerArgType.BUNDLE)) {
//                 String message = String.format("`bundle` arg already present in `%s`", methodName);
//                 throw new MethodArgumentsException(message);
//             }
// 
//             if (lifecycleType != ActivityLifecycleType.CREATE && lifecycleType != ActivityLifecycleType.SAVE_INSTANCE_STATE) {
//                 String message = String.format(
//                         "`bundle` arg can only be added for `onCreate` or `onSaveInstanceState` in `%s`",
//                         methodName);
// 
//                 throw new MethodArgumentsException(message);
//             }
// 
//             args.add(ListenerArgType.BUNDLE);
// 
//             return this;
//         }
// 
//         public Builder addActivityArg() throws MethodArgumentsException {
//             if (args.contains(ListenerArgType.ACTIVITY)) {
//                 String message = String.format("`activity` arg already present in `%s`", methodName);
//                 throw new MethodArgumentsException(message);
//             }
// 
//             args.add(ListenerArgType.ACTIVITY);
// 
//             return this;
//         }
// 
//         public ListenerMethod build() {
//             return new ListenerMethod(methodName, args);
//         }
//     }
// }
// 
// Path: aircycle-compiler/src/main/java/com/github/simonpercic/aircycle/model/type/ActivityLifecycleType.java
// public enum ActivityLifecycleType {
//     CREATE,
//     START,
//     RESUME,
//     PAUSE,
//     STOP,
//     SAVE_INSTANCE_STATE,
//     DESTROY
// }
// 
// Path: aircycle-compiler/src/main/java/com/github/simonpercic/aircycle/utils/ElementValidator.java
// public final class ElementValidator {
// 
//     private ElementValidator() {
//         // no instance
//     }
// 
//     public static boolean isPublic(Element element) {
//         return hasModifier(element, Modifier.PUBLIC);
//     }
// 
//     public static boolean isPrivate(Element element) {
//         return hasModifier(element, Modifier.PRIVATE);
//     }
// 
//     private static boolean hasModifier(Element element, Modifier modifier) {
//         return element.getModifiers().contains(modifier);
//     }
// }


// Path: aircycle-compiler/src/main/java/com/github/simonpercic/aircycle/manager/MethodParser.java
import android.app.Activity;
import android.os.Bundle;
import com.github.simonpercic.aircycle.exception.MethodArgumentsException;
import com.github.simonpercic.aircycle.model.ListenerMethod;
import com.github.simonpercic.aircycle.model.type.ActivityLifecycleType;
import com.github.simonpercic.aircycle.utils.ElementValidator;
import com.github.simonpercic.collectionhelper.CollectionHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

                    enclosingElement.getQualifiedName());

            logger.e(message, enclosingElement);
            return null;
        }

        ListenerMethod.Builder builder = ListenerMethod.builder(activityLifecycle, methodName);

        List<? extends VariableElement> parameters = method.getParameters();

        if (!CollectionHelper.isEmpty(parameters)) {
            TypeMirror bundleType = elementUtils.getTypeElement(Bundle.class.getCanonicalName()).asType();
            TypeMirror activityType = elementUtils.getTypeElement(Activity.class.getCanonicalName()).asType();

            for (int i = 0; i < parameters.size(); i++) {
                VariableElement parameter = parameters.get(i);
                TypeMirror paramType = parameter.asType();

                try {
                    if (typeUtils.isSubtype(paramType, activityType)) {
                        builder.addActivityArg();
                    } else if (typeUtils.isSameType(paramType, bundleType)) {
                        builder.addBundleArg();
                    } else {
                        String message = String.format(
                                "Invalid method argument of type `%s` at index `%s` in `%s",
                                paramType.toString(), i, methodName);

                        logger.e(message, method);
                    }
                } catch (MethodArgumentsException e) {