// 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;
package com.github.simonpercic.aircycle.manager;





/**
 * Listener method parser.
 *
 * @author Simon Percic <a href="https://github.com/simonpercic">https://github.com/simonpercic</a>
 */
@Singleton
public class MethodParser {

    private final ProcessorLogger logger;
    private final Elements elementUtils;
    private final Types typeUtils;

    @Inject
    public MethodParser(ProcessorLogger logger, Elements elementUtils, Types typeUtils) {
        this.logger = logger;
        this.elementUtils = elementUtils;
        this.typeUtils = typeUtils;
    }

// 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;

package com.github.simonpercic.aircycle.manager;





/**
 * Listener method parser.
 *
 * @author Simon Percic <a href="https://github.com/simonpercic">https://github.com/simonpercic</a>
 */
@Singleton
public class MethodParser {

    private final ProcessorLogger logger;
    private final Elements elementUtils;
    private final Types typeUtils;

    @Inject
    public MethodParser(ProcessorLogger logger, Elements elementUtils, Types typeUtils) {
        this.logger = logger;
        this.elementUtils = elementUtils;
        this.typeUtils = typeUtils;
    }

    public Map<ActivityLifecycleType, List<ListenerMethod>> parseLifecycleMethods(TypeElement element,