// Path: ghostwriter-jdk-v7/src/main/java/io/ghostwriter/openjdk/v7/common/Instrumenter.java
// public interface Instrumenter {
// 
//     abstract class Option {
//         public static final String GHOSTWRITER_EXCLUDE = "GHOSTWRITER_EXCLUDE";
//         public static final String GHOSTWRITER_TRACE_VALUE_CHANGE = "GHOSTWRITER_TRACE_VALUE_CHANGE";
//         public static final String GHOSTWRITER_TRACE_ON_ERROR = "GHOSTWRITER_TRACE_ON_ERROR";
//         public static final String GHOSTWRITER_TRACE_RETURNING = "GHOSTWRITER_TRACE_RETURNING";
//         public static final String GHOSTWRITER_ANNOTATED_ONLY = "GHOSTWRITER_ANNOTATED_ONLY";
//         public static final String GHOSTWRITER_EXCLUDE_METHODS = "GHOSTWRITER_EXCLUDE_METHODS";
//         public static final String GHOSTWRITER_INSTRUMENT = "GHOSTWRITER_INSTRUMENT";
//         public static final String GHOSTWRITER_VERBOSE = "GHOSTWRITER_VERBOSE";
//         public static final String GHOSTWRITER_SHORT_METHOD_LIMIT = "GHOSTWRITER_SHORT_METHOD_LIMIT";
//     }
// 
//     void initialize(ProcessingEnvironment processingEnv);
// 
//     void process(Element element);
// 
//     boolean doInstrument();
// }
// 
// Path: ghostwriter-jdk-v7/src/main/java/io/ghostwriter/openjdk/v7/common/Logger.java
// public enum Logger {
//     ;
// 
//     private static Messager messager;
// 
//     private static boolean doVerboseLogging = false;
// 
//     private static String format(Class<?> klass, String method, String message) {
//         final int INITIAL_CAPACITY = 32;
//         StringBuilder sb = new StringBuilder(INITIAL_CAPACITY);
//         if (klass != null) {
//             sb.append(klass.getName());
//             sb.append(".");
//         }
//         sb.append(method);
//         sb.append(": ");
//         sb.append(message);
// 
//         return sb.toString();
//     }
// 
//     public static void note(Class<?> type, String method, String message) {
//         if (!doVerboseLogging) {
//             return;
//         }
// 
//         validateState();
//         String output = format(type, method, message);
//         messager.printMessage(Diagnostic.Kind.NOTE, output);
//     }
// 
//     public static void warning(Class<?> type, String method, String message) {
//         validateState();
//         String output = format(type, method, message);
//         messager.printMessage(Diagnostic.Kind.MANDATORY_WARNING, output);
//     }
// 
//     /**
//      * Display an error message.
//      *
//      * @param type    - class that produced the error
//      * @param method  - method that produced the error
//      * @param message - error description
//      */
//     public static void error(Class<?> type, String method, String message) {
//         validateState();
//         String output = format(type, method, message);
//         messager.printMessage(Diagnostic.Kind.ERROR, output);
//     }
// 
//     public static void initialize(Messager msg, boolean verbose) {
//         if (msg == null) {
//             throw new IllegalArgumentException("Cannot initialize with null!");
//         }
//         messager = msg;
//         doVerboseLogging = verbose;
//     }
// 
//     private static void validateState() {
//         if (messager == null) {
//             throw new IllegalStateException("Logger has not been initialized!");
//         }
//     }
// 
// }


import io.ghostwriter.openjdk.v7.common.Instrumenter;
import io.ghostwriter.openjdk.v7.common.Logger;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import java.util.Set;
public class GhostWriterAnnotationProcessor extends AbstractProcessor {

    // part of the Annotation processor API. Since GhostWriter just hijacks the processor pipeline
    // we take care not to claim any annotations and thus always return false.
    protected static boolean NO_ANNOTATIONS_CLAIMED = false;

    private Instrumenter instrumenter;

    public GhostWriterAnnotationProcessor(Instrumenter instrumenter) {
        this.instrumenter = instrumenter;
    }

