// Path: lib_processor/src/main/java/com/razerdp/lib/processor/BaseProcessor.java
// public abstract class BaseProcessor extends AbstractProcessor {
//     protected Filer mFiler;
//     protected Logger mLogger;
//     protected Types mTypesUtil;
//     protected Elements mElementUtil;
// 
//     @Override
//     public synchronized void init(ProcessingEnvironment processingEnvironment) {
//         super.init(processingEnvironment);
// 
//         mFiler = processingEnvironment.getFiler();
//         mTypesUtil = processingEnvironment.getTypeUtils();
//         mElementUtil = processingEnvironment.getElementUtils();
// 
//         mLogger = new Logger(processingEnvironment.getMessager());
//     }
// 
//     @Override
//     public SourceVersion getSupportedSourceVersion() {
//         return SourceVersion.latestSupported();
//     }
// 
//     @Override
//     public Set<String> getSupportedAnnotationTypes() {
//         Set<String> supportedAnnotationsSet = new LinkedHashSet<>();
//         Set<Class<? extends Annotation>> result = new LinkedHashSet<>();
//         onSetSupportedAnnotation(result);
//         for (Class<? extends Annotation> aClass : result) {
//             supportedAnnotationsSet.add(aClass.getCanonicalName());
//         }
//         return supportedAnnotationsSet;
//     }
// 
//     protected abstract void onSetSupportedAnnotation(Set<Class<? extends Annotation>> result);
// 
// 
//     public void logi(CharSequence which) {
//         mLogger.i(which);
//     }
// 
//     public void loge(CharSequence which) {
//         mLogger.e(which);
//     }
// 
//     public void logw(CharSequence which) {
//         mLogger.w(which);
//     }
// 
//     public void loge(Throwable which) {
//         mLogger.e(which);
//     }
// }
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String PACKAGE_SPARSEARRAY = "android.util";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_FIELD_NAME="SERVICE_IMPL_MAP";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_FILE_NAME = "ServiceImplGen";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_INTERFACE = "com.razerdp.github.common.modules.base.IModuleServiceProvider";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_INTERFACE_METHOD="getServiceImplMap";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_PACKAGE_NAME = PACKAGE_NAME + ".apt.gen";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String PACKAGE_NAME = "com.razerdp.github";


import com.razerdp.lib.annotations.ServiceImpl;
import com.razerdp.lib.processor.BaseProcessor;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import static com.razerdp.lib.config.AnnotationConfig.AndroidConfig.PACKAGE_SPARSEARRAY;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_FIELD_NAME;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_FILE_NAME;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_INTERFACE;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_INTERFACE_METHOD;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_PACKAGE_NAME;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.PACKAGE_NAME;
    private void scanClass(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        //scan for service impl
        Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(ServiceImpl.class);

        for (Element element : elements) {
            //only get annotation for class type
            if (!(element instanceof TypeElement)) continue;

            if (element.getKind() != ElementKind.CLASS) {
                loge(TAG + " @ServiceImpl is only for class");
                continue;
            }

            if (!element.getModifiers().contains(Modifier.PUBLIC)) {
                loge(TAG + " @ServiceImpl is only for public class");
                continue;
            }

            TypeElement typeElement = (TypeElement) element;
            TypeMirror mirror = typeElement.asType();
            if (!(mirror.getKind() == TypeKind.DECLARED)) {
                continue;
            }

            // check interface
            List<? extends TypeMirror> superClassElement = mTypesUtil.directSupertypes(mirror);
            if (superClassElement == null || superClassElement.size() <= 0) continue;

            TypeMirror serviceInterfaceElement = null;
            for (TypeMirror typeMirror : superClassElement) {
// Path: lib_processor/src/main/java/com/razerdp/lib/processor/BaseProcessor.java
// public abstract class BaseProcessor extends AbstractProcessor {
//     protected Filer mFiler;
//     protected Logger mLogger;
//     protected Types mTypesUtil;
//     protected Elements mElementUtil;
// 
//     @Override
//     public synchronized void init(ProcessingEnvironment processingEnvironment) {
//         super.init(processingEnvironment);
// 
//         mFiler = processingEnvironment.getFiler();
//         mTypesUtil = processingEnvironment.getTypeUtils();
//         mElementUtil = processingEnvironment.getElementUtils();
// 
//         mLogger = new Logger(processingEnvironment.getMessager());
//     }
// 
//     @Override
//     public SourceVersion getSupportedSourceVersion() {
//         return SourceVersion.latestSupported();
//     }
// 
//     @Override
//     public Set<String> getSupportedAnnotationTypes() {
//         Set<String> supportedAnnotationsSet = new LinkedHashSet<>();
//         Set<Class<? extends Annotation>> result = new LinkedHashSet<>();
//         onSetSupportedAnnotation(result);
//         for (Class<? extends Annotation> aClass : result) {
//             supportedAnnotationsSet.add(aClass.getCanonicalName());
//         }
//         return supportedAnnotationsSet;
//     }
// 
//     protected abstract void onSetSupportedAnnotation(Set<Class<? extends Annotation>> result);
// 
// 
//     public void logi(CharSequence which) {
//         mLogger.i(which);
//     }
// 
//     public void loge(CharSequence which) {
//         mLogger.e(which);
//     }
// 
//     public void logw(CharSequence which) {
//         mLogger.w(which);
//     }
// 
//     public void loge(Throwable which) {
//         mLogger.e(which);
//     }
// }
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String PACKAGE_SPARSEARRAY = "android.util";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_FIELD_NAME="SERVICE_IMPL_MAP";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_FILE_NAME = "ServiceImplGen";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_INTERFACE = "com.razerdp.github.common.modules.base.IModuleServiceProvider";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_INTERFACE_METHOD="getServiceImplMap";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String APT_PACKAGE_NAME = PACKAGE_NAME + ".apt.gen";
// 
// Path: lib_annotations/src/main/java/com/razerdp/lib/config/AnnotationConfig.java
// public static final String PACKAGE_NAME = "com.razerdp.github";


// Path: lib_processor/src/main/java/com/razerdp/lib/processor/service/ModuleServiceProcessor.java
import com.razerdp.lib.annotations.ServiceImpl;
import com.razerdp.lib.processor.BaseProcessor;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import static com.razerdp.lib.config.AnnotationConfig.AndroidConfig.PACKAGE_SPARSEARRAY;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_FIELD_NAME;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_FILE_NAME;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_INTERFACE;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_INTERFACE_METHOD;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.APT_PACKAGE_NAME;
import static com.razerdp.lib.config.AnnotationConfig.ServiceConfig.PACKAGE_NAME;

    private void scanClass(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        //scan for service impl
        Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(ServiceImpl.class);

        for (Element element : elements) {
            //only get annotation for class type
            if (!(element instanceof TypeElement)) continue;

            if (element.getKind() != ElementKind.CLASS) {
                loge(TAG + " @ServiceImpl is only for class");
                continue;
            }

            if (!element.getModifiers().contains(Modifier.PUBLIC)) {
                loge(TAG + " @ServiceImpl is only for public class");
                continue;
            }

            TypeElement typeElement = (TypeElement) element;
            TypeMirror mirror = typeElement.asType();
            if (!(mirror.getKind() == TypeKind.DECLARED)) {
                continue;
            }

            // check interface
            List<? extends TypeMirror> superClassElement = mTypesUtil.directSupertypes(mirror);
            if (superClassElement == null || superClassElement.size() <= 0) continue;

            TypeMirror serviceInterfaceElement = null;
            for (TypeMirror typeMirror : superClassElement) {
                if (typeMirror.toString().startsWith(PACKAGE_NAME)) {