    public GhostWriterAnnotationProcessor() {
        this(new Javac7Instrumenter());
    }

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);

        instrumenter.initialize(processingEnv);
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        if (roundEnv.processingOver()) {
            return NO_ANNOTATIONS_CLAIMED;
        }

        if (!instrumenter.doInstrument()) {
// Path: ghostwriter-jdk-v7/src/main/java/io/ghostwriter/openjdk/v7/common/Instrumenter.java
// public interface Instrumenter {
// 
//     abstract class Option {
//         public static final String GHOSTWRITER_EXCLUDE = "GHOSTWRITER_EXCLUDE";
//         public static final String GHOSTWRITER_TRACE_VALUE_CHANGE = "GHOSTWRITER_TRACE_VALUE_CHANGE";
//         public static final String GHOSTWRITER_TRACE_ON_ERROR = "GHOSTWRITER_TRACE_ON_ERROR";
//         public static final String GHOSTWRITER_TRACE_RETURNING = "GHOSTWRITER_TRACE_RETURNING";
//         public static final String GHOSTWRITER_ANNOTATED_ONLY = "GHOSTWRITER_ANNOTATED_ONLY";
//         public static final String GHOSTWRITER_EXCLUDE_METHODS = "GHOSTWRITER_EXCLUDE_METHODS";
//         public static final String GHOSTWRITER_INSTRUMENT = "GHOSTWRITER_INSTRUMENT";
//         public static final String GHOSTWRITER_VERBOSE = "GHOSTWRITER_VERBOSE";
//         public static final String GHOSTWRITER_SHORT_METHOD_LIMIT = "GHOSTWRITER_SHORT_METHOD_LIMIT";
//     }
// 
//     void initialize(ProcessingEnvironment processingEnv);
// 
//     void process(Element element);
// 
//     boolean doInstrument();
// }
// 
// Path: ghostwriter-jdk-v7/src/main/java/io/ghostwriter/openjdk/v7/common/Logger.java
// public enum Logger {
//     ;
// 
//     private static Messager messager;
// 
//     private static boolean doVerboseLogging = false;
// 
//     private static String format(Class<?> klass, String method, String message) {
//         final int INITIAL_CAPACITY = 32;
//         StringBuilder sb = new StringBuilder(INITIAL_CAPACITY);
//         if (klass != null) {
//             sb.append(klass.getName());
//             sb.append(".");
//         }
//         sb.append(method);
//         sb.append(": ");
//         sb.append(message);
// 
//         return sb.toString();
//     }
// 
//     public static void note(Class<?> type, String method, String message) {
//         if (!doVerboseLogging) {
//             return;
//         }
// 
//         validateState();
//         String output = format(type, method, message);
//         messager.printMessage(Diagnostic.Kind.NOTE, output);
//     }
// 
//     public static void warning(Class<?> type, String method, String message) {
//         validateState();
//         String output = format(type, method, message);
//         messager.printMessage(Diagnostic.Kind.MANDATORY_WARNING, output);
//     }
// 
//     /**
//      * Display an error message.
//      *
//      * @param type    - class that produced the error
//      * @param method  - method that produced the error
//      * @param message - error description
//      */
//     public static void error(Class<?> type, String method, String message) {
//         validateState();
//         String output = format(type, method, message);
//         messager.printMessage(Diagnostic.Kind.ERROR, output);
//     }
// 
//     public static void initialize(Messager msg, boolean verbose) {
//         if (msg == null) {
//             throw new IllegalArgumentException("Cannot initialize with null!");
//         }
//         messager = msg;
//         doVerboseLogging = verbose;
//     }
// 
//     private static void validateState() {
//         if (messager == null) {
//             throw new IllegalStateException("Logger has not been initialized!");
//         }
//     }
// 
// }


// Path: ghostwriter-jdk-v7/src/main/java/io/ghostwriter/openjdk/v7/GhostWriterAnnotationProcessor.java
import io.ghostwriter.openjdk.v7.common.Instrumenter;
import io.ghostwriter.openjdk.v7.common.Logger;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import java.util.Set;

public class GhostWriterAnnotationProcessor extends AbstractProcessor {

    // part of the Annotation processor API. Since GhostWriter just hijacks the processor pipeline
    // we take care not to claim any annotations and thus always return false.
    protected static boolean NO_ANNOTATIONS_CLAIMED = false;

    private Instrumenter instrumenter;

    public GhostWriterAnnotationProcessor(Instrumenter instrumenter) {
        this.instrumenter = instrumenter;
    }

    public GhostWriterAnnotationProcessor() {
        this(new Javac7Instrumenter());
    }

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);

        instrumenter.initialize(processingEnv);
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        if (roundEnv.processingOver()) {
            return NO_ANNOTATIONS_CLAIMED;
        }

        if (!instrumenter.doInstrument()) {
            Logger.note(getClass(), "process", "skipping processing...");