changeset 427:a633786bb7b9

Move generators around to proper packages.
author shade
date Wed, 26 Feb 2014 17:18:42 +0400
parents 7088ef5476cd
children 82c32cef2e5d
files jmh-core/src/main/java/org/openjdk/jmh/generators/GenerateMicroBenchmarkProcessor.java jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APClassInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APFieldInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APMetadataInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APMethodInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APParameterInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/AnnProcessGeneratorSource.java jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/AnnUtils.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGenerator.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGeneratorUtils.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/CompilerControlPlugin.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/GroupValidationPlugin.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/HelperMethodValidationPlugin.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/ParamValidationPlugin.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/Plugin.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObjectHandler.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/BenchmarkInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/ClassInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/FieldInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/GenerationException.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/GeneratorSource.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/HelperMethodInvocation.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/HelperType.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/MetadataInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodGroup.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodInvocation.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/ParameterInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/StateObject.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/BenchmarkGenerator.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/BenchmarkGeneratorUtils.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/BenchmarkInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/ClassInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/CompilerControlPlugin.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/FieldInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GenerateMicroBenchmarkProcessor.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GenerationException.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GeneratorSource.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GroupValidationPlugin.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/HelperMethodInvocation.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/HelperMethodValidationPlugin.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/HelperType.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MetadataInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MethodGroup.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MethodInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MethodInvocation.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/ParamValidationPlugin.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/ParameterInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/Plugin.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/StateObject.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/StateObjectHandler.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APClassInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APFieldInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APMetadataInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APMethodInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APParameterInfo.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/AnnProcessGeneratorSource.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/AnnUtils.java jmh-core/src/main/resources/META-INF/services/javax.annotation.processing.Processor
diffstat 59 files changed, 3750 insertions(+), 3726 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/GenerateMicroBenchmarkProcessor.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators;
+
+import org.openjdk.jmh.generators.annotations.AnnProcessGeneratorSource;
+import org.openjdk.jmh.generators.core.BenchmarkGenerator;
+import org.openjdk.jmh.generators.source.GeneratorSource;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import java.util.Set;
+
+/**
+ * @author staffan.friberg@oracle.com
+ * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+@SupportedAnnotationTypes("*")
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class GenerateMicroBenchmarkProcessor extends AbstractProcessor {
+
+    private final BenchmarkGenerator generator = new BenchmarkGenerator();
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        GeneratorSource source = new AnnProcessGeneratorSource(roundEnv, processingEnv);
+        if (!roundEnv.processingOver()) {
+            generator.generate(source);
+        } else {
+            generator.complete(source);
+        }
+        return true;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APClassInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.annotations;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.FieldInfo;
+import org.openjdk.jmh.generators.source.MethodInfo;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.ElementFilter;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class APClassInfo extends APMetadataInfo implements ClassInfo {
+
+    private final TypeElement el;
+
+    public APClassInfo(ProcessingEnvironment processEnv, TypeElement element) {
+        super(processEnv, element);
+        this.el = element;
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annClass) {
+        return el.getAnnotation(annClass);
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotationRecursive(Class<T> annClass) {
+        return AnnUtils.getAnnotationRecursive(el, annClass);
+    }
+
+    @Override
+    public Collection<MethodInfo> getConstructors() {
+        Collection<MethodInfo> mis = new ArrayList<MethodInfo>();
+        for (ExecutableElement e : ElementFilter.constructorsIn(el.getEnclosedElements())) {
+            mis.add(new APMethodInfo(processEnv, this, e));
+        }
+        return mis;
+    }
+
+    @Override
+    public boolean isNested() {
+        return el.getNestingKind().isNested();
+    }
+
+    @Override
+    public String getNestedName() {
+        return AnnUtils.getNestedName(el);
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return el.getQualifiedName().toString();
+    }
+
+    @Override
+    public Collection<FieldInfo> getDeclaredFields() {
+        List<FieldInfo> ls = new ArrayList<FieldInfo>();
+        for (VariableElement e : ElementFilter.fieldsIn(el.getEnclosedElements())) {
+            ls.add(new APFieldInfo(processEnv, e));
+        }
+        return ls;
+    }
+
+    @Override
+    public Collection<FieldInfo> getFields() {
+        List<FieldInfo> ls = new ArrayList<FieldInfo>();
+        ls.addAll(getDeclaredFields());
+        for (ClassInfo cl : getSuperclasses()) {
+            ls.addAll(cl.getDeclaredFields());
+        }
+        return ls;
+    }
+
+    @Override
+    public Collection<MethodInfo> getDeclaredMethods() {
+        Collection<MethodInfo> mis = new ArrayList<MethodInfo>();
+        for (ExecutableElement e : ElementFilter.methodsIn(el.getEnclosedElements())) {
+            mis.add(new APMethodInfo(processEnv, this, e));
+        }
+        return mis;
+    }
+
+    @Override
+    public Collection<MethodInfo> getMethods() {
+        List<MethodInfo> ls = new ArrayList<MethodInfo>();
+        ls.addAll(getDeclaredMethods());
+        for (ClassInfo cl : getSuperclasses()) {
+            ls.addAll(cl.getDeclaredMethods());
+        }
+        return ls;
+    }
+
+    @Override
+    public String getPackageName() {
+        return AnnUtils.getPackageName(el);
+    }
+
+    @Override
+    public Collection<ClassInfo> getSuperclasses() {
+        List<ClassInfo> list = new ArrayList<ClassInfo>();
+        TypeElement walk = el;
+        while ((walk = (TypeElement) processEnv.getTypeUtils().asElement(walk.getSuperclass())) != null) {
+            list.add(new APClassInfo(processEnv, walk));
+        }
+        return list;
+    }
+
+    @Override
+    public boolean isAbstract() {
+        return el.getModifiers().contains(Modifier.ABSTRACT);
+    }
+
+    @Override
+    public boolean isPublic() {
+        return el.getModifiers().contains(Modifier.PUBLIC);
+    }
+
+    @Override
+    public boolean isStatic() {
+        return el.getModifiers().contains(Modifier.STATIC);
+    }
+
+    @Override
+    public boolean isStrictFP() {
+        return el.getModifiers().contains(Modifier.STRICTFP);
+    }
+
+    public String toString() {
+        return getQualifiedName();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APFieldInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.annotations;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.FieldInfo;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import java.lang.annotation.Annotation;
+
+public class APFieldInfo extends APMetadataInfo implements FieldInfo {
+
+    private final VariableElement ve;
+
+    public APFieldInfo(ProcessingEnvironment processEnv, VariableElement ve) {
+        super(processEnv, ve);
+        this.ve = ve;
+    }
+
+    @Override
+    public String getName() {
+        return ve.getSimpleName().toString();
+    }
+
+    @Override
+    public String getType() {
+        return ve.asType().toString();
+    }
+
+    @Override
+    public boolean isPublic() {
+        return ve.getModifiers().contains(Modifier.PUBLIC);
+    }
+
+    @Override
+    public boolean isStatic() {
+        return ve.getModifiers().contains(Modifier.STATIC);
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annClass) {
+        return ve.getAnnotation(annClass);
+    }
+
+    @Override
+    public ClassInfo getOwner() {
+        return new APClassInfo(processEnv, (TypeElement)ve.getEnclosingElement());
+    }
+
+    public String toString() {
+        return getType() + " " + getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APMetadataInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.annotations;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+
+public class APMetadataInfo {
+
+    protected final ProcessingEnvironment processEnv;
+    private final Element element;
+
+    public APMetadataInfo(ProcessingEnvironment processEnv, Element element) {
+        this.processEnv = processEnv;
+        this.element = element;
+    }
+
+    public Element getElement() {
+        return element;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APMethodInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.annotations;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.MethodInfo;
+import org.openjdk.jmh.generators.source.ParameterInfo;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.VariableElement;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class APMethodInfo extends APMetadataInfo implements MethodInfo {
+
+    private final ClassInfo ci;
+    private final ExecutableElement el;
+
+    public APMethodInfo(ProcessingEnvironment processEnv, ClassInfo ci, ExecutableElement el) {
+        super(processEnv, el);
+        this.ci = ci;
+        this.el = el;
+    }
+
+    @Override
+    public ClassInfo getOwner() {
+        return ci;
+    }
+
+    @Override
+    public String getName() {
+        return el.getSimpleName().toString();
+    }
+
+    @Override
+    public String getReturnType() {
+        return el.getReturnType().toString();
+    }
+
+    @Override
+    public Collection<ParameterInfo> getParameters() {
+        Collection<ParameterInfo> pis = new ArrayList<ParameterInfo>();
+        for (VariableElement v : el.getParameters()) {
+            pis.add(new APParameterInfo(processEnv, v));
+        }
+        return pis;
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annClass) {
+        return el.getAnnotation(annClass);
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotationRecursive(Class<T> annClass) {
+        return AnnUtils.getAnnotationRecursive(el, annClass);
+    }
+
+    @Override
+    public boolean isPublic() {
+        return el.getModifiers().contains(Modifier.PUBLIC);
+    }
+
+    @Override
+    public boolean isAbstract() {
+        return el.getModifiers().contains(Modifier.ABSTRACT);
+    }
+
+    @Override
+    public boolean isSynchronized() {
+        return el.getModifiers().contains(Modifier.SYNCHRONIZED);
+    }
+
+    @Override
+    public boolean isStrictFP() {
+        return el.getModifiers().contains(Modifier.STRICTFP);
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return ci.getQualifiedName() + "." + el.toString();
+    }
+
+    @Override
+    public int compareTo(MethodInfo o) {
+        return getQualifiedName().compareTo(o.getQualifiedName());
+    }
+
+    public String toString() {
+        return getOwner() + " " + getName() ;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/APParameterInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.annotations;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.ParameterInfo;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+
+public class APParameterInfo extends APMetadataInfo implements ParameterInfo {
+    private final VariableElement ve;
+    private final TypeElement stateType;
+
+    public APParameterInfo(ProcessingEnvironment processEnv, VariableElement ve) {
+        super(processEnv, ve);
+        this.ve = ve;
+        this.stateType = (TypeElement) processEnv.getTypeUtils().asElement(ve.asType());
+    }
+
+    @Override
+    public ClassInfo getType() {
+        return new APClassInfo(processEnv, stateType);
+    }
+
+    public String toString() {
+        return getType() + " " + ve.getSimpleName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/AnnProcessGeneratorSource.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.annotations;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.GeneratorSource;
+import org.openjdk.jmh.generators.source.MetadataInfo;
+
+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.TypeElement;
+import javax.lang.model.util.ElementFilter;
+import javax.tools.Diagnostic;
+import javax.tools.StandardLocation;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.TreeSet;
+
+public class AnnProcessGeneratorSource implements GeneratorSource {
+
+    private final RoundEnvironment roundEnv;
+    private final ProcessingEnvironment processingEnv;
+
+    public AnnProcessGeneratorSource(RoundEnvironment roundEnv, ProcessingEnvironment processingEnv) {
+        this.roundEnv = roundEnv;
+        this.processingEnv = processingEnv;
+    }
+
+    @Override
+    public Collection<ClassInfo> getClasses() {
+        // Need to do a few rollovers to find all classes that have @GMB-annotated methods in their
+        // subclasses. This is mostly due to some of the nested classes not discoverable at once,
+        // when we need to discover the enclosing class first. With the potentially non-zero nesting
+        // depth, we need to do a few rounds. Hopefully we will just do a single stride in most
+        // cases.
+
+        Collection<TypeElement> discoveredClasses = new TreeSet<TypeElement>(new Comparator<TypeElement>() {
+            @Override
+            public int compare(TypeElement o1, TypeElement o2) {
+                return o1.getQualifiedName().toString().compareTo(o2.getQualifiedName().toString());
+            }
+        });
+
+        // Walk around until convergence...
+
+        int lastSize = -1;
+        while (discoveredClasses.size() > lastSize) {
+            lastSize = discoveredClasses.size();
+            for (Element e : roundEnv.getRootElements()) {
+                if (e.getKind() != ElementKind.CLASS) continue;
+                TypeElement walk = (TypeElement) e;
+                do {
+                    discoveredClasses.add(walk);
+                    for (TypeElement nested : ElementFilter.typesIn(walk.getEnclosedElements())) {
+                        discoveredClasses.add(nested);
+                    }
+                } while ((walk = (TypeElement) processingEnv.getTypeUtils().asElement(walk.getSuperclass())) != null);
+            }
+        }
+
+        return convert(discoveredClasses);
+    }
+
+    protected Collection<ClassInfo> convert(Collection<TypeElement> els) {
+        List<ClassInfo> list = new ArrayList<ClassInfo>();
+        for (TypeElement el : els) {
+            list.add(new APClassInfo(processingEnv, el));
+        }
+        return list;
+    }
+
+    @Override
+    public ClassInfo resolveClass(String className) {
+        return new APClassInfo(processingEnv, processingEnv.getElementUtils().getTypeElement(className));
+    }
+
+    @Override
+    public Writer newResource(String path) throws IOException {
+        return processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", path).openWriter();
+    }
+
+    @Override
+    public Writer newFile(String objectName) throws IOException {
+        return processingEnv.getFiler().createSourceFile(objectName).openWriter();
+    }
+
+    @Override
+    public void printError(String message) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message);
+    }
+
+    @Override
+    public void printError(String message, MetadataInfo element) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, ((APMetadataInfo)element).getElement());
+    }
+
+    @Override
+    public void printError(String message, Throwable throwable) {
+        printError(message + " " + throwable);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/annotations/AnnUtils.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.annotations;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import java.lang.annotation.Annotation;
+
+public class AnnUtils {
+
+    /**
+     * Recursively get the annotation, until found, or reached the top of hierarchy.
+     * @param root where to start
+     * @param annotation what to look for
+     * @param <A> type of what we look for
+     * @return annotation
+     */
+    public static <A extends Annotation> A getAnnotationRecursive(Element root, Class<A> annotation) {
+        Element walk = root;
+        A result = null;
+        while (walk != null && (result = walk.getAnnotation(annotation)) == null) {
+            walk = walk.getEnclosingElement();
+        }
+        return result;
+    }
+
+    /**
+     * Get the package name part of a class
+     *
+     * @param clazz the subject
+     * @return the package name or "" if no package
+     */
+    public static String getPackageName(TypeElement clazz) {
+        Element walk = clazz;
+        while (walk.getKind() != ElementKind.PACKAGE) {
+            walk = walk.getEnclosingElement();
+        }
+        return ((PackageElement)walk).getQualifiedName().toString();
+    }
+
+    /**
+     * Get the class name along with any nested class names
+     * @param clazz the subject
+     * @return the synthetic class name in form of "parent1_parent2_classname"
+     */
+    public static String getNestedName(TypeElement clazz) {
+        String name = "";
+        Element walk = clazz;
+        while (walk.getKind() != ElementKind.PACKAGE) {
+            name = walk.getSimpleName().toString() + (name.isEmpty() ? "" : "_" + name);
+            walk = walk.getEnclosingElement();
+        }
+        return name.substring(0, name.length());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGenerator.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,990 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.core;
+
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
+import org.openjdk.jmh.annotations.Group;
+import org.openjdk.jmh.annotations.GroupThreads;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.generators.source.BenchmarkInfo;
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.FieldInfo;
+import org.openjdk.jmh.generators.source.GenerationException;
+import org.openjdk.jmh.generators.source.GeneratorSource;
+import org.openjdk.jmh.generators.source.MethodGroup;
+import org.openjdk.jmh.generators.source.MethodInfo;
+import org.openjdk.jmh.generators.source.ParameterInfo;
+import org.openjdk.jmh.generators.source.StateObject;
+import org.openjdk.jmh.logic.BlackHole;
+import org.openjdk.jmh.logic.InfraControl;
+import org.openjdk.jmh.logic.ThreadControl;
+import org.openjdk.jmh.logic.results.AverageTimeResult;
+import org.openjdk.jmh.logic.results.RawResults;
+import org.openjdk.jmh.logic.results.Result;
+import org.openjdk.jmh.logic.results.ResultRole;
+import org.openjdk.jmh.logic.results.SampleTimeResult;
+import org.openjdk.jmh.logic.results.SingleShotResult;
+import org.openjdk.jmh.logic.results.ThroughputResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
+import org.openjdk.jmh.runner.MicroBenchmarkList;
+import org.openjdk.jmh.util.internal.HashMultimap;
+import org.openjdk.jmh.util.internal.Multimap;
+import org.openjdk.jmh.util.internal.SampleBuffer;
+
+import javax.annotation.Generated;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.annotation.IncompleteAnnotationException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
+/**
+ * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
+ */
+public class BenchmarkGenerator {
+
+    private final Set<BenchmarkInfo> benchmarkInfos;
+    private final Collection<Plugin> plugins;
+    private final CompilerControlPlugin compilerControl;
+    private final Set<String> processedBenchmarks;
+
+    public BenchmarkGenerator() {
+        benchmarkInfos = new HashSet<BenchmarkInfo>();
+        processedBenchmarks = new HashSet<String>();
+        compilerControl = new CompilerControlPlugin();
+
+        plugins = new ArrayList<Plugin>();
+        plugins.add(new HelperMethodValidationPlugin());
+        plugins.add(new GroupValidationPlugin());
+        plugins.add(new ParamValidationPlugin());
+        plugins.add(compilerControl);
+    }
+
+    public void generate(GeneratorSource source) {
+        try {
+            for (Plugin sub : plugins) {
+                sub.process(source);
+            }
+
+            // Build a Set of classes with a list of annotated methods
+            Multimap<ClassInfo, MethodInfo> clazzes = buildAnnotatedSet(source);
+
+            // Generate code for all found Classes and Methods
+            for (ClassInfo clazz : clazzes.keys()) {
+                if (!processedBenchmarks.add(clazz.getQualifiedName())) continue;
+                try {
+                    validateBenchmark(clazz, clazzes.get(clazz));
+                    BenchmarkInfo info = makeBenchmarkInfo(clazz, clazzes.get(clazz));
+                    generateClass(source, clazz, info);
+                    benchmarkInfos.add(info);
+                } catch (GenerationException ge) {
+                    source.printError(ge.getMessage(), ge.getElement());
+                }
+            }
+        } catch (Throwable t) {
+            source.printError("Annotation generators had thrown the exception: " + t);
+            t.printStackTrace(System.err);
+        }
+    }
+
+    public void complete(GeneratorSource source) {
+        for (Plugin sub : plugins) {
+            sub.finish(source);
+        }
+
+        // Processing completed, final round. Print all added methods to file
+        try {
+            PrintWriter writer = new PrintWriter(source.newResource(MicroBenchmarkList.MICROBENCHMARK_LIST.substring(1)));
+            for (BenchmarkInfo info : benchmarkInfos) {
+                for (String method : info.methodGroups.keySet()) {
+                    MethodGroup group = info.methodGroups.get(method);
+                    for (Mode m : group.getModes()) {
+                        BenchmarkRecord br = new BenchmarkRecord(
+                                info.userName + "." + method,
+                                info.generatedName + "." + method,
+                                m,
+                                group.getThreads(),
+                                group.getTotalThreadCount(),
+                                group.getWarmupIterations(),
+                                group.getWarmupTime(),
+                                group.getWarmupBatchSize(),
+                                group.getMeasurementIterations(),
+                                group.getMeasurementTime(),
+                                group.getMeasurementBatchSize(),
+                                group.getForks(),
+                                group.getWarmupForks(),
+                                group.getJVMArgs(),
+                                group.getJVMArgsPrepend(),
+                                group.getJVMArgsAppend(),
+                                group.getParams()
+                        );
+                        writer.println(br.toLine());
+                    }
+                }
+            }
+
+            writer.close();
+        } catch (IOException ex) {
+            source.printError("Error writing MicroBenchmark list " + ex);
+        }
+    }
+
+    /**
+     * Build a set of Classes which has annotated methods in them
+     *
+     * @return for all methods annotated with $annotation, returns Map<holder-class, Set<method>>
+     */
+    private Multimap<ClassInfo, MethodInfo> buildAnnotatedSet(GeneratorSource source) {
+        // Transitively close the hierarchy:
+        //   If superclass has a @GMB method, then all subclasses also have it.
+        //   We skip the generated classes, which we had probably generated during the previous rounds
+        //   of processing. Abstract classes are of no interest for us either.
+
+        Multimap<ClassInfo, MethodInfo> result = new HashMultimap<ClassInfo, MethodInfo>();
+        for (ClassInfo currentClass : source.getClasses()) {
+            if (currentClass.getQualifiedName().contains("generated")) continue;
+            if (currentClass.isAbstract()) continue;
+
+            for (MethodInfo mi : currentClass.getDeclaredMethods()) {
+                GenerateMicroBenchmark ann = mi.getAnnotation(GenerateMicroBenchmark.class);
+                if (ann != null) {
+                    result.put(currentClass, mi);
+                }
+            }
+
+            for (ClassInfo upperClass : currentClass.getSuperclasses()) {
+                if (upperClass.getQualifiedName().contains("generated")) continue;
+                for (MethodInfo mi : upperClass.getDeclaredMethods()) {
+                    GenerateMicroBenchmark ann = mi.getAnnotation(GenerateMicroBenchmark.class);
+                    if (ann != null) {
+                        result.put(currentClass, mi);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * Do basic benchmark validation.
+     */
+    private void validateBenchmark(ClassInfo clazz, Collection<MethodInfo> methods) {
+        if (clazz.getQualifiedName().isEmpty()) {
+            throw new GenerationException("Microbenchmark should have package other than default.", clazz);
+        }
+
+        Collection<ClassInfo> states = new ArrayList<ClassInfo>();
+
+        // validate all arguments are @State-s
+        for (MethodInfo e : methods) {
+            for (ParameterInfo var : e.getParameters()) {
+                states.add(var.getType());
+            }
+        }
+
+        // validate if enclosing class is implicit @State
+        if (clazz.getAnnotation(State.class) != null) {
+            states.add(clazz);
+        }
+
+        // validate @State classes
+        for (ClassInfo state : states) {
+            // Because of https://bugs.openjdk.java.net/browse/JDK-8031122,
+            // we need to preemptively check the annotation value, and
+            // the API can only allow that by catching the exception, argh.
+            try {
+                state.getAnnotation(State.class).value();
+            } catch (IncompleteAnnotationException iae) {
+                throw new GenerationException("The " + State.class.getSimpleName() +
+                        " annotation should have the explicit " + Scope.class.getSimpleName() + " argument",
+                        state);
+            }
+
+            if (!state.isPublic()) {
+                throw new GenerationException("The " + State.class.getSimpleName() +
+                        " annotation only supports public classes.", state);
+            }
+
+            if (state.isNested() && !state.isStatic()) {
+                throw new GenerationException("The " + State.class.getSimpleName() +
+                        " annotation does not support inner classes, make sure the class is nested (static).",
+                        state);
+            }
+
+            boolean hasDefaultConstructor = false;
+            for (MethodInfo constructor : state.getConstructors()) {
+                hasDefaultConstructor |= (constructor.getParameters().isEmpty() && constructor.isPublic());
+            }
+
+            if (!hasDefaultConstructor) {
+                throw new GenerationException("The " + State.class.getSimpleName() +
+                        " annotation can only be applied to the classes having the default public constructor.",
+                        state);
+            }
+        }
+
+        // validate against rogue fields
+        if (clazz.getAnnotation(State.class) == null || clazz.isAbstract()) {
+            for (FieldInfo fi : clazz.getFields()) {
+                // allow static fields
+                if (fi.isStatic()) continue;
+                throw new GenerationException(
+                        "Field \"" + fi.getName() + "\" is declared within " +
+                                "the class not having @" + State.class.getSimpleName() + " annotation. " +
+                                "This can result in unspecified behavior, and prohibited.", fi);
+            }
+        }
+
+        // check modifiers
+        for (MethodInfo m : methods) {
+            if (!m.isPublic()) {
+                throw new GenerationException("@" + GenerateMicroBenchmark.class.getSimpleName() +
+                        " method should be public.", m);
+            }
+
+            if (m.isAbstract()) {
+                throw new GenerationException("@" + GenerateMicroBenchmark.class.getSimpleName()
+                        + " method can not be abstract.", m);
+            }
+            if (m.isSynchronized()) {
+                if (clazz.getAnnotation(State.class) == null) {
+                    throw new GenerationException("@" + GenerateMicroBenchmark.class.getSimpleName()
+                            + " method can only be synchronized if the enclosing class is annotated with "
+                            + "@" + State.class.getSimpleName() + ".", m);
+                    }
+            }
+        }
+
+        // check annotations
+        for (MethodInfo m : methods) {
+            OperationsPerInvocation opi = m.getAnnotationRecursive(OperationsPerInvocation.class);
+            if (opi != null && opi.value() < 1) {
+                throw new GenerationException("The " + OperationsPerInvocation.class.getSimpleName() +
+                        " needs to be greater than 0.", m);
+            }
+        }
+    }
+
+    /**
+     * validate benchmark info
+     * @param info benchmark info to validate
+     */
+    private void validateBenchmarkInfo(BenchmarkInfo info) {
+        // check the @Group preconditions,
+        // ban some of the surprising configurations
+        //
+        for (MethodGroup group : info.methodGroups.values()) {
+            if (group.methods().size() == 1) {
+                MethodInfo meth = group.methods().iterator().next();
+                if (meth.getAnnotation(Group.class) == null) {
+                    for (ParameterInfo param : meth.getParameters()) {
+                        State stateAnn = param.getType().getAnnotation(State.class);
+                        if (stateAnn != null && stateAnn.value() == Scope.Group) {
+                            throw new GenerationException(
+                                    "Only @" + Group.class.getSimpleName() + " methods can reference @" + State.class.getSimpleName()
+                                            + "(" + Scope.class.getSimpleName() + "." + Scope.Group + ") states.",
+                                    meth);
+                        }
+                    }
+
+                    State stateAnn = meth.getOwner().getAnnotation(State.class);
+                    if (stateAnn != null && stateAnn.value() == Scope.Group) {
+                        throw new GenerationException(
+                                "Only @" + Group.class.getSimpleName() + " methods can implicitly reference @" + State.class.getSimpleName()
+                                        + "(" + Scope.class.getSimpleName() + "." + Scope.Group + ") states.",
+                                meth);
+                    }
+                }
+            } else {
+                for (MethodInfo m : group.methods()) {
+                    if (m.getAnnotation(Group.class) == null) {
+                        throw new GenerationException(
+                                "Internal error: multiple methods per @" + Group.class.getSimpleName()
+                                        + ", but not all methods have @" + Group.class.getSimpleName(),
+                                m);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Generate BenchmarkInfo for given class.
+     * We will figure out method groups at this point.
+     *
+     * @param clazz holder class
+     * @param methods annotated methods
+     * @return BenchmarkInfo
+     */
+    private BenchmarkInfo makeBenchmarkInfo(ClassInfo clazz, Collection<MethodInfo> methods) {
+        Map<String, MethodGroup> result = new TreeMap<String, MethodGroup>();
+
+        for (MethodInfo method : methods) {
+            Group groupAnn = method.getAnnotation(Group.class);
+            String groupName = (groupAnn != null) ? groupAnn.value() : method.getName();
+
+            if (!checkJavaIdentifier(groupName)) {
+                throw new GenerationException("Group name should be the legal Java identifier.", method);
+            }
+
+            MethodGroup group = result.get(groupName);
+            if (group == null) {
+                group = new MethodGroup(groupName);
+                result.put(groupName, group);
+            }
+
+            BenchmarkMode mbAn = method.getAnnotationRecursive(BenchmarkMode.class);
+            if (mbAn != null) {
+                group.addModes(mbAn.value());
+            }
+
+            group.addStrictFP(clazz.isStrictFP());
+            group.addStrictFP(method.isStrictFP());
+            group.addMethod(method, (method.getAnnotation(GroupThreads.class) != null) ? method.getAnnotation(GroupThreads.class).value() : 1);
+
+            // Discovering @Params, part 1:
+            //   For each parameter, walk the type hierarchy up to discover inherited @Param fields in @State objects.
+            for (ParameterInfo pi : method.getParameters()) {
+                for (FieldInfo fi : pi.getType().getFields()) {
+                    if (fi.getAnnotation(Param.class) != null) {
+                        group.addParam(fi.getName(), fi.getAnnotation(Param.class).value());
+                    }
+                }
+            }
+
+            // Discovering @Params, part 2:
+            //  Walk the type hierarchy up to discover inherited @Param fields for class.
+            for (FieldInfo fi : clazz.getFields()) {
+                if (fi.getAnnotation(Param.class) != null) {
+                    group.addParam(fi.getName(), fi.getAnnotation(Param.class).value());
+                }
+            }
+        }
+
+        // enforce the default value
+        for (MethodGroup group : result.values()) {
+            if (group.getModes().isEmpty()) {
+                group.addModes(Mode.Throughput);
+            }
+        }
+
+        String sourcePackage = clazz.getPackageName();
+        String generatedPackageName = sourcePackage + ".generated";
+        String generatedClassName = clazz.getNestedName();
+
+        BenchmarkInfo info = new BenchmarkInfo(clazz.getQualifiedName(), generatedPackageName, generatedClassName, result);
+        validateBenchmarkInfo(info);
+        return info;
+    }
+
+    public static boolean checkJavaIdentifier(String id) {
+        for (int i = 0; i < id.length(); i++) {
+            char c = id.charAt(i);
+            if (!Character.isJavaIdentifierPart(c)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Create and generate Java code for a class and it's methods
+     */
+    private void generateClass(GeneratorSource source, ClassInfo classInfo, BenchmarkInfo info) {
+        try {
+            // Create file and open an outputstream
+            PrintWriter writer = new PrintWriter(source.newFile(info.generatedName), false);
+
+            // Write package and imports
+            writer.println("package " + info.generatedPackageName + ';');
+            writer.println();
+
+            generateImport(writer);
+
+            // Write class header
+            writer.println("@" + CompilerControl.class.getSimpleName() +
+                    "(" + CompilerControl.class.getSimpleName() + "." + CompilerControl.Mode.class.getSimpleName() +
+                    "." + CompilerControl.Mode.DONT_INLINE + ")");
+            writer.println("@Generated(\"" + BenchmarkGenerator.class.getCanonicalName() + "\")");
+            writer.println("public final class " + info.generatedClassName + " {");
+            writer.println();
+            generatePadding(writer);
+
+            StateObjectHandler states = new StateObjectHandler();
+
+            // benchmark instance is implicit
+            states.bindImplicit(classInfo, "bench", Scope.Thread);
+
+            // default blackhole is implicit
+            states.bindImplicit(source.resolveClass(BlackHole.class.getCanonicalName()), "blackhole", Scope.Thread);
+
+            // Write all methods
+            for (String groupName : info.methodGroups.keySet()) {
+                for (MethodInfo method : info.methodGroups.get(groupName).methods()) {
+                    for (ParameterInfo p : method.getParameters()) {
+                        states.bindArg(method, p);
+                    }
+                }
+
+                for (Mode benchmarkKind : Mode.values()) {
+                    if (benchmarkKind == Mode.All) continue;
+                    generateMethod(benchmarkKind, writer, info.methodGroups.get(groupName), states);
+                }
+                states.clearArgs();
+            }
+
+            // Write out state initializers
+            for (String s : states.getStateInitializers()) {
+                writer.println(ident(1) + s);
+            }
+            writer.println();
+
+            // Write out the required fields
+            for (String s : states.getFields()) {
+                writer.println(ident(1) + s);
+            }
+            writer.println();
+
+            // Write out the required objects
+            for (String s : states.getStateOverrides()) {
+                writer.println(ident(1) + s);
+            }
+            writer.println();
+
+            // Finish class
+            writer.println("}");
+            writer.println();
+
+            writer.close();
+        } catch (IOException ex) {
+            throw new GenerationException("IOException", classInfo);
+        }
+    }
+
+    private void generatePadding(PrintWriter writer) {
+        for (int p = 0; p < 16; p++) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(ident(1));
+            sb.append("boolean jmh_pad_").append(p);
+            for (int q = 1; q < 16; q++) {
+                sb.append(", jmh_pad_").append(p).append("_").append(q);
+            }
+            sb.append(";");
+            writer.println(sb.toString());
+        }
+    }
+
+    private void generateImport(PrintWriter writer) {
+        Class<?>[] imports = new Class<?>[] {
+                List.class, AtomicInteger.class, AtomicIntegerFieldUpdater.class,
+                Collection.class, Collections.class, ArrayList.class, Arrays.class,
+                TimeUnit.class, Generated.class, CompilerControl.class,
+                InfraControl.class, ThreadControl.class, BlackHole.class,
+                Result.class, ThroughputResult.class, AverageTimeResult.class,
+                SampleTimeResult.class, SingleShotResult.class, SampleBuffer.class,
+                Mode.class, Fork.class, Measurement.class, Threads.class, Warmup.class,
+                BenchmarkMode.class, RawResults.class, ResultRole.class
+        };
+
+        for (Class<?> c : imports) {
+            writer.println("import " + c.getName() + ';');
+        }
+        writer.println();
+    }
+
+    /**
+     * Generate the method for a specific benchmark method
+     */
+    private void generateMethod(Mode benchmarkKind, PrintWriter writer, MethodGroup methodGroup, StateObjectHandler states) {
+        writer.println();
+        switch (benchmarkKind) {
+            case Throughput:
+                generateThroughput(writer, benchmarkKind, methodGroup, states);
+                break;
+            case AverageTime:
+                generateAverageTime(writer, benchmarkKind, methodGroup, states);
+                break;
+            case SampleTime:
+                generateSampleTime(writer, benchmarkKind, methodGroup, states);
+                break;
+            case SingleShotTime:
+                generateSingleShotTime(writer, benchmarkKind, methodGroup, states);
+                break;
+            default:
+                throw new AssertionError("Shouldn't be here");
+        }
+    }
+
+    private void generateThroughput(PrintWriter writer, Mode benchmarkKind, MethodGroup methodGroup, StateObjectHandler states) {
+        writer.println(ident(1) + "public Collection<? extends Result> " + methodGroup.getName() + "_" + benchmarkKind +
+                "(InfraControl control, ThreadControl threadControl) throws Throwable {");
+        writer.println();
+
+        methodProlog(writer, methodGroup);
+
+        boolean isSingleMethod = (methodGroup.methods().size() == 1);
+        int subGroup = -1;
+        for (MethodInfo method : methodGroup.methods()) {
+            compilerControl.defaultForceInline(method);
+
+            subGroup++;
+
+            writer.println(ident(2) + "if (threadControl.subgroup == " + subGroup + ") {");
+
+            iterationProlog(writer, 3, method, states);
+
+            // synchronize iterations prolog: announce ready
+            writer.println(ident(3) + "control.announceWarmupReady();");
+
+            // synchronize iterations prolog: catchup loop
+            writer.println(ident(3) + "while (control.warmupShouldWait) {");
+
+            invocationProlog(writer, 4, method, states, false);
+            writer.println(ident(4) + emitCall(method, states) + ';');
+            invocationEpilog(writer, 4, method, states, false);
+
+            writer.println(ident(3) + "}");
+            writer.println();
+
+            // control objects get a special treatment
+            for (StateObject so : states.getControls()) {
+                writer.println(ident(3) + so.localIdentifier + ".startMeasurement = true;");
+                writer.println(ident(3) + so.localIdentifier + ".iterationTime = control.getDuration();");
+            }
+
+            // measurement loop call
+            writer.println(ident(3) + "RawResults res = new RawResults(" + methodGroup.getOperationsPerInvocation() + "L);");
+            writer.println(ident(3) + method.getName() + "_" + benchmarkKind + "_measurementLoop" +
+                    "(control, res, " + states.getImplicit("bench").toLocal() + ", " + states.getImplicit("blackhole").toLocal() + prefix(states.getArgList(method)) + ");");
+
+            // control objects get a special treatment
+            for (StateObject so : states.getControls()) {
+                writer.println(ident(3) + so.localIdentifier + ".stopMeasurement = true;");
+            }
+
+            // synchronize iterations epilog: announce ready
+            writer.println(ident(3) + "control.announceWarmdownReady();");
+
+            // synchronize iterations epilog: catchup loop
+            writer.println(ident(3) + "while (control.warmdownShouldWait) {");
+
+            invocationProlog(writer, 4, method, states, false);
+            writer.println(ident(4) + emitCall(method, states) + ';');
+            invocationEpilog(writer, 4, method, states, false);
+
+            writer.println(ident(3) + "}");
+
+            // iteration prolog
+            iterationEpilog(writer, 3, method, states);
+
+            writer.println(ident(3) + "Collection<Result> results = new ArrayList<Result>();");
+            writer.println(ident(3) + "TimeUnit tu = (control.timeUnit != null) ? control.timeUnit : TimeUnit." + methodGroup.getOutputTimeUnit() + ";");
+            writer.println(ident(3) + "results.add(new ThroughputResult(ResultRole.PRIMARY, \"" + method.getName() + "\", res.getOperations(), res.getTime(), tu));");
+            if (!isSingleMethod) {
+                writer.println(ident(3) + "results.add(new ThroughputResult(ResultRole.SECONDARY, \"" + method.getName() + "\", res.getOperations(), res.getTime(), tu));");
+            }
+            for (String ops : states.getAuxResultNames(method)) {
+                writer.println(ident(3) + "results.add(new ThroughputResult(ResultRole.SECONDARY, \"" + ops + "\", " + states.getAuxResultAccessor(method, ops) + ", res.getTime(), tu));");
+            }
+            writer.println(ident(3) + "return results;");
+            writer.println(ident(2) + "} else");
+        }
+        writer.println(ident(3) + "throw new IllegalStateException(\"Harness failed to distribute threads among groups properly\");");
+        writer.println();
+
+        writer.println(ident(1) + "}");
+
+        // measurement loop bodies
+        for (MethodInfo method : methodGroup.methods()) {
+            String methodName = method.getName() + "_" + benchmarkKind + "_measurementLoop";
+            writer.println(ident(1) + "public " + (methodGroup.isStrictFP() ? "strictfp" : "") + " void " + methodName + "(InfraControl control, RawResults result, " + states.getImplicit("bench").toTypeDef() + ", " + states.getImplicit("blackhole").toTypeDef() + prefix(states.getTypeArgList(method)) + ") throws Throwable {");
+            writer.println(ident(2) + "long operations = 0;");
+            writer.println(ident(2) + "long realTime = 0;");
+            writer.println(ident(2) + "result.startTime = System.nanoTime();");
+            writer.println(ident(2) + "do {");
+
+            invocationProlog(writer, 3, method, states, true);
+            writer.println(ident(3) + emitCall(method, states) + ';');
+            invocationEpilog(writer, 3, method, states, true);
+
+            writer.println(ident(3) + "operations++;");
+            writer.println(ident(2) + "} while(!control.isDone);");
+            writer.println(ident(2) + "result.stopTime = System.nanoTime();");
+            writer.println(ident(2) + "result.realTime = realTime;");
+            writer.println(ident(2) + "result.operations = operations;");
+            writer.println(ident(1) + "}");
+            writer.println();
+        }
+    }
+
+    private void generateAverageTime(PrintWriter writer, Mode benchmarkKind, MethodGroup methodGroup, StateObjectHandler states) {
+        writer.println(ident(1) + "public Collection<? extends Result> " + methodGroup.getName() + "_" + benchmarkKind +
+                "(InfraControl control, ThreadControl threadControl) throws Throwable {");
+
+        methodProlog(writer, methodGroup);
+
+        boolean isSingleMethod = (methodGroup.methods().size() == 1);
+        int subGroup = -1;
+        for (MethodInfo method : methodGroup.methods()) {
+            compilerControl.defaultForceInline(method);
+
+            subGroup++;
+
+            writer.println(ident(2) + "if (threadControl.subgroup == " + subGroup + ") {");
+
+            iterationProlog(writer, 3, method, states);
+
+            // synchronize iterations prolog: announce ready
+            writer.println(ident(3) + "control.announceWarmupReady();");
+
+            // synchronize iterations prolog: catchup loop
+            writer.println(ident(3) + "while (control.warmupShouldWait) {");
+
+            invocationProlog(writer, 4, method, states, false);
+            writer.println(ident(4) + emitCall(method, states) + ';');
+            invocationEpilog(writer, 4, method, states, false);
+
+            writer.println(ident(3) + "}");
+            writer.println();
+
+            // control objects get a special treatment
+            for (StateObject so : states.getControls()) {
+                writer.println(ident(3) + so.localIdentifier + ".startMeasurement = true;");
+                writer.println(ident(3) + so.localIdentifier + ".iterationTime = control.getDuration();");
+            }
+
+            // measurement loop call
+            writer.println(ident(3) + "RawResults res = new RawResults(" + methodGroup.getOperationsPerInvocation() + "L);");
+            writer.println(ident(3) + method.getName() + "_" + benchmarkKind + "_measurementLoop(control, res, " + states.getImplicit("bench").toLocal() + ", " + states.getImplicit("blackhole").toLocal() + prefix(states.getArgList(method)) + ");");
+
+            // control objects get a special treatment
+            for (StateObject so : states.getControls()) {
+                writer.println(ident(3) + so.localIdentifier + ".stopMeasurement = true;");
+            }
+
+            // synchronize iterations epilog: announce ready
+            writer.println(ident(3) + "control.announceWarmdownReady();");
+
+            // synchronize iterations epilog: catchup loop
+            writer.println(ident(3) + "while (control.warmdownShouldWait) {");
+
+            invocationProlog(writer, 4, method, states, false);
+            writer.println(ident(4) + emitCall(method, states) + ';');
+            invocationEpilog(writer, 4, method, states, false);
+
+            writer.println(ident(3) + "}");
+
+            iterationEpilog(writer, 3, method, states);
+
+            writer.println(ident(3) + "Collection<Result> results = new ArrayList<Result>();");
+            writer.println(ident(3) + "TimeUnit tu = (control.timeUnit != null) ? control.timeUnit : TimeUnit." + methodGroup.getOutputTimeUnit() + ";");
+            writer.println(ident(3) + "results.add(new AverageTimeResult(ResultRole.PRIMARY, \"" + method.getName() + "\", res.getOperations(), res.getTime(), tu));");
+            if (!isSingleMethod) {
+                writer.println(ident(3) + "results.add(new AverageTimeResult(ResultRole.SECONDARY, \"" + method.getName() + "\", res.getOperations(), res.getTime(), tu));");
+            }
+            for (String ops : states.getAuxResultNames(method)) {
+                writer.println(ident(3) + "results.add(new AverageTimeResult(ResultRole.SECONDARY, \"" + ops + "\", " + states.getAuxResultAccessor(method, ops) + ", res.getTime(), tu));");
+            }
+            writer.println(ident(3) + "return results;");
+            writer.println(ident(2) + "} else");
+        }
+        writer.println(ident(3) + "throw new IllegalStateException(\"Harness failed to distribute threads among groups properly\");");
+        writer.println();
+
+        writer.println(ident(1) + "}");
+
+        // measurement loop bodies
+        for (MethodInfo method : methodGroup.methods()) {
+            writer.println(ident(1) + "public " + (methodGroup.isStrictFP() ? "strictfp" : "") +  " void " + method.getName() + "_" + benchmarkKind + "_measurementLoop" +
+                    "(InfraControl control, RawResults result, " + states.getImplicit("bench").toTypeDef() + ", " + states.getImplicit("blackhole").toTypeDef() +
+                    prefix(states.getTypeArgList(method)) + ") throws Throwable {");
+            writer.println(ident(2) + "long operations = 0;");
+            writer.println(ident(2) + "long realTime = 0;");
+            writer.println(ident(2) + "result.startTime = System.nanoTime();");
+            writer.println(ident(2) + "do {");
+
+            invocationProlog(writer, 3, method, states, true);
+            writer.println(ident(3) + emitCall(method, states) + ';');
+            invocationEpilog(writer, 3, method, states, true);
+
+            writer.println(ident(3) + "operations++;");
+            writer.println(ident(2) + "} while(!control.isDone);");
+            writer.println(ident(2) + "result.stopTime = System.nanoTime();");
+            writer.println(ident(2) + "result.realTime = realTime;");
+            writer.println(ident(2) + "result.operations = operations;");
+            writer.println(ident(1) + "}");
+            writer.println();
+        }
+    }
+
+    private void methodProlog(PrintWriter writer, MethodGroup methodGroup) {
+        // do nothing
+    }
+
+    private String prefix(String argList) {
+        if (argList.trim().isEmpty()) {
+            return "";
+        } else {
+            return ", " + argList;
+        }
+    }
+
+    private void generateSampleTime(PrintWriter writer, Mode benchmarkKind, MethodGroup methodGroup, StateObjectHandler states) {
+        writer.println(ident(1) + "public Collection<? extends Result> " + methodGroup.getName() + "_" + benchmarkKind +
+                "(InfraControl control, ThreadControl threadControl) throws Throwable {");
+        writer.println();
+
+        methodProlog(writer, methodGroup);
+
+        boolean isSingleMethod = (methodGroup.methods().size() == 1);
+        int subGroup = -1;
+        for (MethodInfo method : methodGroup.methods()) {
+            compilerControl.defaultForceInline(method);
+
+            subGroup++;
+
+            writer.println(ident(2) + "if (threadControl.subgroup == " + subGroup + ") {");
+
+            iterationProlog(writer, 3, method, states);
+
+            // synchronize iterations prolog: announce ready
+            writer.println(ident(3) + "control.announceWarmupReady();");
+
+            // synchronize iterations prolog: catchup loop
+            writer.println(ident(3) + "while (control.warmupShouldWait) {");
+
+            invocationProlog(writer, 4, method, states, false);
+            writer.println(ident(4) + emitCall(method, states) + ';');
+            invocationEpilog(writer, 4, method, states, false);
+
+            writer.println(ident(3) + "}");
+            writer.println();
+
+            // control objects get a special treatment
+            for (StateObject so : states.getControls()) {
+                writer.println(ident(3) + so.localIdentifier + ".startMeasurement = true;");
+                writer.println(ident(3) + so.localIdentifier + ".iterationTime = control.getDuration();");
+            }
+
+            // measurement loop call
+            writer.println(ident(3) + "SampleBuffer buffer = new SampleBuffer();");
+            writer.println(ident(3) + method.getName() + "_" + benchmarkKind + "_measurementLoop(control, buffer, " + states.getImplicit("bench").toLocal() + ", " + states.getImplicit("blackhole").toLocal() + prefix(states.getArgList(method)) + ");");
+
+            // control objects get a special treatment
+            for (StateObject so : states.getControls()) {
+                writer.println(ident(3) + so.localIdentifier + ".stopMeasurement = true;");
+            }
+
+            // synchronize iterations epilog: announce ready
+            writer.println(ident(3) + "control.announceWarmdownReady();");
+
+            // synchronize iterations epilog: catchup loop
+            writer.println(ident(3) + "while (control.warmdownShouldWait) {");
+
+            invocationProlog(writer, 4, method, states, false);
+            writer.println(ident(4) + emitCall(method, states) + ';');
+            invocationEpilog(writer, 4, method, states, false);
+
+            writer.println(ident(3) + "}");
+            writer.println();
+
+            iterationEpilog(writer, 3, method, states);
+
+            writer.println(ident(3) + "Collection<Result> results = new ArrayList<Result>();");
+            writer.println(ident(3) + "TimeUnit tu = (control.timeUnit != null) ? control.timeUnit : TimeUnit." + methodGroup.getOutputTimeUnit() + ";");
+            writer.println(ident(3) + "results.add(new SampleTimeResult(ResultRole.PRIMARY, \"" + method.getName() + "\", buffer, tu));");
+            if (!isSingleMethod) {
+                writer.println(ident(3) + "results.add(new SampleTimeResult(ResultRole.SECONDARY, \"" + method.getName() + "\", buffer, tu));");
+            }
+            writer.println(ident(3) + "return results;");
+            writer.println(ident(2) + "} else");
+        }
+        writer.println(ident(3) + "throw new IllegalStateException(\"Harness failed to distribute threads among groups properly\");");
+
+        writer.println(ident(1) + "}");
+
+        // measurement loop bodies
+        for (MethodInfo method : methodGroup.methods()) {
+            writer.println(ident(1) + "public " + (methodGroup.isStrictFP() ? "strictfp" : "") + " void " + method.getName() + "_" + benchmarkKind + "_measurementLoop(InfraControl control, SampleBuffer buffer, " + states.getImplicit("bench").toTypeDef() + ", " + states.getImplicit("blackhole").toTypeDef() + prefix(states.getTypeArgList(method)) + ") throws Throwable {");
+            writer.println(ident(2) + "long realTime = 0;");
+            writer.println(ident(2) + "int rnd = (int)System.nanoTime();");
+            writer.println(ident(2) + "int rndMask = 0;");
+            writer.println(ident(2) + "long time = 0;");
+            writer.println(ident(2) + "int currentStride = 0;");
+            writer.println(ident(2) + "do {");
+
+            invocationProlog(writer, 3, method, states, true);
+
+            writer.println(ident(3) + "rnd = (rnd * 1664525 + 1013904223);");
+            writer.println(ident(3) + "boolean sample = (rnd & rndMask) == 0;");
+            writer.println(ident(3) + "if (sample) {");
+            writer.println(ident(4) + "time = System.nanoTime();");
+            writer.println(ident(3) + "}");
+            writer.println(ident(3) + "" + emitCall(method, states) + ';');
+            writer.println(ident(3) + "if (sample) {");
+            writer.println(ident(4) + "buffer.add(System.nanoTime() - time);");
+            writer.println(ident(4) + "if (currentStride++ > 1000000) {");
+            writer.println(ident(5) + "buffer.half();");
+            writer.println(ident(5) + "currentStride = 0;");
+            writer.println(ident(5) + "rndMask = (rndMask << 1) + 1;");
+            writer.println(ident(4) + "}");
+            writer.println(ident(3) + "}");
+
+            invocationEpilog(writer, 3, method, states, true);
+
+            writer.println(ident(2) + "} while(!control.isDone);");
+
+            writer.println(ident(1) + "}");
+            writer.println();
+        }
+    }
+
+    private void generateSingleShotTime(PrintWriter writer, Mode benchmarkKind, MethodGroup methodGroup, StateObjectHandler states) {
+        writer.println(ident(1) + "public Collection<? extends Result> " + methodGroup.getName() + "_" + benchmarkKind + "(InfraControl control, ThreadControl threadControl) throws Throwable {");
+
+        methodProlog(writer, methodGroup);
+
+        writer.println(ident(2) + "long realTime = 0;");
+
+        boolean isSingleMethod = (methodGroup.methods().size() == 1);
+        int subGroup = -1;
+        for (MethodInfo method : methodGroup.methods()) {
+            compilerControl.defaultForceInline(method);
+
+            subGroup++;
+
+            writer.println(ident(2) + "if (threadControl.subgroup == " + subGroup + ") {");
+
+            iterationProlog(writer, 3, method, states);
+
+            invocationProlog(writer, 3, method, states, false);
+
+            writer.println(ident(3) + "long time1 = System.nanoTime();");
+            writer.println(ident(3) + "int batchSize = control.batchSize;");
+            writer.println(ident(3) + "for (int b = 0; b < batchSize; b++) {");
+            writer.println(ident(4) + emitCall(method, states) + ';');
+            writer.println(ident(3) + "}");
+            writer.println(ident(3) + "long time2 = System.nanoTime();");
+
+            invocationEpilog(writer, 3, method, states, false);
+
+            iterationEpilog(writer, 3, method, states);
+
+            writer.println(ident(3) + "Collection<Result> results = new ArrayList<Result>();");
+            writer.println(ident(3) + "TimeUnit tu = (control.timeUnit != null) ? control.timeUnit : TimeUnit." + methodGroup.getOutputTimeUnit() + ";");
+            writer.println(ident(3) + "results.add(new SingleShotResult(ResultRole.PRIMARY, \"" + method.getName() + "\", (realTime > 0) ? realTime : (time2 - time1), tu));");
+            if (!isSingleMethod) {
+                writer.println(ident(3) + "results.add(new SingleShotResult(ResultRole.SECONDARY, \"" + method.getName() + "\", (realTime > 0) ? realTime : (time2 - time1), tu));");
+            }
+            writer.println(ident(3) + "return results;");
+            writer.println(ident(2) + "} else");
+        }
+        writer.println(ident(3) + "throw new IllegalStateException(\"Harness failed to distribute threads among groups properly\");");
+        writer.println();
+
+        writer.println(ident(1) + "}");
+    }
+
+    private void invocationProlog(PrintWriter writer, int prefix, MethodInfo method, StateObjectHandler states, boolean pauseMeasurement) {
+        if (!states.getInvocationSetups(method).isEmpty()) {
+            for (String s : states.getInvocationSetups(method))
+                writer.println(ident(prefix) + s);
+            if (pauseMeasurement)
+                writer.println(ident(prefix) + "long rt = System.nanoTime();");
+            writer.println();
+        }
+    }
+
+    private void invocationEpilog(PrintWriter writer, int prefix, MethodInfo method, StateObjectHandler states, boolean pauseMeasurement) {
+        if (!states.getInvocationTearDowns(method).isEmpty()) {
+            writer.println();
+            if (pauseMeasurement)
+                writer.println(ident(prefix) + "realTime += (System.nanoTime() - rt);");
+            for (String s : states.getInvocationTearDowns(method))
+                writer.println(ident(prefix) + s);
+            writer.println();
+        }
+    }
+
+    private void iterationProlog(PrintWriter writer, int prefix, MethodInfo method, StateObjectHandler states) {
+        for (String s : states.getStateGetters(method)) writer.println(ident(prefix) + s);
+        writer.println();
+
+        writer.println(ident(prefix) + "control.preSetup();");
+
+        for (String s : states.getIterationSetups(method)) writer.println(ident(prefix) + s);
+        writer.println();
+    }
+
+    private void iterationEpilog(PrintWriter writer, int prefix, MethodInfo method, StateObjectHandler states) {
+        writer.println(ident(prefix) + "control.preTearDown();");
+
+        for (String s : states.getIterationTearDowns(method)) writer.println(ident(prefix) + s);
+        writer.println();
+
+        writer.println(ident(prefix) + "if (control.isLastIteration()) {");
+        for (String s : states.getRunTearDowns(method)) writer.println(ident(prefix + 1) + s);
+        for (String s : states.getStateDestructors(method)) writer.println(ident(prefix + 1) + s);
+        writer.println(ident(prefix) + "}");
+    }
+
+    private String emitCall(MethodInfo method, StateObjectHandler states) {
+        if ("void".equalsIgnoreCase(method.getReturnType())) {
+            return states.getImplicit("bench").localIdentifier + "." + method.getName() + "(" + states.getArgList(method) + ")";
+        } else {
+            return states.getImplicit("blackhole").localIdentifier + ".consume(" + states.getImplicit("bench").localIdentifier + "." + method.getName() + "(" + states.getArgList(method) + "))";
+        }
+    }
+
+    public static String ident(int prefix) {
+        char[] chars = new char[prefix*4];
+        for (int i = 0; i < prefix*4; i++) {
+            chars[i] = ' ';
+        }
+        return new String(chars);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGeneratorUtils.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.core;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.FieldInfo;
+import org.openjdk.jmh.generators.source.GeneratorSource;
+import org.openjdk.jmh.generators.source.MethodInfo;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class BenchmarkGeneratorUtils {
+
+    public static <T extends Annotation> Collection<MethodInfo> getMethodsAnnotatedWith(GeneratorSource source, Class<T> annClass) {
+        List<MethodInfo> mis = new ArrayList<MethodInfo>();
+        for (ClassInfo ci : source.getClasses()) {
+            for (MethodInfo mi : ci.getDeclaredMethods()) {
+                if (mi.getAnnotation(annClass) != null) {
+                    mis.add(mi);
+                }
+            }
+        }
+        return mis;
+    }
+
+    public static <T extends Annotation> Collection<ClassInfo> getClassesAnnotatedWith(GeneratorSource source, Class<T> annClass) {
+        List<ClassInfo> cis = new ArrayList<ClassInfo>();
+        for (ClassInfo ci : source.getClasses()) {
+            if (ci.getAnnotation(annClass) != null) {
+                cis.add(ci);
+            }
+        }
+        return cis;
+    }
+
+    public static <T extends Annotation> Collection<FieldInfo> getFieldsAnnotatedWith(GeneratorSource source, Class<T> annClass) {
+        List<FieldInfo> mis = new ArrayList<FieldInfo>();
+        for (ClassInfo ci : source.getClasses()) {
+            for (FieldInfo mi : ci.getDeclaredFields()) {
+                if (mi.getAnnotation(annClass) != null) {
+                    mis.add(mi);
+                }
+            }
+        }
+        return mis;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/CompilerControlPlugin.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.core;
+
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.GeneratorSource;
+import org.openjdk.jmh.generators.source.MethodInfo;
+import org.openjdk.jmh.runner.CompilerHints;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class CompilerControlPlugin implements Plugin {
+
+    private final List<String> lines = new ArrayList<String>();
+
+    private final Set<MethodInfo> defaultForceInlineMethods = new TreeSet<MethodInfo>(new Comparator<MethodInfo>() {
+        @Override
+        public int compare(MethodInfo o1, MethodInfo o2) {
+            return o1.getQualifiedName().compareTo(o2.getQualifiedName());
+        }
+    });
+
+    private final Set<ClassInfo> defaultForceInlineClasses = new TreeSet<ClassInfo>(new Comparator<ClassInfo>() {
+        @Override
+        public int compare(ClassInfo o1, ClassInfo o2) {
+            return o1.getQualifiedName().compareTo(o2.getQualifiedName());
+        }
+    });
+
+    public void defaultForceInline(MethodInfo methodInfo) {
+        defaultForceInlineMethods.add(methodInfo);
+    }
+
+    public void defaultForceInline(ClassInfo classInfo) {
+        defaultForceInlineClasses.add(classInfo);
+    }
+
+    public void process(GeneratorSource source) {
+        try {
+            for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, CompilerControl.class)) {
+                CompilerControl ann = element.getAnnotation(CompilerControl.class);
+                if (ann == null) {
+                    throw new IllegalStateException("No annotation");
+                }
+
+                CompilerControl.Mode command = ann.value();
+                lines.add(command.command() + "," + getName(element));
+            }
+
+            for (MethodInfo element : defaultForceInlineMethods) {
+                if (element.getAnnotation(CompilerControl.class) != null) continue;
+                lines.add(CompilerControl.Mode.INLINE.command() + "," + getName(element));
+            }
+
+            for (ClassInfo element : BenchmarkGeneratorUtils.getClassesAnnotatedWith(source, CompilerControl.class)) {
+                CompilerControl ann = element.getAnnotation(CompilerControl.class);
+                if (ann == null) {
+                    throw new IllegalStateException("No annotation");
+                }
+
+                CompilerControl.Mode command = ann.value();
+                lines.add(command.command() + "," + getName(element));
+            }
+
+            for (ClassInfo element : defaultForceInlineClasses) {
+                if (element.getAnnotation(CompilerControl.class) != null) continue;
+                lines.add(CompilerControl.Mode.INLINE.command() + "," + getName(element));
+            }
+        } catch (Throwable t) {
+            source.printError("Compiler control generators had thrown the unexpected exception", t);
+        }
+    }
+
+    @Override
+    public void finish(GeneratorSource source) {
+        try {
+            PrintWriter writer = new PrintWriter(source.newResource(CompilerHints.LIST.substring(1)));
+            for (String line : lines) {
+                writer.println(line);
+            }
+            writer.close();
+        } catch (IOException ex) {
+            source.printError("Error writing compiler hint list ", ex);
+        } catch (Throwable t) {
+            source.printError("Compiler control generators had thrown the unexpected exception", t);
+        }
+    }
+
+    private static String getName(MethodInfo mi) {
+       return mi.getOwner().getQualifiedName().replaceAll("\\.", "/") + "." + mi.getName();
+    }
+
+    private static String getName(ClassInfo ci) {
+      return ci.getQualifiedName().replaceAll("\\.", "/") + ".*";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/GroupValidationPlugin.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.core;
+
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.annotations.Group;
+import org.openjdk.jmh.annotations.GroupThreads;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.generators.source.GeneratorSource;
+import org.openjdk.jmh.generators.source.MethodInfo;
+
+public class GroupValidationPlugin implements Plugin {
+
+    @Override
+    public void process(GeneratorSource source) {
+        try {
+            for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, CompilerControl.class)) {
+                if (element.getAnnotation(Threads.class) != null) {
+                    source.printError("@" + Threads.class.getSimpleName() + " annotation is placed within " +
+                                    "the benchmark method with @" + Group.class.getSimpleName() + " annotation. " +
+                                    "This has ambiguous behavioral effect, and prohibited. " +
+                                    "Did you mean @" + GroupThreads.class.getSimpleName() + " instead?",
+                            element);
+                }
+            }
+        } catch (Throwable t) {
+            source.printError("Group validation generators had thrown the unexpected exception", t);
+        }
+    }
+
+    @Override
+    public void finish(GeneratorSource source) {
+        // do nothing
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/HelperMethodValidationPlugin.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.core;
+
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.generators.source.GeneratorSource;
+import org.openjdk.jmh.generators.source.MethodInfo;
+
+public class HelperMethodValidationPlugin implements Plugin {
+
+    @Override
+    public void process(GeneratorSource source) {
+        try {
+            for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, Setup.class)) {
+                // OK to have these annotation for @State objects
+                if (element.getOwner().getAnnotation(State.class) != null) continue;
+
+                // Abstract classes are not instantiated, assume OK
+                if (element.getOwner().isAbstract()) continue;
+
+                source.printError(
+                        "@" + Setup.class.getSimpleName() + " annotation is placed within " +
+                                "the class not having @" + State.class.getSimpleName() + " annotation. " +
+                                "This has no behavioral effect, and prohibited.",
+                        element);
+            }
+
+            for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, TearDown.class)) {
+                // OK to have these annotation for @State objects
+                if (element.getOwner().getAnnotation(State.class) != null) continue;
+
+                // Abstract classes are not instantiated, assume OK
+                if (element.getOwner().isAbstract()) continue;
+
+                source.printError(
+                            "@" + TearDown.class.getSimpleName() + " annotation is placed within " +
+                                    "the class not having @" + State.class.getSimpleName() + " annotation. " +
+                                    "This can be futile if no @State-bearing subclass is used.",
+                            element);
+            }
+
+        } catch (Throwable t) {
+            source.printError("Helper method validation generators had thrown the unexpected exception.", t);
+        }
+    }
+
+    @Override
+    public void finish(GeneratorSource source) {
+        // do nothing
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/ParamValidationPlugin.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.core;
+
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.generators.source.FieldInfo;
+import org.openjdk.jmh.generators.source.GeneratorSource;
+
+public class ParamValidationPlugin implements Plugin {
+
+    @Override
+    public void process(GeneratorSource source) {
+        try {
+            for (FieldInfo element : BenchmarkGeneratorUtils.getFieldsAnnotatedWith(source, Param.class)) {
+                if (!element.isPublic()) {
+                    source.printError(
+                            "@" + Param.class.getSimpleName() + " annotation is not acceptable on non-public field.",
+                            element
+                    );
+                }
+
+                if (element.isStatic()) {
+                    source.printError(
+                            "@" + Param.class.getSimpleName() + " annotation is not acceptable on static fields.",
+                            element
+                    );
+                }
+
+                if (element.getOwner().getAnnotationRecursive(State.class) == null) {
+                    source.printError(
+                            "@" + Param.class.getSimpleName() + " annotation should be placed in @" + State.class.getSimpleName() +
+                                    "-annotated class.",
+                            element
+                    );
+                }
+
+
+                String[] values = element.getAnnotation(Param.class).value();
+
+                if (values.length >= 1 && !values[0].equalsIgnoreCase(Param.BLANK_ARGS)) {
+                    String type = element.getType();
+                    for (String val : values) {
+                        if (!isConforming(val, type)) {
+                            source.printError(
+                                    "Some @" + Param.class.getSimpleName() + " values can not be converted to target type: " +
+                                    "\"" + val + "\" can not be converted to " + type,
+                                    element
+                            );
+                        }
+                    }
+                }
+
+            }
+        } catch (Throwable t) {
+            source.printError("Param validation generators had thrown the unexpected exception.", t);
+        }
+    }
+
+    private boolean isConforming(String val, String type) {
+        if (type.equalsIgnoreCase("java.lang.String")) {
+            return true;
+        }
+        if (type.equalsIgnoreCase("boolean") || type.equalsIgnoreCase("java.lang.Boolean")) {
+            return (val.equalsIgnoreCase("true") || val.equalsIgnoreCase("false"));
+        }
+        if (type.equalsIgnoreCase("byte") || type.equalsIgnoreCase("java.lang.Byte")) {
+            try {
+                Byte.valueOf(val);
+                return true;
+            } catch (NumberFormatException nfe){
+            }
+        }
+        if (type.equalsIgnoreCase("char") || type.equalsIgnoreCase("java.lang.Character")) {
+            return (val.length() != 0);
+        }
+        if (type.equalsIgnoreCase("short") || type.equalsIgnoreCase("java.lang.Short")) {
+            try {
+                Short.valueOf(val);
+                return true;
+            } catch (NumberFormatException nfe){
+            }
+        }
+        if (type.equalsIgnoreCase("int") || type.equalsIgnoreCase("java.lang.Integer")) {
+            try {
+                Integer.valueOf(val);
+                return true;
+            } catch (NumberFormatException nfe){
+            }
+        }
+        if (type.equalsIgnoreCase("float") || type.equalsIgnoreCase("java.lang.Float")) {
+            try {
+                Float.valueOf(val);
+                return true;
+            } catch (NumberFormatException nfe){
+            }
+        }
+        if (type.equalsIgnoreCase("long") || type.equalsIgnoreCase("java.lang.Long")) {
+            try {
+                Long.valueOf(val);
+                return true;
+            } catch (NumberFormatException nfe){
+            }
+        }
+        if (type.equalsIgnoreCase("double") || type.equalsIgnoreCase("java.lang.Double")) {
+            try {
+                Double.valueOf(val);
+                return true;
+            } catch (NumberFormatException nfe){
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void finish(GeneratorSource source) {
+        // do nothing
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/Plugin.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.core;
+
+import org.openjdk.jmh.generators.source.GeneratorSource;
+
+public interface Plugin {
+
+    void process(GeneratorSource source);
+
+    void finish(GeneratorSource source);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObjectHandler.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,612 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.core;
+
+import org.openjdk.jmh.annotations.AuxCounters;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.FieldInfo;
+import org.openjdk.jmh.generators.source.GenerationException;
+import org.openjdk.jmh.generators.source.HelperMethodInvocation;
+import org.openjdk.jmh.generators.source.HelperType;
+import org.openjdk.jmh.generators.source.MethodInfo;
+import org.openjdk.jmh.generators.source.ParameterInfo;
+import org.openjdk.jmh.generators.source.StateObject;
+import org.openjdk.jmh.logic.Control;
+import org.openjdk.jmh.util.internal.HashMultimap;
+import org.openjdk.jmh.util.internal.Multimap;
+import org.openjdk.jmh.util.internal.TreesetMultimap;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+public class StateObjectHandler {
+
+    private final Multimap<String, StateObject> args;
+    private final Map<String, StateObject> implicits;
+    private final Set<StateObject> stateObjects;
+    private final Multimap<StateObject, HelperMethodInvocation> helpersByState;
+
+    private final Map<String, Integer> globalIndexByType = new HashMap<String, Integer>();
+    private final Map<String, Integer> groupIndexByType = new HashMap<String, Integer>();
+    private final Map<String, Integer> localIndexByType = new HashMap<String, Integer>();
+
+    private final HashMap<String, String> collapsedTypes = new HashMap<String, String>();
+    private int collapsedIndex = 0;
+
+    private final Set<String> claimedJmhTypes = new HashSet<String>();
+    private final HashMap<String, String> jmhTypes = new HashMap<String, String>();
+    private final Multimap<String, String> auxNames = new HashMultimap<String, String>();
+    private final Map<String, String> auxAccessors = new HashMap<String, String>();
+
+    public StateObjectHandler() {
+        this.args = new HashMultimap<String, StateObject>();
+        this.implicits = new HashMap<String, StateObject>();
+        this.stateObjects = new HashSet<StateObject>();
+        this.helpersByState = new TreesetMultimap<StateObject, HelperMethodInvocation>();
+    }
+
+    private String getJMHtype(String type) {
+        String jmhType = jmhTypes.get(type);
+        if (jmhType == null) {
+            int v = 1;
+            do {
+                jmhType = getBaseType(type) + "_" + v + "_jmh";
+                v++;
+            } while (!claimedJmhTypes.add(jmhType));
+            jmhTypes.put(type, jmhType);
+        }
+        return jmhType;
+    }
+
+    private String getBaseType(String type) {
+        return type.substring(type.lastIndexOf(".") + 1);
+    }
+
+    public void bindArg(MethodInfo mi, ParameterInfo pi) {
+        State ann = pi.getType().getAnnotation(State.class);
+        if (ann != null) {
+            bindState(mi, pi.getType(), ann.value(), null);
+        } else {
+            throw new IllegalStateException("The method parameter is not a @State: " + pi);
+        }
+    }
+
+    public void bindImplicit(ClassInfo ci, String label) {
+        bindImplicit(ci, label, Scope.Thread);
+    }
+
+    public void bindImplicit(ClassInfo ci, String label, Scope scope) {
+        State ann = ci.getAnnotation(State.class);
+        bindState(null, ci, (ann != null) ? ann.value() : scope, label);
+    }
+
+    private void bindState(MethodInfo execMethod, ClassInfo ci, Scope scope, String implicitLabel) {
+        Integer index;
+        String className = ci.getQualifiedName();
+        switch (scope) {
+            case Benchmark: {
+                index = globalIndexByType.get(className);
+                if (index == null) {
+                    index = 0;
+                    globalIndexByType.put(className, index);
+                }
+                break;
+            }
+            case Group:
+                index = groupIndexByType.get(className);
+                if (index == null) {
+                    index = 0;
+                    groupIndexByType.put(className, index);
+                }
+                break;
+            case Thread: {
+                index = localIndexByType.get(className);
+                if (index == null) {
+                    index = -1;
+                }
+                index++;
+                localIndexByType.put(className, index);
+                break;
+            }
+            default:
+                throw new IllegalStateException("Unknown scope: " + scope);
+        }
+
+        StateObject so;
+        if (implicitLabel != null) {
+            so = new StateObject(className, getJMHtype(className), scope, "f_" + implicitLabel, "l_" + implicitLabel);
+            implicits.put(implicitLabel, so);
+        } else {
+            String identifier = collapseTypeName(className) + index;
+            so = new StateObject(className, getJMHtype(className), scope, "f_" + identifier, "l_" + identifier);
+            args.put(execMethod.getName(), so);
+        }
+
+        // auxiliary result, produce the accessors
+        if (ci.getAnnotation(AuxCounters.class) != null) {
+            if (scope != Scope.Thread) {
+                throw new GenerationException("@" + AuxCounters.class.getSimpleName() +
+                        " can only be used with " + Scope.class.getSimpleName() + "." + Scope.Thread + " states.", ci);
+            }
+
+            for (FieldInfo sub : ci.getDeclaredFields()) {
+                if (sub.isPublic()) {
+                    String fieldType = sub.getType();
+                    if (fieldType.equals("int") || fieldType.equals("long")) {
+                        String name = sub.getName();
+                        String meth = execMethod.getName();
+                        auxNames.put(meth, name);
+                        String prev = auxAccessors.put(meth + name, so.localIdentifier + "." + name);
+                        if (prev != null) {
+                            throw new GenerationException("Conflicting @" + AuxCounters.class.getSimpleName() +
+                                " counters. Make sure there are no @" + State.class.getSimpleName() + "-s with the same counter " +
+                                " injected into this method.", sub);
+                        }
+                    }
+                }
+            }
+
+            for (MethodInfo sub : ci.getDeclaredMethods()) {
+                if (sub.isPublic()) {
+                    String returnType = sub.getReturnType();
+                    if (returnType.equals("int") || returnType.equals("long")) {
+                        String name = sub.getName();
+                        String meth = execMethod.getName();
+                        auxNames.put(meth, name);
+                        String prev = auxAccessors.put(meth + name, so.localIdentifier + "." + name + "()");
+                        if (prev != null) {
+                            throw new GenerationException("Conflicting @" + AuxCounters.class.getSimpleName() +
+                                    " counters. Make sure there are no @" + State.class.getSimpleName() + "-s with the same counter " +
+                                    " injected into this method.", sub);
+                        }
+                    }
+                }
+            }
+        }
+
+        stateObjects.add(so);
+
+        // walk the type hierarchy up to discover inherited @Params
+        for (FieldInfo fi : ci.getFields()) {
+            if (fi.getAnnotation(Param.class) != null) {
+                so.addParam(fi);
+            }
+        }
+
+        // put the @State objects helper methods
+        for (MethodInfo mi : ci.getMethods()) {
+            Setup setupAnn = mi.getAnnotation(Setup.class);
+            if (setupAnn != null) {
+                helpersByState.put(so, new HelperMethodInvocation(mi, so, setupAnn.value(), HelperType.SETUP));
+            }
+
+            TearDown tearDownAnn = mi.getAnnotation(TearDown.class);
+            if (tearDownAnn != null) {
+                helpersByState.put(so, new HelperMethodInvocation(mi, so, tearDownAnn.value(), HelperType.TEARDOWN));
+            }
+        }
+
+    }
+
+    public String getArgList(MethodInfo methodInfo) {
+        StringBuilder sb = new StringBuilder();
+
+        int i = 0;
+        for (StateObject so : args.get(methodInfo.getName())) {
+            if (i != 0) {
+                sb.append(", ");
+            }
+            sb.append(so.toLocal());
+            i++;
+        }
+        return sb.toString();
+    }
+
+    public String getTypeArgList(MethodInfo methodInfo) {
+        StringBuilder sb = new StringBuilder();
+
+        int i = 0;
+        for (StateObject so : args.get(methodInfo.getName())) {
+            if (i != 0) {
+                sb.append(", ");
+            }
+            sb.append(so.toTypeDef());
+            i++;
+        }
+        return sb.toString();
+    }
+
+    public static Collection<StateObject> cons(Collection<StateObject>... colls) {
+        SortedSet<StateObject> r = new TreeSet<StateObject>(StateObject.ID_COMPARATOR);
+        for (Collection<StateObject> coll : colls) {
+            r.addAll(coll);
+        }
+        return r;
+    }
+
+    public Collection<String> getHelperBlock(MethodInfo method, Level helperLevel, HelperType type) {
+
+        Collection<StateObject> states = cons(args.get(method.getName()), implicits.values(), getControls());
+
+        // Look for the offending methods.
+        // This will be used to skip the irrelevant blocks for state objects down the stream.
+        Set<StateObject> hasHelpers = new HashSet<StateObject>();
+        for (StateObject so : states) {
+            for (HelperMethodInvocation hmi : helpersByState.get(so)) {
+                if (hmi.helperLevel == helperLevel) hasHelpers.add(so);
+            }
+        }
+
+        List<String> result = new ArrayList<String>();
+
+        // Handle Thread object helpers
+        for (StateObject so : states) {
+            if (so.scope != Scope.Thread) continue;
+            if (!hasHelpers.contains(so)) continue;
+
+            if (type == HelperType.SETUP) {
+                result.add("if (!" + so.localIdentifier + ".ready" + helperLevel + ") {");
+                for (HelperMethodInvocation mi : helpersByState.get(so)) {
+                    if (mi.helperLevel == helperLevel && mi.type == HelperType.SETUP) {
+                        result.add("    " + so.localIdentifier + "." + mi.method.getName() + "();");
+                    }
+                }
+                result.add("    " + so.localIdentifier + ".ready" + helperLevel + " = true;");
+                result.add("}");
+            }
+
+            if (type == HelperType.TEARDOWN) {
+                result.add("if (" + so.localIdentifier + ".ready" + helperLevel + ") {");
+                for (HelperMethodInvocation mi : helpersByState.get(so)) {
+                    if (mi.helperLevel == helperLevel && mi.type == HelperType.TEARDOWN) {
+                        result.add("    " + so.localIdentifier + "." + mi.method.getName() + "();");
+                    }
+                }
+                result.add("    " + so.localIdentifier + ".ready" + helperLevel + " = false;");
+                result.add("}");
+            }
+        }
+
+        // Handle Benchmark/Group object helpers
+        for (StateObject so : states) {
+            if (so.scope != Scope.Benchmark && so.scope != Scope.Group) continue;
+            if (!hasHelpers.contains(so)) continue;
+
+            if (type == HelperType.SETUP) {
+                result.add("while(!" + so.type + ".setup" + helperLevel + "MutexUpdater.compareAndSet(" + so.localIdentifier + ", 0, 1)) {");
+                result.add("    if (Thread.interrupted()) throw new InterruptedException();");
+                result.add("}");
+                result.add("try {");
+                result.add("    if (!" + so.localIdentifier + ".ready" + helperLevel + ") {");
+                for (HelperMethodInvocation mi : helpersByState.get(so)) {
+                    if (mi.helperLevel == helperLevel && mi.type == HelperType.SETUP) {
+                        result.add("        " + so.localIdentifier + "." + mi.method.getName() + "();");
+                    }
+                }
+                result.add("        " + so.localIdentifier + ".ready" + helperLevel + " = true;");
+                result.add("    }");
+                result.add("} finally {");
+                result.add("    " + so.type + ".setup" + helperLevel + "MutexUpdater.set(" + so.localIdentifier + ", 0);");
+                result.add("}");
+            }
+
+            if (type == HelperType.TEARDOWN) {
+                result.add("while(!" + so.type + ".tear" + helperLevel + "MutexUpdater.compareAndSet(" + so.localIdentifier + ", 0, 1)) {");
+                result.add("    if (Thread.interrupted()) throw new InterruptedException();");
+                result.add("}");
+                result.add("try {");
+                result.add("    if (" + so.localIdentifier + ".ready" + helperLevel + ") {");
+                for (HelperMethodInvocation mi : helpersByState.get(so)) {
+                    if (mi.helperLevel == helperLevel && mi.type == HelperType.TEARDOWN) {
+                        result.add("        " + so.localIdentifier + "." + mi.method.getName() + "();");
+                    }
+                }
+                result.add("        " + so.localIdentifier + ".ready" + helperLevel + " = false;");
+                result.add("    }");
+                result.add("} finally {");
+                result.add("    " + so.type + ".tear" + helperLevel + "MutexUpdater.set(" + so.localIdentifier + ", 0);");
+                result.add("}");
+            }
+        }
+
+        return result;
+    }
+
+    public Collection<String> getInvocationSetups(MethodInfo method) {
+        return getHelperBlock(method, Level.Invocation, HelperType.SETUP);
+    }
+
+    public Collection<String> getInvocationTearDowns(MethodInfo method) {
+        return getHelperBlock(method, Level.Invocation, HelperType.TEARDOWN);
+    }
+
+    public Collection<String> getIterationSetups(MethodInfo method) {
+        return getHelperBlock(method, Level.Iteration, HelperType.SETUP);
+    }
+
+    public Collection<String> getIterationTearDowns(MethodInfo method) {
+        return getHelperBlock(method, Level.Iteration, HelperType.TEARDOWN);
+    }
+
+    public Collection<String> getRunSetups(MethodInfo method) {
+        return getHelperBlock(method, Level.Trial, HelperType.SETUP);
+    }
+
+    public Collection<String> getRunTearDowns(MethodInfo method) {
+        return getHelperBlock(method, Level.Trial, HelperType.TEARDOWN);
+    }
+
+    public List<String> getStateInitializers() {
+        Collection<StateObject> sos = cons(stateObjects);
+
+        List<String> result = new ArrayList<String>();
+
+        for (StateObject so : sos) {
+            if (so.scope != Scope.Benchmark) continue;
+
+            result.add("");
+            result.add("static volatile " + so.type + " " + so.fieldIdentifier + ";");
+            result.add("");
+            result.add(so.type + " tryInit_" + so.fieldIdentifier + "(InfraControl control, " + so.type + " val) throws Throwable {");
+            result.add("    synchronized(this.getClass()) {");
+            result.add("        if (" + so.fieldIdentifier + " == null) {");
+            result.add("            " + so.fieldIdentifier + " = val;");
+            result.add("        }");
+            result.add("        if (!" + so.fieldIdentifier + ".ready" + Level.Trial + ") {");
+            for (String paramName : so.getParamsLabels()) {
+                result.add("            " + so.fieldIdentifier + "." + paramName + " = " + so.getParamAccessor(paramName) + ";");
+            }
+            for (HelperMethodInvocation hmi : helpersByState.get(so)) {
+                if (hmi.helperLevel != Level.Trial) continue;
+                if (hmi.type != HelperType.SETUP) continue;
+                result.add("            " + so.fieldIdentifier + "." + hmi.method.getName() + "();");
+            }
+            result.add("            " + so.fieldIdentifier + ".ready" + Level.Trial + " = true;");
+            result.add("        }");
+            result.add("    }");
+            result.add("    return " + so.fieldIdentifier + ";");
+            result.add("}");
+        }
+
+        for (StateObject so : sos) {
+            if (so.scope != Scope.Thread) continue;
+
+            result.add("");
+            result.add(so.type + " " + so.fieldIdentifier + ";");
+            result.add("");
+            result.add(so.type + " tryInit_" + so.fieldIdentifier + "(InfraControl control, " + so.type + " val) throws Throwable {");
+            result.add("    if (" + so.fieldIdentifier + " == null) {");
+            for (String paramName : so.getParamsLabels()) {
+                result.add("                val." + paramName + " = " + so.getParamAccessor(paramName) + ";");
+            }
+            for (HelperMethodInvocation hmi : helpersByState.get(so)) {
+                if (hmi.helperLevel != Level.Trial) continue;
+                if (hmi.type != HelperType.SETUP) continue;
+                result.add("                val." + hmi.method.getName() + "();");
+            }
+            result.add("                " + "val.ready" + Level.Trial + " = true;");
+            result.add("          " + so.fieldIdentifier + " = val;");
+            result.add("    }");
+            result.add("    return " + so.fieldIdentifier + ";");
+            result.add("}");
+        }
+
+        for (StateObject so : sos) {
+            if (so.scope != Scope.Group) continue;
+
+            result.add("");
+            result.add("static java.util.Map<Integer, " + so.type + "> " + so.fieldIdentifier + "_map = java.util.Collections.synchronizedMap(new java.util.HashMap<Integer, " + so.type + ">());");
+            result.add("");
+            result.add(so.type + " tryInit_" + so.fieldIdentifier + "(InfraControl control, int groupId, " + so.type + " val) throws Throwable {");
+            result.add("    synchronized(this.getClass()) {");
+            result.add("        " + so.type + " local = " + so.fieldIdentifier + "_map.get(groupId);");
+            result.add("        if (local == null) {");
+            result.add("            " + so.fieldIdentifier + "_map.put(groupId, val);");
+            result.add("            local = val;");
+            result.add("        }");
+            result.add("        if (!local.ready" + Level.Trial + ") {");
+            for (String paramName : so.getParamsLabels()) {
+                result.add("            local." + paramName + " = " + so.getParamAccessor(paramName) + ";");
+            }
+            for (HelperMethodInvocation hmi : helpersByState.get(so)) {
+                if (hmi.helperLevel != Level.Trial) continue;
+                if (hmi.type != HelperType.SETUP) continue;
+                result.add("            local." + hmi.method.getName() + "();");
+            }
+            result.add("            " + "local.ready" + Level.Trial + " = true;");
+            result.add("            " + so.fieldIdentifier + "_map.put(groupId, val);");
+            result.add("        }");
+            result.add("        return local;");
+            result.add("    }");
+            result.add("}");
+        }
+        return result;
+    }
+
+    public Collection<String> getStateDestructors(MethodInfo method) {
+        Collection<StateObject> sos = cons(args.get(method.getName()), implicits.values());
+
+        List<String> result = new ArrayList<String>();
+        for (StateObject so : sos) {
+            if (so.scope != Scope.Benchmark) continue;
+            result.add("synchronized(this.getClass()) {");
+            result.add("    " + so.fieldIdentifier + " = null;");
+            result.add("}");
+        }
+
+        for (StateObject so : sos) {
+            if (so.scope != Scope.Thread) continue;
+            result.add("" + so.fieldIdentifier + " = null;");
+        }
+
+        for (StateObject so : sos) {
+            if (so.scope != Scope.Group) continue;
+            result.add("synchronized(this.getClass()) {");
+            result.add("    " + so.fieldIdentifier + "_map.remove(threadControl.group);");
+            result.add("}");
+        }
+        return result;
+    }
+
+    public List<String> getStateGetters(MethodInfo method) {
+        List<String> result = new ArrayList<String>();
+        for (StateObject so : cons(args.get(method.getName()), implicits.values(), getControls())) {
+            switch (so.scope) {
+                case Benchmark:
+                case Thread:
+                    result.add(so.type + " " + so.localIdentifier + " = tryInit_" + so.fieldIdentifier + "(control, new " + so.type + "());");
+                    break;
+                case Group:
+                    result.add(so.type + " " + so.localIdentifier + " = tryInit_" + so.fieldIdentifier + "(control, threadControl.group, new " + so.type + "());");
+                    break;
+                default:
+                    throw new IllegalStateException("Unhandled scope: " + so.scope);
+            }
+        }
+        return result;
+    }
+
+    public List<String> getStateOverrides() {
+        Set<String> visited = new HashSet<String>();
+
+        List<String> result = new ArrayList<String>();
+        for (StateObject so : cons(stateObjects)) {
+            if (!visited.add(so.userType)) continue;
+            result.add("static class " + so.type + "_B1 extends " + so.userType + " {");
+            padding(result, "b1");
+            result.add("}");
+            result.add("");
+            result.add("static class " + so.type + "_B2 extends " + so.type + "_B1 {");
+
+
+            for (Level level : Level.values()) {
+                result.add("    public volatile int setup" + level + "Mutex;");
+                result.add("    public volatile int tear" + level + "Mutex;");
+                result.add("    public final static AtomicIntegerFieldUpdater setup" + level + "MutexUpdater = " +
+                        "AtomicIntegerFieldUpdater.newUpdater(" + so.type + "_B2.class, \"setup" + level + "Mutex\");");
+                result.add("    public final static AtomicIntegerFieldUpdater tear" + level + "MutexUpdater = " +
+                        "AtomicIntegerFieldUpdater.newUpdater(" + so.type + "_B2.class, \"tear" + level + "Mutex\");");
+                result.add("");
+            }
+
+            switch (so.scope) {
+                case Benchmark:
+                case Group:
+                    for (Level level : Level.values()) {
+                        result.add("    public volatile boolean ready" + level + ";");
+                    }
+                    break;
+                case Thread:
+                    for (Level level : Level.values()) {
+                        result.add("    public boolean ready" + level + ";");
+                    }
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown state scope: " + so.scope);
+            }
+
+            result.add("}");
+            result.add("");
+            result.add("static class " + so.type + "_B3 extends " + so.type + "_B2 {");
+            padding(result, "b3");
+            result.add("}");
+            result.add("");
+            result.add("static final class " + so.type + " extends " + so.type + "_B3 {");
+            result.add("}");
+            result.add("");
+        }
+        return result;
+    }
+
+    public static void padding(List<String> lines, String suffix) {
+        for (int p = 0; p < 16; p++) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("    boolean jmh_").append(suffix).append("_pad_").append(p);
+            for (int q = 1; q < 16; q++) {
+                sb.append(", jmh_").append(suffix).append("_pad_").append(p).append("_").append(q);
+            }
+            sb.append(";");
+            lines.add(sb.toString());
+        }
+    }
+
+    public void clearArgs() {
+        args.clear();
+    }
+
+    public Collection<String> getFields() {
+        return Collections.emptyList();
+    }
+
+    private String collapseTypeName(String e) {
+        if (collapsedTypes.containsKey(e)) {
+            return collapsedTypes.get(e);
+        }
+
+        String[] strings = e.split("\\.");
+        String name = strings[strings.length - 1].toLowerCase();
+
+        String collapsedName = name + (collapsedIndex++) + "_";
+        collapsedTypes.put(e, collapsedName);
+        return collapsedName;
+    }
+
+    public StateObject getImplicit(String label) {
+        return implicits.get(label);
+    }
+
+    public Collection<StateObject> getControls() {
+        Collection<StateObject> s = new ArrayList<StateObject>();
+        for (StateObject so : cons(args.values())) {
+            if (so.userType.equals(Control.class.getName())) {
+                s.add(so);
+            }
+        }
+        return s;
+    }
+
+    public Collection<String> getAuxResultNames(MethodInfo method) {
+        return auxNames.get(method.getName());
+    }
+
+    public String getAuxResultAccessor(MethodInfo method, String name) {
+        return auxAccessors.get(method.getName() + name);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/BenchmarkInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+import java.util.Map;
+
+public class BenchmarkInfo {
+    public final String userName;
+    public final String generatedName;
+    public final String generatedPackageName;
+    public final String generatedClassName;
+    public final Map<String, MethodGroup> methodGroups;
+
+    public BenchmarkInfo(String userName, String generatedPackageName, String generatedClassName, Map<String, MethodGroup> methods) {
+        this.userName = userName;
+        this.generatedPackageName = generatedPackageName;
+        this.generatedClassName = generatedClassName;
+        this.generatedName = generatedPackageName + "." + generatedClassName;
+        this.methodGroups = methods;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        BenchmarkInfo that = (BenchmarkInfo) o;
+
+        if (!userName.equals(that.userName)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return userName.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/ClassInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+
+/**
+ * Class metadata.
+ */
+public interface ClassInfo extends MetadataInfo {
+
+    String getPackageName();
+
+    String getNestedName();
+
+    String getQualifiedName();
+
+    Collection<FieldInfo> getDeclaredFields();
+
+    Collection<FieldInfo> getFields();
+
+    Collection<MethodInfo> getConstructors();
+
+    Collection<MethodInfo> getDeclaredMethods();
+
+    Collection<MethodInfo> getMethods();
+
+    Collection<ClassInfo> getSuperclasses();
+
+    <T extends Annotation> T getAnnotation(Class<T> annClass);
+
+    <T extends Annotation> T getAnnotationRecursive(Class<T> annClass);
+
+    boolean isNested();
+
+    boolean isAbstract();
+
+    boolean isPublic();
+
+    boolean isStatic();
+
+    boolean isStrictFP();
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/FieldInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+import java.lang.annotation.Annotation;
+
+public interface FieldInfo extends MetadataInfo {
+
+    String getName();
+
+    String getType();
+
+    boolean isPublic();
+
+    boolean isStatic();
+
+    <T extends Annotation> T getAnnotation(Class<T> annClass);
+
+    ClassInfo getOwner();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/GenerationException.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+public class GenerationException extends RuntimeException {
+
+    private final MetadataInfo element;
+
+    public GenerationException(String message, MetadataInfo element) {
+        super(message);
+        this.element = element;
+    }
+
+    public MetadataInfo getElement() {
+        return element;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/GeneratorSource.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Collection;
+
+public interface GeneratorSource {
+
+    Collection<ClassInfo> getClasses();
+
+    ClassInfo resolveClass(String className);
+
+    Writer newResource(String path) throws IOException;
+
+    Writer newFile(String objectName) throws IOException;
+
+    void printError(String message);
+
+    void printError(String message, MetadataInfo element);
+
+    void printError(String message, Throwable throwable);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/HelperMethodInvocation.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+import org.openjdk.jmh.annotations.Level;
+
+public class HelperMethodInvocation implements Comparable<HelperMethodInvocation> {
+    public final MethodInfo method;
+    public final StateObject state;
+    public final Level helperLevel;
+    public final HelperType type;
+
+    public HelperMethodInvocation(MethodInfo method, StateObject state, Level helperLevel, HelperType type) {
+        this.method = method;
+        this.state = state;
+        this.helperLevel = helperLevel;
+        this.type = type;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        HelperMethodInvocation that = (HelperMethodInvocation) o;
+
+        if (helperLevel != that.helperLevel) return false;
+        if (!method.equals(that.method)) return false;
+        if (!state.equals(that.state)) return false;
+        if (type != that.type) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = method.hashCode();
+        result = 31 * result + state.hashCode();
+        result = 31 * result + helperLevel.hashCode();
+        result = 31 * result + type.hashCode();
+        return result;
+    }
+
+    @Override
+    public int compareTo(HelperMethodInvocation o) {
+        return method.compareTo(o.method);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/HelperType.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+public enum HelperType {
+    SETUP,
+    TEARDOWN,
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/MetadataInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+public interface MetadataInfo {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodGroup.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OperationsPerInvocation;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.parameters.TimeValue;
+import org.openjdk.jmh.util.internal.Optional;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
+
+public class MethodGroup implements Comparable<MethodGroup> {
+    private final String name;
+    private final Set<MethodInvocation> methods;
+    private final EnumSet<Mode> modes;
+    private final Map<String, String[]> params;
+    private boolean strictFP;
+
+    public MethodGroup(String name) {
+        this.name = name;
+        this.methods = new TreeSet<MethodInvocation>();
+        this.modes = EnumSet.noneOf(Mode.class);
+        this.params = new TreeMap<String, String[]>();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MethodGroup methodGroup = (MethodGroup) o;
+
+        if (!name.equals(methodGroup.name)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public int compareTo(MethodGroup o) {
+        return name.compareTo(o.name);
+    }
+
+    public void addMethod(MethodInfo method, int threads) {
+        methods.add(new MethodInvocation(method, threads));
+    }
+
+    public Collection<MethodInfo> methods() {
+        Collection<MethodInfo> result = new ArrayList<MethodInfo>();
+        for (MethodInvocation m : methods) {
+            result.add(m.method);
+        }
+        return result;
+    }
+
+    public Optional<Integer> getTotalThreadCount() {
+        Threads ann = getFinal(Threads.class);
+        if (ann != null) {
+            return Optional.of(ann.value());
+        }
+        return Optional.none();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void addParam(String name, String[] value) {
+        params.put(name, value);
+    }
+
+    public void addStrictFP(boolean sfp) {
+        strictFP |= sfp;
+    }
+
+    public boolean isStrictFP() {
+        return strictFP;
+    }
+
+    public void addModes(Mode eMode) {
+        modes.add(eMode);
+    }
+
+    public void addModes(Mode[] eModes) {
+        Collections.addAll(modes, eModes);
+    }
+
+    public Set<Mode> getModes() {
+        return modes;
+    }
+
+    public int[] getThreads() {
+        int[] threads = new int[methods.size()];
+        int c = 0;
+        for (MethodInvocation mi : methods) {
+            threads[c++] = mi.threads;
+        }
+        return threads;
+    }
+
+    public long getOperationsPerInvocation() {
+        OperationsPerInvocation ann = getFinal(OperationsPerInvocation.class);
+        return (ann != null) ? ann.value() : 1;
+    }
+
+    public TimeUnit getOutputTimeUnit() {
+        OutputTimeUnit ann = getFinal(OutputTimeUnit.class);
+        return (ann != null) ? ann.value() : TimeUnit.MILLISECONDS;
+    }
+
+    public Optional<Integer> getWarmupIterations() {
+        Warmup ann = getFinal(Warmup.class);
+        if (ann != null && ann.iterations() != Warmup.BLANK_ITERATIONS) {
+            return Optional.of(ann.iterations());
+        }
+        return Optional.none();
+    }
+
+    public Optional<TimeValue> getWarmupTime() {
+        Warmup ann = getFinal(Warmup.class);
+        if (ann != null && ann.time() != Warmup.BLANK_TIME) {
+            return Optional.of(new TimeValue(ann.time(), ann.timeUnit()));
+        }
+        return Optional.none();
+    }
+
+    public Optional<Integer> getWarmupBatchSize() {
+        Warmup ann = getFinal(Warmup.class);
+        if (ann != null && ann.batchSize() != Warmup.BLANK_BATCHSIZE) {
+            return Optional.of(ann.batchSize());
+        }
+        return Optional.none();
+    }
+
+    public Optional<Integer> getMeasurementIterations() {
+        Measurement ann = getFinal(Measurement.class);
+        if (ann != null && ann.iterations() != Measurement.BLANK_ITERATIONS) {
+            return Optional.of(ann.iterations());
+        }
+        return Optional.none();
+    }
+
+    public Optional<TimeValue> getMeasurementTime() {
+        Measurement ann = getFinal(Measurement.class);
+        if (ann != null && ann.time() != Measurement.BLANK_TIME) {
+            return Optional.of(new TimeValue(ann.time(), ann.timeUnit()));
+        }
+        return Optional.none();
+    }
+
+    public Optional<Integer> getMeasurementBatchSize() {
+        Measurement ann = getFinal(Measurement.class);
+        if (ann != null && ann.batchSize() != Measurement.BLANK_BATCHSIZE) {
+            return Optional.of(ann.batchSize());
+        }
+        return Optional.none();
+    }
+
+    public Optional<Integer> getForks() {
+        Fork ann = getFinal(Fork.class);
+        if (ann != null && ann.value() != Fork.BLANK_FORKS) {
+            return Optional.of(ann.value());
+        }
+        return Optional.none();
+    }
+
+    public Optional<Integer> getWarmupForks() {
+        Fork ann = getFinal(Fork.class);
+        if (ann != null && ann.warmups() != Fork.BLANK_FORKS) {
+            return Optional.of(ann.warmups());
+        }
+        return Optional.none();
+    }
+
+    public Optional<Collection<String>> getJVMArgs() {
+        Fork ann = getFinal(Fork.class);
+        if (ann != null && !(ann.jvmArgs().length == 1 && ann.jvmArgs()[0].equals(Fork.BLANK_ARGS))) {
+            return Optional.<Collection<String>>of(Arrays.asList(ann.jvmArgs()));
+        }
+        return Optional.none();
+    }
+
+    public Optional<Collection<String>> getJVMArgsAppend() {
+        Fork ann = getFinal(Fork.class);
+        if (ann != null && !(ann.jvmArgsAppend().length == 1 && ann.jvmArgsAppend()[0].equals(Fork.BLANK_ARGS))) {
+            return Optional.<Collection<String>>of(Arrays.asList(ann.jvmArgsAppend()));
+        }
+        return Optional.none();
+    }
+
+    public Optional<Collection<String>> getJVMArgsPrepend() {
+        Fork ann = getFinal(Fork.class);
+        if (ann != null && !(ann.jvmArgsPrepend().length == 1 && ann.jvmArgsPrepend()[0].equals(Fork.BLANK_ARGS))) {
+            return Optional.<Collection<String>>of(Arrays.asList(ann.jvmArgsPrepend()));
+        }
+        return Optional.none();
+    }
+
+    private <T extends Annotation> T getFinal(Class<T> klass) {
+        T finalAnn = null;
+        for (MethodInvocation mi : methods) {
+            T ann = mi.method.getAnnotationRecursive(klass);
+            if (ann != null && finalAnn != null) {
+                if (!finalAnn.equals(ann)) {
+                    throw new GenerationException("Colliding annotations: " + ann + " vs. " + finalAnn, mi.method);
+                }
+            }
+            finalAnn = ann;
+        }
+        return finalAnn;
+    }
+
+    public Optional<Map<String, String[]>> getParams() {
+        Map<String, String[]> map = new TreeMap<String, String[]>();
+
+        for (String key : params.keySet()) {
+            String[] values = params.get(key);
+            if (values.length == 1 && values[0].equalsIgnoreCase(Param.BLANK_ARGS)) {
+                map.put(key, new String[0]);
+            } else {
+                map.put(key, values);
+            }
+        }
+
+        if (params.isEmpty()) {
+            return Optional.none();
+        } else {
+            return Optional.of(map);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+
+public interface MethodInfo extends Comparable<MethodInfo>, MetadataInfo {
+
+    ClassInfo getOwner();
+
+    String getName();
+    String getQualifiedName();
+    String getReturnType();
+
+    Collection<ParameterInfo> getParameters();
+
+    <T extends Annotation> T getAnnotation(Class<T> annClass);
+    <T extends Annotation> T getAnnotationRecursive(Class<T> annClass);
+
+    boolean isPublic();
+    boolean isAbstract();
+    boolean isSynchronized();
+    boolean isStrictFP();
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodInvocation.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+public class MethodInvocation implements Comparable<MethodInvocation> {
+    public final MethodInfo method;
+    public final int threads;
+
+    public MethodInvocation(MethodInfo method, int threads) {
+        this.method = method;
+        this.threads = threads;
+    }
+
+    @Override
+    public int compareTo(MethodInvocation o) {
+        return method.compareTo(o.method);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/ParameterInfo.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+public interface ParameterInfo extends MetadataInfo {
+    ClassInfo getType();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/StateObject.java	Wed Feb 26 17:18:42 2014 +0400
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.source;
+
+import org.openjdk.jmh.annotations.Scope;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class StateObject {
+
+    public static final Comparator<StateObject> ID_COMPARATOR = new Comparator<StateObject>() {
+        @Override
+        public int compare(StateObject o1, StateObject o2) {
+            return o1.fieldIdentifier.compareTo(o2.fieldIdentifier);
+        }
+    };
+
+    public final String userType;
+    public final String type;
+    public final Scope scope;
+    public final String localIdentifier;
+    public final String fieldIdentifier;
+    public final Map<String, String> params;
+
+    public StateObject(String userType, String jmhType, Scope scope, String fieldIdentifier, String localIdentifier) {
+        this.userType = userType;
+        this.type = jmhType;
+        this.scope = scope;
+        this.localIdentifier = localIdentifier;
+        this.fieldIdentifier = fieldIdentifier;
+        this.params = new TreeMap<String, String>();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        StateObject that = (StateObject) o;
+
+        if (fieldIdentifier != null ? !fieldIdentifier.equals(that.fieldIdentifier) : that.fieldIdentifier != null)
+            return false;
+        if (scope != that.scope) return false;
+        if (type != null ? !type.equals(that.type) : that.type != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = type != null ? type.hashCode() : 0;
+        result = 31 * result + (scope != null ? scope.hashCode() : 0);
+        result = 31 * result + (fieldIdentifier != null ? fieldIdentifier.hashCode() : 0);
+        return result;
+    }
+
+    public String toTypeDef() {
+        return type + " " + localIdentifier;
+    }
+
+    public String toLocal() {
+        return localIdentifier;
+    }
+
+    public String getParamAccessor(String name) {
+        return params.get(name);
+    }
+
+    public void addParam(FieldInfo fieldInfo) {
+        String type = fieldInfo.getType();
+        String name = fieldInfo.getName();
+        if (type.equalsIgnoreCase("java.lang.String")) {
+            params.put(name, "control.getParam(\"" + name + "\")");
+            return;
+        }
+        if (type.equalsIgnoreCase("boolean") || type.equalsIgnoreCase("java.lang.Boolean")) {
+            params.put(name, "Boolean.valueOf(control.getParam(\"" + name + "\"))");
+            return;
+        }
+        if (type.equalsIgnoreCase("byte") || type.equalsIgnoreCase("java.lang.Byte")) {
+            params.put(name, "Byte.valueOf(control.getParam(\"" + name + "\"))");
+            return;
+        }
+        if (type.equalsIgnoreCase("char") || type.equalsIgnoreCase("java.lang.Character")) {
+            params.put(name, "(control.getParam(\"" + name + "\")).charAt(0)");
+            return;
+        }
+        if (type.equalsIgnoreCase("short") || type.equalsIgnoreCase("java.lang.Short")) {
+            params.put(name, "Short.valueOf(control.getParam(\"" + name + "\"))");
+            return;
+        }
+        if (type.equalsIgnoreCase("int") || type.equalsIgnoreCase("java.lang.Integer")) {
+            params.put(name, "Integer.valueOf(control.getParam(\"" + name + "\"))");
+            return;
+        }
+        if (type.equalsIgnoreCase("float") || type.equalsIgnoreCase("java.lang.Float")) {
+            params.put(name, "Float.valueOf(control.getParam(\"" + name + "\"))");
+            return;
+        }
+        if (type.equalsIgnoreCase("long") || type.equalsIgnoreCase("java.lang.Long")) {
+            params.put(name, "Long.valueOf(control.getParam(\"" + name + "\"))");
+            return;
+        }
+        if (type.equalsIgnoreCase("double") || type.equalsIgnoreCase("java.lang.Double")) {
+            params.put(name, "Double.valueOf(control.getParam(\"" + name + "\"))");
+            return;
+        }
+        throw new IllegalStateException("Unknown type: " + type);
+    }
+
+    public Collection<String> getParamsLabels() {
+        return params.keySet();
+    }
+}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/BenchmarkGenerator.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,981 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.CompilerControl;
-import org.openjdk.jmh.annotations.Fork;
-import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
-import org.openjdk.jmh.annotations.Group;
-import org.openjdk.jmh.annotations.GroupThreads;
-import org.openjdk.jmh.annotations.Measurement;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OperationsPerInvocation;
-import org.openjdk.jmh.annotations.Param;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.Threads;
-import org.openjdk.jmh.annotations.Warmup;
-import org.openjdk.jmh.logic.BlackHole;
-import org.openjdk.jmh.logic.InfraControl;
-import org.openjdk.jmh.logic.ThreadControl;
-import org.openjdk.jmh.logic.results.AverageTimeResult;
-import org.openjdk.jmh.logic.results.RawResults;
-import org.openjdk.jmh.logic.results.Result;
-import org.openjdk.jmh.logic.results.ResultRole;
-import org.openjdk.jmh.logic.results.SampleTimeResult;
-import org.openjdk.jmh.logic.results.SingleShotResult;
-import org.openjdk.jmh.logic.results.ThroughputResult;
-import org.openjdk.jmh.runner.BenchmarkRecord;
-import org.openjdk.jmh.runner.MicroBenchmarkList;
-import org.openjdk.jmh.util.internal.HashMultimap;
-import org.openjdk.jmh.util.internal.Multimap;
-import org.openjdk.jmh.util.internal.SampleBuffer;
-
-import javax.annotation.Generated;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.lang.annotation.IncompleteAnnotationException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-
-/**
- * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
- */
-public class BenchmarkGenerator {
-
-    private final Set<BenchmarkInfo> benchmarkInfos;
-    private final Collection<Plugin> plugins;
-    private final CompilerControlPlugin compilerControl;
-    private final Set<String> processedBenchmarks;
-
-    public BenchmarkGenerator() {
-        benchmarkInfos = new HashSet<BenchmarkInfo>();
-        processedBenchmarks = new HashSet<String>();
-        compilerControl = new CompilerControlPlugin();
-
-        plugins = new ArrayList<Plugin>();
-        plugins.add(new HelperMethodValidationPlugin());
-        plugins.add(new GroupValidationPlugin());
-        plugins.add(new ParamValidationPlugin());
-        plugins.add(compilerControl);
-    }
-
-    public void generate(GeneratorSource source) {
-        try {
-            for (Plugin sub : plugins) {
-                sub.process(source);
-            }
-
-            // Build a Set of classes with a list of annotated methods
-            Multimap<ClassInfo, MethodInfo> clazzes = buildAnnotatedSet(source);
-
-            // Generate code for all found Classes and Methods
-            for (ClassInfo clazz : clazzes.keys()) {
-                if (!processedBenchmarks.add(clazz.getQualifiedName())) continue;
-                try {
-                    validateBenchmark(clazz, clazzes.get(clazz));
-                    BenchmarkInfo info = makeBenchmarkInfo(clazz, clazzes.get(clazz));
-                    generateClass(source, clazz, info);
-                    benchmarkInfos.add(info);
-                } catch (GenerationException ge) {
-                    source.printError(ge.getMessage(), ge.getElement());
-                }
-            }
-        } catch (Throwable t) {
-            source.printError("Annotation processor had thrown the exception: " + t);
-            t.printStackTrace(System.err);
-        }
-    }
-
-    public void complete(GeneratorSource source) {
-        for (Plugin sub : plugins) {
-            sub.finish(source);
-        }
-
-        // Processing completed, final round. Print all added methods to file
-        try {
-            PrintWriter writer = new PrintWriter(source.newResource(MicroBenchmarkList.MICROBENCHMARK_LIST.substring(1)));
-            for (BenchmarkInfo info : benchmarkInfos) {
-                for (String method : info.methodGroups.keySet()) {
-                    MethodGroup group = info.methodGroups.get(method);
-                    for (Mode m : group.getModes()) {
-                        BenchmarkRecord br = new BenchmarkRecord(
-                                info.userName + "." + method,
-                                info.generatedName + "." + method,
-                                m,
-                                group.getThreads(),
-                                group.getTotalThreadCount(),
-                                group.getWarmupIterations(),
-                                group.getWarmupTime(),
-                                group.getWarmupBatchSize(),
-                                group.getMeasurementIterations(),
-                                group.getMeasurementTime(),
-                                group.getMeasurementBatchSize(),
-                                group.getForks(),
-                                group.getWarmupForks(),
-                                group.getJVMArgs(),
-                                group.getJVMArgsPrepend(),
-                                group.getJVMArgsAppend(),
-                                group.getParams()
-                        );
-                        writer.println(br.toLine());
-                    }
-                }
-            }
-
-            writer.close();
-        } catch (IOException ex) {
-            source.printError("Error writing MicroBenchmark list " + ex);
-        }
-    }
-
-    /**
-     * Build a set of Classes which has annotated methods in them
-     *
-     * @return for all methods annotated with $annotation, returns Map<holder-class, Set<method>>
-     */
-    private Multimap<ClassInfo, MethodInfo> buildAnnotatedSet(GeneratorSource source) {
-        // Transitively close the hierarchy:
-        //   If superclass has a @GMB method, then all subclasses also have it.
-        //   We skip the generated classes, which we had probably generated during the previous rounds
-        //   of processing. Abstract classes are of no interest for us either.
-
-        Multimap<ClassInfo, MethodInfo> result = new HashMultimap<ClassInfo, MethodInfo>();
-        for (ClassInfo currentClass : source.getClasses()) {
-            if (currentClass.getQualifiedName().contains("generated")) continue;
-            if (currentClass.isAbstract()) continue;
-
-            for (MethodInfo mi : currentClass.getDeclaredMethods()) {
-                GenerateMicroBenchmark ann = mi.getAnnotation(GenerateMicroBenchmark.class);
-                if (ann != null) {
-                    result.put(currentClass, mi);
-                }
-            }
-
-            for (ClassInfo upperClass : currentClass.getSuperclasses()) {
-                if (upperClass.getQualifiedName().contains("generated")) continue;
-                for (MethodInfo mi : upperClass.getDeclaredMethods()) {
-                    GenerateMicroBenchmark ann = mi.getAnnotation(GenerateMicroBenchmark.class);
-                    if (ann != null) {
-                        result.put(currentClass, mi);
-                    }
-                }
-            }
-        }
-        return result;
-    }
-
-
-    /**
-     * Do basic benchmark validation.
-     */
-    private void validateBenchmark(ClassInfo clazz, Collection<MethodInfo> methods) {
-        if (clazz.getQualifiedName().isEmpty()) {
-            throw new GenerationException("Microbenchmark should have package other than default.", clazz);
-        }
-
-        Collection<ClassInfo> states = new ArrayList<ClassInfo>();
-
-        // validate all arguments are @State-s
-        for (MethodInfo e : methods) {
-            for (ParameterInfo var : e.getParameters()) {
-                states.add(var.getType());
-            }
-        }
-
-        // validate if enclosing class is implicit @State
-        if (clazz.getAnnotation(State.class) != null) {
-            states.add(clazz);
-        }
-
-        // validate @State classes
-        for (ClassInfo state : states) {
-            // Because of https://bugs.openjdk.java.net/browse/JDK-8031122,
-            // we need to preemptively check the annotation value, and
-            // the API can only allow that by catching the exception, argh.
-            try {
-                state.getAnnotation(State.class).value();
-            } catch (IncompleteAnnotationException iae) {
-                throw new GenerationException("The " + State.class.getSimpleName() +
-                        " annotation should have the explicit " + Scope.class.getSimpleName() + " argument",
-                        state);
-            }
-
-            if (!state.isPublic()) {
-                throw new GenerationException("The " + State.class.getSimpleName() +
-                        " annotation only supports public classes.", state);
-            }
-
-            if (state.isNested() && !state.isStatic()) {
-                throw new GenerationException("The " + State.class.getSimpleName() +
-                        " annotation does not support inner classes, make sure the class is nested (static).",
-                        state);
-            }
-
-            boolean hasDefaultConstructor = false;
-            for (MethodInfo constructor : state.getConstructors()) {
-                hasDefaultConstructor |= (constructor.getParameters().isEmpty() && constructor.isPublic());
-            }
-
-            if (!hasDefaultConstructor) {
-                throw new GenerationException("The " + State.class.getSimpleName() +
-                        " annotation can only be applied to the classes having the default public constructor.",
-                        state);
-            }
-        }
-
-        // validate against rogue fields
-        if (clazz.getAnnotation(State.class) == null || clazz.isAbstract()) {
-            for (FieldInfo fi : clazz.getFields()) {
-                // allow static fields
-                if (fi.isStatic()) continue;
-                throw new GenerationException(
-                        "Field \"" + fi.getName() + "\" is declared within " +
-                                "the class not having @" + State.class.getSimpleName() + " annotation. " +
-                                "This can result in unspecified behavior, and prohibited.", fi);
-            }
-        }
-
-        // check modifiers
-        for (MethodInfo m : methods) {
-            if (!m.isPublic()) {
-                throw new GenerationException("@" + GenerateMicroBenchmark.class.getSimpleName() +
-                        " method should be public.", m);
-            }
-
-            if (m.isAbstract()) {
-                throw new GenerationException("@" + GenerateMicroBenchmark.class.getSimpleName()
-                        + " method can not be abstract.", m);
-            }
-            if (m.isSynchronized()) {
-                if (clazz.getAnnotation(State.class) == null) {
-                    throw new GenerationException("@" + GenerateMicroBenchmark.class.getSimpleName()
-                            + " method can only be synchronized if the enclosing class is annotated with "
-                            + "@" + State.class.getSimpleName() + ".", m);
-                    }
-            }
-        }
-
-        // check annotations
-        for (MethodInfo m : methods) {
-            OperationsPerInvocation opi = m.getAnnotationRecursive(OperationsPerInvocation.class);
-            if (opi != null && opi.value() < 1) {
-                throw new GenerationException("The " + OperationsPerInvocation.class.getSimpleName() +
-                        " needs to be greater than 0.", m);
-            }
-        }
-    }
-
-    /**
-     * validate benchmark info
-     * @param info benchmark info to validate
-     */
-    private void validateBenchmarkInfo(BenchmarkInfo info) {
-        // check the @Group preconditions,
-        // ban some of the surprising configurations
-        //
-        for (MethodGroup group : info.methodGroups.values()) {
-            if (group.methods().size() == 1) {
-                MethodInfo meth = group.methods().iterator().next();
-                if (meth.getAnnotation(Group.class) == null) {
-                    for (ParameterInfo param : meth.getParameters()) {
-                        State stateAnn = param.getType().getAnnotation(State.class);
-                        if (stateAnn != null && stateAnn.value() == Scope.Group) {
-                            throw new GenerationException(
-                                    "Only @" + Group.class.getSimpleName() + " methods can reference @" + State.class.getSimpleName()
-                                            + "(" + Scope.class.getSimpleName() + "." + Scope.Group + ") states.",
-                                    meth);
-                        }
-                    }
-
-                    State stateAnn = meth.getOwner().getAnnotation(State.class);
-                    if (stateAnn != null && stateAnn.value() == Scope.Group) {
-                        throw new GenerationException(
-                                "Only @" + Group.class.getSimpleName() + " methods can implicitly reference @" + State.class.getSimpleName()
-                                        + "(" + Scope.class.getSimpleName() + "." + Scope.Group + ") states.",
-                                meth);
-                    }
-                }
-            } else {
-                for (MethodInfo m : group.methods()) {
-                    if (m.getAnnotation(Group.class) == null) {
-                        throw new GenerationException(
-                                "Internal error: multiple methods per @" + Group.class.getSimpleName()
-                                        + ", but not all methods have @" + Group.class.getSimpleName(),
-                                m);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Generate BenchmarkInfo for given class.
-     * We will figure out method groups at this point.
-     *
-     * @param clazz holder class
-     * @param methods annotated methods
-     * @return BenchmarkInfo
-     */
-    private BenchmarkInfo makeBenchmarkInfo(ClassInfo clazz, Collection<MethodInfo> methods) {
-        Map<String, MethodGroup> result = new TreeMap<String, MethodGroup>();
-
-        for (MethodInfo method : methods) {
-            Group groupAnn = method.getAnnotation(Group.class);
-            String groupName = (groupAnn != null) ? groupAnn.value() : method.getName();
-
-            if (!checkJavaIdentifier(groupName)) {
-                throw new GenerationException("Group name should be the legal Java identifier.", method);
-            }
-
-            MethodGroup group = result.get(groupName);
-            if (group == null) {
-                group = new MethodGroup(groupName);
-                result.put(groupName, group);
-            }
-
-            BenchmarkMode mbAn = method.getAnnotationRecursive(BenchmarkMode.class);
-            if (mbAn != null) {
-                group.addModes(mbAn.value());
-            }
-
-            group.addStrictFP(clazz.isStrictFP());
-            group.addStrictFP(method.isStrictFP());
-            group.addMethod(method, (method.getAnnotation(GroupThreads.class) != null) ? method.getAnnotation(GroupThreads.class).value() : 1);
-
-            // Discovering @Params, part 1:
-            //   For each parameter, walk the type hierarchy up to discover inherited @Param fields in @State objects.
-            for (ParameterInfo pi : method.getParameters()) {
-                for (FieldInfo fi : pi.getType().getFields()) {
-                    if (fi.getAnnotation(Param.class) != null) {
-                        group.addParam(fi.getName(), fi.getAnnotation(Param.class).value());
-                    }
-                }
-            }
-
-            // Discovering @Params, part 2:
-            //  Walk the type hierarchy up to discover inherited @Param fields for class.
-            for (FieldInfo fi : clazz.getFields()) {
-                if (fi.getAnnotation(Param.class) != null) {
-                    group.addParam(fi.getName(), fi.getAnnotation(Param.class).value());
-                }
-            }
-        }
-
-        // enforce the default value
-        for (MethodGroup group : result.values()) {
-            if (group.getModes().isEmpty()) {
-                group.addModes(Mode.Throughput);
-            }
-        }
-
-        String sourcePackage = clazz.getPackageName();
-        String generatedPackageName = sourcePackage + ".generated";
-        String generatedClassName = clazz.getNestedName();
-
-        BenchmarkInfo info = new BenchmarkInfo(clazz.getQualifiedName(), generatedPackageName, generatedClassName, result);
-        validateBenchmarkInfo(info);
-        return info;
-    }
-
-    public static boolean checkJavaIdentifier(String id) {
-        for (int i = 0; i < id.length(); i++) {
-            char c = id.charAt(i);
-            if (!Character.isJavaIdentifierPart(c)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Create and generate Java code for a class and it's methods
-     */
-    private void generateClass(GeneratorSource source, ClassInfo classInfo, BenchmarkInfo info) {
-        try {
-            // Create file and open an outputstream
-            PrintWriter writer = new PrintWriter(source.newFile(info.generatedName), false);
-
-            // Write package and imports
-            writer.println("package " + info.generatedPackageName + ';');
-            writer.println();
-
-            generateImport(writer);
-
-            // Write class header
-            writer.println("@" + CompilerControl.class.getSimpleName() +
-                    "(" + CompilerControl.class.getSimpleName() + "." + CompilerControl.Mode.class.getSimpleName() +
-                    "." + CompilerControl.Mode.DONT_INLINE + ")");
-            writer.println("@Generated(\"" + BenchmarkGenerator.class.getCanonicalName() + "\")");
-            writer.println("public final class " + info.generatedClassName + " {");
-            writer.println();
-            generatePadding(writer);
-
-            StateObjectHandler states = new StateObjectHandler();
-
-            // benchmark instance is implicit
-            states.bindImplicit(classInfo, "bench", Scope.Thread);
-
-            // default blackhole is implicit
-            states.bindImplicit(source.resolveClass(BlackHole.class.getCanonicalName()), "blackhole", Scope.Thread);
-
-            // Write all methods
-            for (String groupName : info.methodGroups.keySet()) {
-                for (MethodInfo method : info.methodGroups.get(groupName).methods()) {
-                    for (ParameterInfo p : method.getParameters()) {
-                        states.bindArg(method, p);
-                    }
-                }
-
-                for (Mode benchmarkKind : Mode.values()) {
-                    if (benchmarkKind == Mode.All) continue;
-                    generateMethod(benchmarkKind, writer, info.methodGroups.get(groupName), states);
-                }
-                states.clearArgs();
-            }
-
-            // Write out state initializers
-            for (String s : states.getStateInitializers()) {
-                writer.println(ident(1) + s);
-            }
-            writer.println();
-
-            // Write out the required fields
-            for (String s : states.getFields()) {
-                writer.println(ident(1) + s);
-            }
-            writer.println();
-
-            // Write out the required objects
-            for (String s : states.getStateOverrides()) {
-                writer.println(ident(1) + s);
-            }
-            writer.println();
-
-            // Finish class
-            writer.println("}");
-            writer.println();
-
-            writer.close();
-        } catch (IOException ex) {
-            throw new GenerationException("IOException", classInfo);
-        }
-    }
-
-    private void generatePadding(PrintWriter writer) {
-        for (int p = 0; p < 16; p++) {
-            StringBuilder sb = new StringBuilder();
-            sb.append(ident(1));
-            sb.append("boolean jmh_pad_").append(p);
-            for (int q = 1; q < 16; q++) {
-                sb.append(", jmh_pad_").append(p).append("_").append(q);
-            }
-            sb.append(";");
-            writer.println(sb.toString());
-        }
-    }
-
-    private void generateImport(PrintWriter writer) {
-        Class<?>[] imports = new Class<?>[] {
-                List.class, AtomicInteger.class, AtomicIntegerFieldUpdater.class,
-                Collection.class, Collections.class, ArrayList.class, Arrays.class,
-                TimeUnit.class, Generated.class, CompilerControl.class,
-                InfraControl.class, ThreadControl.class, BlackHole.class,
-                Result.class, ThroughputResult.class, AverageTimeResult.class,
-                SampleTimeResult.class, SingleShotResult.class, SampleBuffer.class,
-                Mode.class, Fork.class, Measurement.class, Threads.class, Warmup.class,
-                BenchmarkMode.class, RawResults.class, ResultRole.class
-        };
-
-        for (Class<?> c : imports) {
-            writer.println("import " + c.getName() + ';');
-        }
-        writer.println();
-    }
-
-    /**
-     * Generate the method for a specific benchmark method
-     */
-    private void generateMethod(Mode benchmarkKind, PrintWriter writer, MethodGroup methodGroup, StateObjectHandler states) {
-        writer.println();
-        switch (benchmarkKind) {
-            case Throughput:
-                generateThroughput(writer, benchmarkKind, methodGroup, states);
-                break;
-            case AverageTime:
-                generateAverageTime(writer, benchmarkKind, methodGroup, states);
-                break;
-            case SampleTime:
-                generateSampleTime(writer, benchmarkKind, methodGroup, states);
-                break;
-            case SingleShotTime:
-                generateSingleShotTime(writer, benchmarkKind, methodGroup, states);
-                break;
-            default:
-                throw new AssertionError("Shouldn't be here");
-        }
-    }
-
-    private void generateThroughput(PrintWriter writer, Mode benchmarkKind, MethodGroup methodGroup, StateObjectHandler states) {
-        writer.println(ident(1) + "public Collection<? extends Result> " + methodGroup.getName() + "_" + benchmarkKind +
-                "(InfraControl control, ThreadControl threadControl) throws Throwable {");
-        writer.println();
-
-        methodProlog(writer, methodGroup);
-
-        boolean isSingleMethod = (methodGroup.methods().size() == 1);
-        int subGroup = -1;
-        for (MethodInfo method : methodGroup.methods()) {
-            compilerControl.defaultForceInline(method);
-
-            subGroup++;
-
-            writer.println(ident(2) + "if (threadControl.subgroup == " + subGroup + ") {");
-
-            iterationProlog(writer, 3, method, states);
-
-            // synchronize iterations prolog: announce ready
-            writer.println(ident(3) + "control.announceWarmupReady();");
-
-            // synchronize iterations prolog: catchup loop
-            writer.println(ident(3) + "while (control.warmupShouldWait) {");
-
-            invocationProlog(writer, 4, method, states, false);
-            writer.println(ident(4) + emitCall(method, states) + ';');
-            invocationEpilog(writer, 4, method, states, false);
-
-            writer.println(ident(3) + "}");
-            writer.println();
-
-            // control objects get a special treatment
-            for (StateObject so : states.getControls()) {
-                writer.println(ident(3) + so.localIdentifier + ".startMeasurement = true;");
-                writer.println(ident(3) + so.localIdentifier + ".iterationTime = control.getDuration();");
-            }
-
-            // measurement loop call
-            writer.println(ident(3) + "RawResults res = new RawResults(" + methodGroup.getOperationsPerInvocation() + "L);");
-            writer.println(ident(3) + method.getName() + "_" + benchmarkKind + "_measurementLoop" +
-                    "(control, res, " + states.getImplicit("bench").toLocal() + ", " + states.getImplicit("blackhole").toLocal() + prefix(states.getArgList(method)) + ");");
-
-            // control objects get a special treatment
-            for (StateObject so : states.getControls()) {
-                writer.println(ident(3) + so.localIdentifier + ".stopMeasurement = true;");
-            }
-
-            // synchronize iterations epilog: announce ready
-            writer.println(ident(3) + "control.announceWarmdownReady();");
-
-            // synchronize iterations epilog: catchup loop
-            writer.println(ident(3) + "while (control.warmdownShouldWait) {");
-
-            invocationProlog(writer, 4, method, states, false);
-            writer.println(ident(4) + emitCall(method, states) + ';');
-            invocationEpilog(writer, 4, method, states, false);
-
-            writer.println(ident(3) + "}");
-
-            // iteration prolog
-            iterationEpilog(writer, 3, method, states);
-
-            writer.println(ident(3) + "Collection<Result> results = new ArrayList<Result>();");
-            writer.println(ident(3) + "TimeUnit tu = (control.timeUnit != null) ? control.timeUnit : TimeUnit." + methodGroup.getOutputTimeUnit() + ";");
-            writer.println(ident(3) + "results.add(new ThroughputResult(ResultRole.PRIMARY, \"" + method.getName() + "\", res.getOperations(), res.getTime(), tu));");
-            if (!isSingleMethod) {
-                writer.println(ident(3) + "results.add(new ThroughputResult(ResultRole.SECONDARY, \"" + method.getName() + "\", res.getOperations(), res.getTime(), tu));");
-            }
-            for (String ops : states.getAuxResultNames(method)) {
-                writer.println(ident(3) + "results.add(new ThroughputResult(ResultRole.SECONDARY, \"" + ops + "\", " + states.getAuxResultAccessor(method, ops) + ", res.getTime(), tu));");
-            }
-            writer.println(ident(3) + "return results;");
-            writer.println(ident(2) + "} else");
-        }
-        writer.println(ident(3) + "throw new IllegalStateException(\"Harness failed to distribute threads among groups properly\");");
-        writer.println();
-
-        writer.println(ident(1) + "}");
-
-        // measurement loop bodies
-        for (MethodInfo method : methodGroup.methods()) {
-            String methodName = method.getName() + "_" + benchmarkKind + "_measurementLoop";
-            writer.println(ident(1) + "public " + (methodGroup.isStrictFP() ? "strictfp" : "") + " void " + methodName + "(InfraControl control, RawResults result, " + states.getImplicit("bench").toTypeDef() + ", " + states.getImplicit("blackhole").toTypeDef() + prefix(states.getTypeArgList(method)) + ") throws Throwable {");
-            writer.println(ident(2) + "long operations = 0;");
-            writer.println(ident(2) + "long realTime = 0;");
-            writer.println(ident(2) + "result.startTime = System.nanoTime();");
-            writer.println(ident(2) + "do {");
-
-            invocationProlog(writer, 3, method, states, true);
-            writer.println(ident(3) + emitCall(method, states) + ';');
-            invocationEpilog(writer, 3, method, states, true);
-
-            writer.println(ident(3) + "operations++;");
-            writer.println(ident(2) + "} while(!control.isDone);");
-            writer.println(ident(2) + "result.stopTime = System.nanoTime();");
-            writer.println(ident(2) + "result.realTime = realTime;");
-            writer.println(ident(2) + "result.operations = operations;");
-            writer.println(ident(1) + "}");
-            writer.println();
-        }
-    }
-
-    private void generateAverageTime(PrintWriter writer, Mode benchmarkKind, MethodGroup methodGroup, StateObjectHandler states) {
-        writer.println(ident(1) + "public Collection<? extends Result> " + methodGroup.getName() + "_" + benchmarkKind +
-                "(InfraControl control, ThreadControl threadControl) throws Throwable {");
-
-        methodProlog(writer, methodGroup);
-
-        boolean isSingleMethod = (methodGroup.methods().size() == 1);
-        int subGroup = -1;
-        for (MethodInfo method : methodGroup.methods()) {
-            compilerControl.defaultForceInline(method);
-
-            subGroup++;
-
-            writer.println(ident(2) + "if (threadControl.subgroup == " + subGroup + ") {");
-
-            iterationProlog(writer, 3, method, states);
-
-            // synchronize iterations prolog: announce ready
-            writer.println(ident(3) + "control.announceWarmupReady();");
-
-            // synchronize iterations prolog: catchup loop
-            writer.println(ident(3) + "while (control.warmupShouldWait) {");
-
-            invocationProlog(writer, 4, method, states, false);
-            writer.println(ident(4) + emitCall(method, states) + ';');
-            invocationEpilog(writer, 4, method, states, false);
-
-            writer.println(ident(3) + "}");
-            writer.println();
-
-            // control objects get a special treatment
-            for (StateObject so : states.getControls()) {
-                writer.println(ident(3) + so.localIdentifier + ".startMeasurement = true;");
-                writer.println(ident(3) + so.localIdentifier + ".iterationTime = control.getDuration();");
-            }
-
-            // measurement loop call
-            writer.println(ident(3) + "RawResults res = new RawResults(" + methodGroup.getOperationsPerInvocation() + "L);");
-            writer.println(ident(3) + method.getName() + "_" + benchmarkKind + "_measurementLoop(control, res, " + states.getImplicit("bench").toLocal() + ", " + states.getImplicit("blackhole").toLocal() + prefix(states.getArgList(method)) + ");");
-
-            // control objects get a special treatment
-            for (StateObject so : states.getControls()) {
-                writer.println(ident(3) + so.localIdentifier + ".stopMeasurement = true;");
-            }
-
-            // synchronize iterations epilog: announce ready
-            writer.println(ident(3) + "control.announceWarmdownReady();");
-
-            // synchronize iterations epilog: catchup loop
-            writer.println(ident(3) + "while (control.warmdownShouldWait) {");
-
-            invocationProlog(writer, 4, method, states, false);
-            writer.println(ident(4) + emitCall(method, states) + ';');
-            invocationEpilog(writer, 4, method, states, false);
-
-            writer.println(ident(3) + "}");
-
-            iterationEpilog(writer, 3, method, states);
-
-            writer.println(ident(3) + "Collection<Result> results = new ArrayList<Result>();");
-            writer.println(ident(3) + "TimeUnit tu = (control.timeUnit != null) ? control.timeUnit : TimeUnit." + methodGroup.getOutputTimeUnit() + ";");
-            writer.println(ident(3) + "results.add(new AverageTimeResult(ResultRole.PRIMARY, \"" + method.getName() + "\", res.getOperations(), res.getTime(), tu));");
-            if (!isSingleMethod) {
-                writer.println(ident(3) + "results.add(new AverageTimeResult(ResultRole.SECONDARY, \"" + method.getName() + "\", res.getOperations(), res.getTime(), tu));");
-            }
-            for (String ops : states.getAuxResultNames(method)) {
-                writer.println(ident(3) + "results.add(new AverageTimeResult(ResultRole.SECONDARY, \"" + ops + "\", " + states.getAuxResultAccessor(method, ops) + ", res.getTime(), tu));");
-            }
-            writer.println(ident(3) + "return results;");
-            writer.println(ident(2) + "} else");
-        }
-        writer.println(ident(3) + "throw new IllegalStateException(\"Harness failed to distribute threads among groups properly\");");
-        writer.println();
-
-        writer.println(ident(1) + "}");
-
-        // measurement loop bodies
-        for (MethodInfo method : methodGroup.methods()) {
-            writer.println(ident(1) + "public " + (methodGroup.isStrictFP() ? "strictfp" : "") +  " void " + method.getName() + "_" + benchmarkKind + "_measurementLoop" +
-                    "(InfraControl control, RawResults result, " + states.getImplicit("bench").toTypeDef() + ", " + states.getImplicit("blackhole").toTypeDef() +
-                    prefix(states.getTypeArgList(method)) + ") throws Throwable {");
-            writer.println(ident(2) + "long operations = 0;");
-            writer.println(ident(2) + "long realTime = 0;");
-            writer.println(ident(2) + "result.startTime = System.nanoTime();");
-            writer.println(ident(2) + "do {");
-
-            invocationProlog(writer, 3, method, states, true);
-            writer.println(ident(3) + emitCall(method, states) + ';');
-            invocationEpilog(writer, 3, method, states, true);
-
-            writer.println(ident(3) + "operations++;");
-            writer.println(ident(2) + "} while(!control.isDone);");
-            writer.println(ident(2) + "result.stopTime = System.nanoTime();");
-            writer.println(ident(2) + "result.realTime = realTime;");
-            writer.println(ident(2) + "result.operations = operations;");
-            writer.println(ident(1) + "}");
-            writer.println();
-        }
-    }
-
-    private void methodProlog(PrintWriter writer, MethodGroup methodGroup) {
-        // do nothing
-    }
-
-    private String prefix(String argList) {
-        if (argList.trim().isEmpty()) {
-            return "";
-        } else {
-            return ", " + argList;
-        }
-    }
-
-    private void generateSampleTime(PrintWriter writer, Mode benchmarkKind, MethodGroup methodGroup, StateObjectHandler states) {
-        writer.println(ident(1) + "public Collection<? extends Result> " + methodGroup.getName() + "_" + benchmarkKind +
-                "(InfraControl control, ThreadControl threadControl) throws Throwable {");
-        writer.println();
-
-        methodProlog(writer, methodGroup);
-
-        boolean isSingleMethod = (methodGroup.methods().size() == 1);
-        int subGroup = -1;
-        for (MethodInfo method : methodGroup.methods()) {
-            compilerControl.defaultForceInline(method);
-
-            subGroup++;
-
-            writer.println(ident(2) + "if (threadControl.subgroup == " + subGroup + ") {");
-
-            iterationProlog(writer, 3, method, states);
-
-            // synchronize iterations prolog: announce ready
-            writer.println(ident(3) + "control.announceWarmupReady();");
-
-            // synchronize iterations prolog: catchup loop
-            writer.println(ident(3) + "while (control.warmupShouldWait) {");
-
-            invocationProlog(writer, 4, method, states, false);
-            writer.println(ident(4) + emitCall(method, states) + ';');
-            invocationEpilog(writer, 4, method, states, false);
-
-            writer.println(ident(3) + "}");
-            writer.println();
-
-            // control objects get a special treatment
-            for (StateObject so : states.getControls()) {
-                writer.println(ident(3) + so.localIdentifier + ".startMeasurement = true;");
-                writer.println(ident(3) + so.localIdentifier + ".iterationTime = control.getDuration();");
-            }
-
-            // measurement loop call
-            writer.println(ident(3) + "SampleBuffer buffer = new SampleBuffer();");
-            writer.println(ident(3) + method.getName() + "_" + benchmarkKind + "_measurementLoop(control, buffer, " + states.getImplicit("bench").toLocal() + ", " + states.getImplicit("blackhole").toLocal() + prefix(states.getArgList(method)) + ");");
-
-            // control objects get a special treatment
-            for (StateObject so : states.getControls()) {
-                writer.println(ident(3) + so.localIdentifier + ".stopMeasurement = true;");
-            }
-
-            // synchronize iterations epilog: announce ready
-            writer.println(ident(3) + "control.announceWarmdownReady();");
-
-            // synchronize iterations epilog: catchup loop
-            writer.println(ident(3) + "while (control.warmdownShouldWait) {");
-
-            invocationProlog(writer, 4, method, states, false);
-            writer.println(ident(4) + emitCall(method, states) + ';');
-            invocationEpilog(writer, 4, method, states, false);
-
-            writer.println(ident(3) + "}");
-            writer.println();
-
-            iterationEpilog(writer, 3, method, states);
-
-            writer.println(ident(3) + "Collection<Result> results = new ArrayList<Result>();");
-            writer.println(ident(3) + "TimeUnit tu = (control.timeUnit != null) ? control.timeUnit : TimeUnit." + methodGroup.getOutputTimeUnit() + ";");
-            writer.println(ident(3) + "results.add(new SampleTimeResult(ResultRole.PRIMARY, \"" + method.getName() + "\", buffer, tu));");
-            if (!isSingleMethod) {
-                writer.println(ident(3) + "results.add(new SampleTimeResult(ResultRole.SECONDARY, \"" + method.getName() + "\", buffer, tu));");
-            }
-            writer.println(ident(3) + "return results;");
-            writer.println(ident(2) + "} else");
-        }
-        writer.println(ident(3) + "throw new IllegalStateException(\"Harness failed to distribute threads among groups properly\");");
-
-        writer.println(ident(1) + "}");
-
-        // measurement loop bodies
-        for (MethodInfo method : methodGroup.methods()) {
-            writer.println(ident(1) + "public " + (methodGroup.isStrictFP() ? "strictfp" : "") + " void " + method.getName() + "_" + benchmarkKind + "_measurementLoop(InfraControl control, SampleBuffer buffer, " + states.getImplicit("bench").toTypeDef() + ", " + states.getImplicit("blackhole").toTypeDef() + prefix(states.getTypeArgList(method)) + ") throws Throwable {");
-            writer.println(ident(2) + "long realTime = 0;");
-            writer.println(ident(2) + "int rnd = (int)System.nanoTime();");
-            writer.println(ident(2) + "int rndMask = 0;");
-            writer.println(ident(2) + "long time = 0;");
-            writer.println(ident(2) + "int currentStride = 0;");
-            writer.println(ident(2) + "do {");
-
-            invocationProlog(writer, 3, method, states, true);
-
-            writer.println(ident(3) + "rnd = (rnd * 1664525 + 1013904223);");
-            writer.println(ident(3) + "boolean sample = (rnd & rndMask) == 0;");
-            writer.println(ident(3) + "if (sample) {");
-            writer.println(ident(4) + "time = System.nanoTime();");
-            writer.println(ident(3) + "}");
-            writer.println(ident(3) + "" + emitCall(method, states) + ';');
-            writer.println(ident(3) + "if (sample) {");
-            writer.println(ident(4) + "buffer.add(System.nanoTime() - time);");
-            writer.println(ident(4) + "if (currentStride++ > 1000000) {");
-            writer.println(ident(5) + "buffer.half();");
-            writer.println(ident(5) + "currentStride = 0;");
-            writer.println(ident(5) + "rndMask = (rndMask << 1) + 1;");
-            writer.println(ident(4) + "}");
-            writer.println(ident(3) + "}");
-
-            invocationEpilog(writer, 3, method, states, true);
-
-            writer.println(ident(2) + "} while(!control.isDone);");
-
-            writer.println(ident(1) + "}");
-            writer.println();
-        }
-    }
-
-    private void generateSingleShotTime(PrintWriter writer, Mode benchmarkKind, MethodGroup methodGroup, StateObjectHandler states) {
-        writer.println(ident(1) + "public Collection<? extends Result> " + methodGroup.getName() + "_" + benchmarkKind + "(InfraControl control, ThreadControl threadControl) throws Throwable {");
-
-        methodProlog(writer, methodGroup);
-
-        writer.println(ident(2) + "long realTime = 0;");
-
-        boolean isSingleMethod = (methodGroup.methods().size() == 1);
-        int subGroup = -1;
-        for (MethodInfo method : methodGroup.methods()) {
-            compilerControl.defaultForceInline(method);
-
-            subGroup++;
-
-            writer.println(ident(2) + "if (threadControl.subgroup == " + subGroup + ") {");
-
-            iterationProlog(writer, 3, method, states);
-
-            invocationProlog(writer, 3, method, states, false);
-
-            writer.println(ident(3) + "long time1 = System.nanoTime();");
-            writer.println(ident(3) + "int batchSize = control.batchSize;");
-            writer.println(ident(3) + "for (int b = 0; b < batchSize; b++) {");
-            writer.println(ident(4) + emitCall(method, states) + ';');
-            writer.println(ident(3) + "}");
-            writer.println(ident(3) + "long time2 = System.nanoTime();");
-
-            invocationEpilog(writer, 3, method, states, false);
-
-            iterationEpilog(writer, 3, method, states);
-
-            writer.println(ident(3) + "Collection<Result> results = new ArrayList<Result>();");
-            writer.println(ident(3) + "TimeUnit tu = (control.timeUnit != null) ? control.timeUnit : TimeUnit." + methodGroup.getOutputTimeUnit() + ";");
-            writer.println(ident(3) + "results.add(new SingleShotResult(ResultRole.PRIMARY, \"" + method.getName() + "\", (realTime > 0) ? realTime : (time2 - time1), tu));");
-            if (!isSingleMethod) {
-                writer.println(ident(3) + "results.add(new SingleShotResult(ResultRole.SECONDARY, \"" + method.getName() + "\", (realTime > 0) ? realTime : (time2 - time1), tu));");
-            }
-            writer.println(ident(3) + "return results;");
-            writer.println(ident(2) + "} else");
-        }
-        writer.println(ident(3) + "throw new IllegalStateException(\"Harness failed to distribute threads among groups properly\");");
-        writer.println();
-
-        writer.println(ident(1) + "}");
-    }
-
-    private void invocationProlog(PrintWriter writer, int prefix, MethodInfo method, StateObjectHandler states, boolean pauseMeasurement) {
-        if (!states.getInvocationSetups(method).isEmpty()) {
-            for (String s : states.getInvocationSetups(method))
-                writer.println(ident(prefix) + s);
-            if (pauseMeasurement)
-                writer.println(ident(prefix) + "long rt = System.nanoTime();");
-            writer.println();
-        }
-    }
-
-    private void invocationEpilog(PrintWriter writer, int prefix, MethodInfo method, StateObjectHandler states, boolean pauseMeasurement) {
-        if (!states.getInvocationTearDowns(method).isEmpty()) {
-            writer.println();
-            if (pauseMeasurement)
-                writer.println(ident(prefix) + "realTime += (System.nanoTime() - rt);");
-            for (String s : states.getInvocationTearDowns(method))
-                writer.println(ident(prefix) + s);
-            writer.println();
-        }
-    }
-
-    private void iterationProlog(PrintWriter writer, int prefix, MethodInfo method, StateObjectHandler states) {
-        for (String s : states.getStateGetters(method)) writer.println(ident(prefix) + s);
-        writer.println();
-
-        writer.println(ident(prefix) + "control.preSetup();");
-
-        for (String s : states.getIterationSetups(method)) writer.println(ident(prefix) + s);
-        writer.println();
-    }
-
-    private void iterationEpilog(PrintWriter writer, int prefix, MethodInfo method, StateObjectHandler states) {
-        writer.println(ident(prefix) + "control.preTearDown();");
-
-        for (String s : states.getIterationTearDowns(method)) writer.println(ident(prefix) + s);
-        writer.println();
-
-        writer.println(ident(prefix) + "if (control.isLastIteration()) {");
-        for (String s : states.getRunTearDowns(method)) writer.println(ident(prefix + 1) + s);
-        for (String s : states.getStateDestructors(method)) writer.println(ident(prefix + 1) + s);
-        writer.println(ident(prefix) + "}");
-    }
-
-    private String emitCall(MethodInfo method, StateObjectHandler states) {
-        if ("void".equalsIgnoreCase(method.getReturnType())) {
-            return states.getImplicit("bench").localIdentifier + "." + method.getName() + "(" + states.getArgList(method) + ")";
-        } else {
-            return states.getImplicit("blackhole").localIdentifier + ".consume(" + states.getImplicit("bench").localIdentifier + "." + method.getName() + "(" + states.getArgList(method) + "))";
-        }
-    }
-
-    public static String ident(int prefix) {
-        char[] chars = new char[prefix*4];
-        for (int i = 0; i < prefix*4; i++) {
-            chars[i] = ' ';
-        }
-        return new String(chars);
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/BenchmarkGeneratorUtils.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-public class BenchmarkGeneratorUtils {
-
-    public static <T extends Annotation> Collection<MethodInfo> getMethodsAnnotatedWith(GeneratorSource source, Class<T> annClass) {
-        List<MethodInfo> mis = new ArrayList<MethodInfo>();
-        for (ClassInfo ci : source.getClasses()) {
-            for (MethodInfo mi : ci.getDeclaredMethods()) {
-                if (mi.getAnnotation(annClass) != null) {
-                    mis.add(mi);
-                }
-            }
-        }
-        return mis;
-    }
-
-    public static <T extends Annotation> Collection<ClassInfo> getClassesAnnotatedWith(GeneratorSource source, Class<T> annClass) {
-        List<ClassInfo> cis = new ArrayList<ClassInfo>();
-        for (ClassInfo ci : source.getClasses()) {
-            if (ci.getAnnotation(annClass) != null) {
-                cis.add(ci);
-            }
-        }
-        return cis;
-    }
-
-    public static <T extends Annotation> Collection<FieldInfo> getFieldsAnnotatedWith(GeneratorSource source, Class<T> annClass) {
-        List<FieldInfo> mis = new ArrayList<FieldInfo>();
-        for (ClassInfo ci : source.getClasses()) {
-            for (FieldInfo mi : ci.getDeclaredFields()) {
-                if (mi.getAnnotation(annClass) != null) {
-                    mis.add(mi);
-                }
-            }
-        }
-        return mis;
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/BenchmarkInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import java.util.Map;
-
-public class BenchmarkInfo {
-    public final String userName;
-    public final String generatedName;
-    public final String generatedPackageName;
-    public final String generatedClassName;
-    public final Map<String, MethodGroup> methodGroups;
-
-    public BenchmarkInfo(String userName, String generatedPackageName, String generatedClassName, Map<String, MethodGroup> methods) {
-        this.userName = userName;
-        this.generatedPackageName = generatedPackageName;
-        this.generatedClassName = generatedClassName;
-        this.generatedName = generatedPackageName + "." + generatedClassName;
-        this.methodGroups = methods;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        BenchmarkInfo that = (BenchmarkInfo) o;
-
-        if (!userName.equals(that.userName)) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return userName.hashCode();
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/ClassInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-
-/**
- * Class metadata.
- */
-public interface ClassInfo extends MetadataInfo {
-
-    /**
-     * Returns the fully qualified package name for class.
-     * Example:
-     *   f(java.util.HashMap) = java.util
-     *
-     * @return package name
-     */
-    String getPackageName();
-
-    /**
-     * Returns the marshalling
-     * @return
-     */
-    String getNestedName();
-
-    String getQualifiedName();
-
-    Collection<FieldInfo> getDeclaredFields();
-
-    Collection<FieldInfo> getFields();
-
-    Collection<MethodInfo> getConstructors();
-
-    Collection<MethodInfo> getDeclaredMethods();
-
-    Collection<MethodInfo> getMethods();
-
-    Collection<ClassInfo> getSuperclasses();
-
-    <T extends Annotation> T getAnnotation(Class<T> annClass);
-
-    <T extends Annotation> T getAnnotationRecursive(Class<T> annClass);
-
-    boolean isNested();
-
-    boolean isAbstract();
-
-    boolean isPublic();
-
-    boolean isStatic();
-
-    boolean isStrictFP();
-
-}
-
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/CompilerControlPlugin.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.annotations.CompilerControl;
-import org.openjdk.jmh.runner.CompilerHints;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-public class CompilerControlPlugin implements Plugin {
-
-    private final List<String> lines = new ArrayList<String>();
-
-    private final Set<MethodInfo> defaultForceInlineMethods = new TreeSet<MethodInfo>(new Comparator<MethodInfo>() {
-        @Override
-        public int compare(MethodInfo o1, MethodInfo o2) {
-            return o1.getQualifiedName().compareTo(o2.getQualifiedName());
-        }
-    });
-
-    private final Set<ClassInfo> defaultForceInlineClasses = new TreeSet<ClassInfo>(new Comparator<ClassInfo>() {
-        @Override
-        public int compare(ClassInfo o1, ClassInfo o2) {
-            return o1.getQualifiedName().compareTo(o2.getQualifiedName());
-        }
-    });
-
-    public void defaultForceInline(MethodInfo methodInfo) {
-        defaultForceInlineMethods.add(methodInfo);
-    }
-
-    public void defaultForceInline(ClassInfo classInfo) {
-        defaultForceInlineClasses.add(classInfo);
-    }
-
-    public void process(GeneratorSource source) {
-        try {
-            for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, CompilerControl.class)) {
-                CompilerControl ann = element.getAnnotation(CompilerControl.class);
-                if (ann == null) {
-                    throw new IllegalStateException("No annotation");
-                }
-
-                CompilerControl.Mode command = ann.value();
-                lines.add(command.command() + "," + getName(element));
-            }
-
-            for (MethodInfo element : defaultForceInlineMethods) {
-                if (element.getAnnotation(CompilerControl.class) != null) continue;
-                lines.add(CompilerControl.Mode.INLINE.command() + "," + getName(element));
-            }
-
-            for (ClassInfo element : BenchmarkGeneratorUtils.getClassesAnnotatedWith(source, CompilerControl.class)) {
-                CompilerControl ann = element.getAnnotation(CompilerControl.class);
-                if (ann == null) {
-                    throw new IllegalStateException("No annotation");
-                }
-
-                CompilerControl.Mode command = ann.value();
-                lines.add(command.command() + "," + getName(element));
-            }
-
-            for (ClassInfo element : defaultForceInlineClasses) {
-                if (element.getAnnotation(CompilerControl.class) != null) continue;
-                lines.add(CompilerControl.Mode.INLINE.command() + "," + getName(element));
-            }
-        } catch (Throwable t) {
-            source.printError("Compiler control processor had thrown the unexpected exception", t);
-        }
-    }
-
-    @Override
-    public void finish(GeneratorSource source) {
-        try {
-            PrintWriter writer = new PrintWriter(source.newResource(CompilerHints.LIST.substring(1)));
-            for (String line : lines) {
-                writer.println(line);
-            }
-            writer.close();
-        } catch (IOException ex) {
-            source.printError("Error writing compiler hint list ", ex);
-        } catch (Throwable t) {
-            source.printError("Compiler control processor had thrown the unexpected exception", t);
-        }
-    }
-
-    private static String getName(MethodInfo mi) {
-       return mi.getOwner().getQualifiedName().replaceAll("\\.", "/") + "." + mi.getName();
-    }
-
-    private static String getName(ClassInfo ci) {
-      return ci.getQualifiedName().replaceAll("\\.", "/") + ".*";
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/FieldInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import java.lang.annotation.Annotation;
-
-public interface FieldInfo extends MetadataInfo {
-
-    String getName();
-
-    String getType();
-
-    boolean isPublic();
-
-    boolean isStatic();
-
-    <T extends Annotation> T getAnnotation(Class<T> annClass);
-
-    ClassInfo getOwner();
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GenerateMicroBenchmarkProcessor.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.processor.internal.annotations.AnnProcessGeneratorSource;
-
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedSourceVersion;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.TypeElement;
-import java.util.Set;
-
-/**
- * @author staffan.friberg@oracle.com
- * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
- * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
- */
-@SupportedAnnotationTypes("*")
-@SupportedSourceVersion(SourceVersion.RELEASE_6)
-public class GenerateMicroBenchmarkProcessor extends AbstractProcessor {
-
-    private final BenchmarkGenerator generator = new BenchmarkGenerator();
-
-    @Override
-    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
-        GeneratorSource source = new AnnProcessGeneratorSource(roundEnv, processingEnv);
-        if (!roundEnv.processingOver()) {
-            generator.generate(source);
-        } else {
-            generator.complete(source);
-        }
-        return true;
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GenerationException.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-public class GenerationException extends RuntimeException {
-
-    private final MetadataInfo element;
-
-    public GenerationException(String message, MetadataInfo element) {
-        super(message);
-        this.element = element;
-    }
-
-    public MetadataInfo getElement() {
-        return element;
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GeneratorSource.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collection;
-
-public interface GeneratorSource {
-
-    Collection<ClassInfo> getClasses();
-
-    ClassInfo resolveClass(String className);
-
-    Writer newResource(String path) throws IOException;
-
-    Writer newFile(String objectName) throws IOException;
-
-    void printError(String message);
-
-    void printError(String message, MetadataInfo element);
-
-    void printError(String message, Throwable throwable);
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GroupValidationPlugin.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.annotations.CompilerControl;
-import org.openjdk.jmh.annotations.Group;
-import org.openjdk.jmh.annotations.GroupThreads;
-import org.openjdk.jmh.annotations.Threads;
-
-public class GroupValidationPlugin implements Plugin {
-
-    @Override
-    public void process(GeneratorSource source) {
-        try {
-            for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, CompilerControl.class)) {
-                if (element.getAnnotation(Threads.class) != null) {
-                    source.printError("@" + Threads.class.getSimpleName() + " annotation is placed within " +
-                                    "the benchmark method with @" + Group.class.getSimpleName() + " annotation. " +
-                                    "This has ambiguous behavioral effect, and prohibited. " +
-                                    "Did you mean @" + GroupThreads.class.getSimpleName() + " instead?",
-                            element);
-                }
-            }
-        } catch (Throwable t) {
-            source.printError("Group validation processor had thrown the unexpected exception", t);
-        }
-    }
-
-    @Override
-    public void finish(GeneratorSource source) {
-        // do nothing
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/HelperMethodInvocation.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.annotations.Level;
-
-public class HelperMethodInvocation implements Comparable<HelperMethodInvocation> {
-    public final MethodInfo method;
-    public final StateObject state;
-    public final Level helperLevel;
-    public final HelperType type;
-
-    public HelperMethodInvocation(MethodInfo method, StateObject state, Level helperLevel, HelperType type) {
-        this.method = method;
-        this.state = state;
-        this.helperLevel = helperLevel;
-        this.type = type;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        HelperMethodInvocation that = (HelperMethodInvocation) o;
-
-        if (helperLevel != that.helperLevel) return false;
-        if (!method.equals(that.method)) return false;
-        if (!state.equals(that.state)) return false;
-        if (type != that.type) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = method.hashCode();
-        result = 31 * result + state.hashCode();
-        result = 31 * result + helperLevel.hashCode();
-        result = 31 * result + type.hashCode();
-        return result;
-    }
-
-    @Override
-    public int compareTo(HelperMethodInvocation o) {
-        return method.compareTo(o.method);
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/HelperMethodValidationPlugin.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.annotations.Setup;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.TearDown;
-
-public class HelperMethodValidationPlugin implements Plugin {
-
-    @Override
-    public void process(GeneratorSource source) {
-        try {
-            for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, Setup.class)) {
-                // OK to have these annotation for @State objects
-                if (element.getOwner().getAnnotation(State.class) != null) continue;
-
-                // Abstract classes are not instantiated, assume OK
-                if (element.getOwner().isAbstract()) continue;
-
-                source.printError(
-                        "@" + Setup.class.getSimpleName() + " annotation is placed within " +
-                                "the class not having @" + State.class.getSimpleName() + " annotation. " +
-                                "This has no behavioral effect, and prohibited.",
-                        element);
-            }
-
-            for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, TearDown.class)) {
-                // OK to have these annotation for @State objects
-                if (element.getOwner().getAnnotation(State.class) != null) continue;
-
-                // Abstract classes are not instantiated, assume OK
-                if (element.getOwner().isAbstract()) continue;
-
-                source.printError(
-                            "@" + TearDown.class.getSimpleName() + " annotation is placed within " +
-                                    "the class not having @" + State.class.getSimpleName() + " annotation. " +
-                                    "This can be futile if no @State-bearing subclass is used.",
-                            element);
-            }
-
-        } catch (Throwable t) {
-            source.printError("Helper method validation processor had thrown the unexpected exception.", t);
-        }
-    }
-
-    @Override
-    public void finish(GeneratorSource source) {
-        // do nothing
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/HelperType.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-public enum HelperType {
-    SETUP,
-    TEARDOWN,
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MetadataInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-public interface MetadataInfo {
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MethodGroup.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.annotations.Fork;
-import org.openjdk.jmh.annotations.Measurement;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OperationsPerInvocation;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Param;
-import org.openjdk.jmh.annotations.Threads;
-import org.openjdk.jmh.annotations.Warmup;
-import org.openjdk.jmh.runner.parameters.TimeValue;
-import org.openjdk.jmh.util.internal.Optional;
-
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.TimeUnit;
-
-public class MethodGroup implements Comparable<MethodGroup> {
-    private final String name;
-    private final Set<MethodInvocation> methods;
-    private final EnumSet<Mode> modes;
-    private final Map<String, String[]> params;
-    private boolean strictFP;
-
-    public MethodGroup(String name) {
-        this.name = name;
-        this.methods = new TreeSet<MethodInvocation>();
-        this.modes = EnumSet.noneOf(Mode.class);
-        this.params = new TreeMap<String, String[]>();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        MethodGroup methodGroup = (MethodGroup) o;
-
-        if (!name.equals(methodGroup.name)) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return name.hashCode();
-    }
-
-    @Override
-    public int compareTo(MethodGroup o) {
-        return name.compareTo(o.name);
-    }
-
-    public void addMethod(MethodInfo method, int threads) {
-        methods.add(new MethodInvocation(method, threads));
-    }
-
-    public Collection<MethodInfo> methods() {
-        Collection<MethodInfo> result = new ArrayList<MethodInfo>();
-        for (MethodInvocation m : methods) {
-            result.add(m.method);
-        }
-        return result;
-    }
-
-    public Optional<Integer> getTotalThreadCount() {
-        Threads ann = getFinal(Threads.class);
-        if (ann != null) {
-            return Optional.of(ann.value());
-        }
-        return Optional.none();
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void addParam(String name, String[] value) {
-        params.put(name, value);
-    }
-
-    public void addStrictFP(boolean sfp) {
-        strictFP |= sfp;
-    }
-
-    public boolean isStrictFP() {
-        return strictFP;
-    }
-
-    public void addModes(Mode eMode) {
-        modes.add(eMode);
-    }
-
-    public void addModes(Mode[] eModes) {
-        Collections.addAll(modes, eModes);
-    }
-
-    public Set<Mode> getModes() {
-        return modes;
-    }
-
-    public int[] getThreads() {
-        int[] threads = new int[methods.size()];
-        int c = 0;
-        for (MethodInvocation mi : methods) {
-            threads[c++] = mi.threads;
-        }
-        return threads;
-    }
-
-    public long getOperationsPerInvocation() {
-        OperationsPerInvocation ann = getFinal(OperationsPerInvocation.class);
-        return (ann != null) ? ann.value() : 1;
-    }
-
-    public TimeUnit getOutputTimeUnit() {
-        OutputTimeUnit ann = getFinal(OutputTimeUnit.class);
-        return (ann != null) ? ann.value() : TimeUnit.MILLISECONDS;
-    }
-
-    public Optional<Integer> getWarmupIterations() {
-        Warmup ann = getFinal(Warmup.class);
-        if (ann != null && ann.iterations() != Warmup.BLANK_ITERATIONS) {
-            return Optional.of(ann.iterations());
-        }
-        return Optional.none();
-    }
-
-    public Optional<TimeValue> getWarmupTime() {
-        Warmup ann = getFinal(Warmup.class);
-        if (ann != null && ann.time() != Warmup.BLANK_TIME) {
-            return Optional.of(new TimeValue(ann.time(), ann.timeUnit()));
-        }
-        return Optional.none();
-    }
-
-    public Optional<Integer> getWarmupBatchSize() {
-        Warmup ann = getFinal(Warmup.class);
-        if (ann != null && ann.batchSize() != Warmup.BLANK_BATCHSIZE) {
-            return Optional.of(ann.batchSize());
-        }
-        return Optional.none();
-    }
-
-    public Optional<Integer> getMeasurementIterations() {
-        Measurement ann = getFinal(Measurement.class);
-        if (ann != null && ann.iterations() != Measurement.BLANK_ITERATIONS) {
-            return Optional.of(ann.iterations());
-        }
-        return Optional.none();
-    }
-
-    public Optional<TimeValue> getMeasurementTime() {
-        Measurement ann = getFinal(Measurement.class);
-        if (ann != null && ann.time() != Measurement.BLANK_TIME) {
-            return Optional.of(new TimeValue(ann.time(), ann.timeUnit()));
-        }
-        return Optional.none();
-    }
-
-    public Optional<Integer> getMeasurementBatchSize() {
-        Measurement ann = getFinal(Measurement.class);
-        if (ann != null && ann.batchSize() != Measurement.BLANK_BATCHSIZE) {
-            return Optional.of(ann.batchSize());
-        }
-        return Optional.none();
-    }
-
-    public Optional<Integer> getForks() {
-        Fork ann = getFinal(Fork.class);
-        if (ann != null && ann.value() != Fork.BLANK_FORKS) {
-            return Optional.of(ann.value());
-        }
-        return Optional.none();
-    }
-
-    public Optional<Integer> getWarmupForks() {
-        Fork ann = getFinal(Fork.class);
-        if (ann != null && ann.warmups() != Fork.BLANK_FORKS) {
-            return Optional.of(ann.warmups());
-        }
-        return Optional.none();
-    }
-
-    public Optional<Collection<String>> getJVMArgs() {
-        Fork ann = getFinal(Fork.class);
-        if (ann != null && !(ann.jvmArgs().length == 1 && ann.jvmArgs()[0].equals(Fork.BLANK_ARGS))) {
-            return Optional.<Collection<String>>of(Arrays.asList(ann.jvmArgs()));
-        }
-        return Optional.none();
-    }
-
-    public Optional<Collection<String>> getJVMArgsAppend() {
-        Fork ann = getFinal(Fork.class);
-        if (ann != null && !(ann.jvmArgsAppend().length == 1 && ann.jvmArgsAppend()[0].equals(Fork.BLANK_ARGS))) {
-            return Optional.<Collection<String>>of(Arrays.asList(ann.jvmArgsAppend()));
-        }
-        return Optional.none();
-    }
-
-    public Optional<Collection<String>> getJVMArgsPrepend() {
-        Fork ann = getFinal(Fork.class);
-        if (ann != null && !(ann.jvmArgsPrepend().length == 1 && ann.jvmArgsPrepend()[0].equals(Fork.BLANK_ARGS))) {
-            return Optional.<Collection<String>>of(Arrays.asList(ann.jvmArgsPrepend()));
-        }
-        return Optional.none();
-    }
-
-    private <T extends Annotation> T getFinal(Class<T> klass) {
-        T finalAnn = null;
-        for (MethodInvocation mi : methods) {
-            T ann = mi.method.getAnnotationRecursive(klass);
-            if (ann != null && finalAnn != null) {
-                if (!finalAnn.equals(ann)) {
-                    throw new GenerationException("Colliding annotations: " + ann + " vs. " + finalAnn, mi.method);
-                }
-            }
-            finalAnn = ann;
-        }
-        return finalAnn;
-    }
-
-    public Optional<Map<String, String[]>> getParams() {
-        Map<String, String[]> map = new TreeMap<String, String[]>();
-
-        for (String key : params.keySet()) {
-            String[] values = params.get(key);
-            if (values.length == 1 && values[0].equalsIgnoreCase(Param.BLANK_ARGS)) {
-                map.put(key, new String[0]);
-            } else {
-                map.put(key, values);
-            }
-        }
-
-        if (params.isEmpty()) {
-            return Optional.none();
-        } else {
-            return Optional.of(map);
-        }
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MethodInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-
-public interface MethodInfo extends Comparable<MethodInfo>, MetadataInfo {
-
-    ClassInfo getOwner();
-
-    String getName();
-    String getQualifiedName();
-    String getReturnType();
-
-    Collection<ParameterInfo> getParameters();
-
-    <T extends Annotation> T getAnnotation(Class<T> annClass);
-    <T extends Annotation> T getAnnotationRecursive(Class<T> annClass);
-
-    boolean isPublic();
-    boolean isAbstract();
-    boolean isSynchronized();
-    boolean isStrictFP();
-
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MethodInvocation.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-public class MethodInvocation implements Comparable<MethodInvocation> {
-    public final MethodInfo method;
-    public final int threads;
-
-    public MethodInvocation(MethodInfo method, int threads) {
-        this.method = method;
-        this.threads = threads;
-    }
-
-    @Override
-    public int compareTo(MethodInvocation o) {
-        return method.compareTo(o.method);
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/ParamValidationPlugin.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.annotations.Param;
-import org.openjdk.jmh.annotations.State;
-
-public class ParamValidationPlugin implements Plugin {
-
-    @Override
-    public void process(GeneratorSource source) {
-        try {
-            for (FieldInfo element : BenchmarkGeneratorUtils.getFieldsAnnotatedWith(source, Param.class)) {
-                if (!element.isPublic()) {
-                    source.printError(
-                            "@" + Param.class.getSimpleName() + " annotation is not acceptable on non-public field.",
-                            element
-                    );
-                }
-
-                if (element.isStatic()) {
-                    source.printError(
-                            "@" + Param.class.getSimpleName() + " annotation is not acceptable on static fields.",
-                            element
-                    );
-                }
-
-                if (element.getOwner().getAnnotationRecursive(State.class) == null) {
-                    source.printError(
-                            "@" + Param.class.getSimpleName() + " annotation should be placed in @" + State.class.getSimpleName() +
-                                    "-annotated class.",
-                            element
-                    );
-                }
-
-
-                String[] values = element.getAnnotation(Param.class).value();
-
-                if (values.length >= 1 && !values[0].equalsIgnoreCase(Param.BLANK_ARGS)) {
-                    String type = element.getType();
-                    for (String val : values) {
-                        if (!isConforming(val, type)) {
-                            source.printError(
-                                    "Some @" + Param.class.getSimpleName() + " values can not be converted to target type: " +
-                                    "\"" + val + "\" can not be converted to " + type,
-                                    element
-                            );
-                        }
-                    }
-                }
-
-            }
-        } catch (Throwable t) {
-            source.printError("Param validation processor had thrown the unexpected exception.", t);
-        }
-    }
-
-    private boolean isConforming(String val, String type) {
-        if (type.equalsIgnoreCase("java.lang.String")) {
-            return true;
-        }
-        if (type.equalsIgnoreCase("boolean") || type.equalsIgnoreCase("java.lang.Boolean")) {
-            return (val.equalsIgnoreCase("true") || val.equalsIgnoreCase("false"));
-        }
-        if (type.equalsIgnoreCase("byte") || type.equalsIgnoreCase("java.lang.Byte")) {
-            try {
-                Byte.valueOf(val);
-                return true;
-            } catch (NumberFormatException nfe){
-            }
-        }
-        if (type.equalsIgnoreCase("char") || type.equalsIgnoreCase("java.lang.Character")) {
-            return (val.length() != 0);
-        }
-        if (type.equalsIgnoreCase("short") || type.equalsIgnoreCase("java.lang.Short")) {
-            try {
-                Short.valueOf(val);
-                return true;
-            } catch (NumberFormatException nfe){
-            }
-        }
-        if (type.equalsIgnoreCase("int") || type.equalsIgnoreCase("java.lang.Integer")) {
-            try {
-                Integer.valueOf(val);
-                return true;
-            } catch (NumberFormatException nfe){
-            }
-        }
-        if (type.equalsIgnoreCase("float") || type.equalsIgnoreCase("java.lang.Float")) {
-            try {
-                Float.valueOf(val);
-                return true;
-            } catch (NumberFormatException nfe){
-            }
-        }
-        if (type.equalsIgnoreCase("long") || type.equalsIgnoreCase("java.lang.Long")) {
-            try {
-                Long.valueOf(val);
-                return true;
-            } catch (NumberFormatException nfe){
-            }
-        }
-        if (type.equalsIgnoreCase("double") || type.equalsIgnoreCase("java.lang.Double")) {
-            try {
-                Double.valueOf(val);
-                return true;
-            } catch (NumberFormatException nfe){
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void finish(GeneratorSource source) {
-        // do nothing
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/ParameterInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-public interface ParameterInfo extends MetadataInfo {
-    ClassInfo getType();
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/Plugin.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-public interface Plugin {
-
-    void process(GeneratorSource source);
-
-    void finish(GeneratorSource source);
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/StateObject.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.annotations.Scope;
-
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.TreeMap;
-
-public class StateObject {
-
-    public static final Comparator<StateObject> ID_COMPARATOR = new Comparator<StateObject>() {
-        @Override
-        public int compare(StateObject o1, StateObject o2) {
-            return o1.fieldIdentifier.compareTo(o2.fieldIdentifier);
-        }
-    };
-
-    public final String userType;
-    public final String type;
-    public final Scope scope;
-    public final String localIdentifier;
-    public final String fieldIdentifier;
-    public final Map<String, String> params;
-
-    public StateObject(String userType, String jmhType, Scope scope, String fieldIdentifier, String localIdentifier) {
-        this.userType = userType;
-        this.type = jmhType;
-        this.scope = scope;
-        this.localIdentifier = localIdentifier;
-        this.fieldIdentifier = fieldIdentifier;
-        this.params = new TreeMap<String, String>();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        StateObject that = (StateObject) o;
-
-        if (fieldIdentifier != null ? !fieldIdentifier.equals(that.fieldIdentifier) : that.fieldIdentifier != null)
-            return false;
-        if (scope != that.scope) return false;
-        if (type != null ? !type.equals(that.type) : that.type != null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = type != null ? type.hashCode() : 0;
-        result = 31 * result + (scope != null ? scope.hashCode() : 0);
-        result = 31 * result + (fieldIdentifier != null ? fieldIdentifier.hashCode() : 0);
-        return result;
-    }
-
-    public String toTypeDef() {
-        return type + " " + localIdentifier;
-    }
-
-    public String toLocal() {
-        return localIdentifier;
-    }
-
-    public String getParamAccessor(String name) {
-        return params.get(name);
-    }
-
-    public void addParam(FieldInfo fieldInfo) {
-        String type = fieldInfo.getType();
-        String name = fieldInfo.getName();
-        if (type.equalsIgnoreCase("java.lang.String")) {
-            params.put(name, "control.getParam(\"" + name + "\")");
-            return;
-        }
-        if (type.equalsIgnoreCase("boolean") || type.equalsIgnoreCase("java.lang.Boolean")) {
-            params.put(name, "Boolean.valueOf(control.getParam(\"" + name + "\"))");
-            return;
-        }
-        if (type.equalsIgnoreCase("byte") || type.equalsIgnoreCase("java.lang.Byte")) {
-            params.put(name, "Byte.valueOf(control.getParam(\"" + name + "\"))");
-            return;
-        }
-        if (type.equalsIgnoreCase("char") || type.equalsIgnoreCase("java.lang.Character")) {
-            params.put(name, "(control.getParam(\"" + name + "\")).charAt(0)");
-            return;
-        }
-        if (type.equalsIgnoreCase("short") || type.equalsIgnoreCase("java.lang.Short")) {
-            params.put(name, "Short.valueOf(control.getParam(\"" + name + "\"))");
-            return;
-        }
-        if (type.equalsIgnoreCase("int") || type.equalsIgnoreCase("java.lang.Integer")) {
-            params.put(name, "Integer.valueOf(control.getParam(\"" + name + "\"))");
-            return;
-        }
-        if (type.equalsIgnoreCase("float") || type.equalsIgnoreCase("java.lang.Float")) {
-            params.put(name, "Float.valueOf(control.getParam(\"" + name + "\"))");
-            return;
-        }
-        if (type.equalsIgnoreCase("long") || type.equalsIgnoreCase("java.lang.Long")) {
-            params.put(name, "Long.valueOf(control.getParam(\"" + name + "\"))");
-            return;
-        }
-        if (type.equalsIgnoreCase("double") || type.equalsIgnoreCase("java.lang.Double")) {
-            params.put(name, "Double.valueOf(control.getParam(\"" + name + "\"))");
-            return;
-        }
-        throw new IllegalStateException("Unknown type: " + type);
-    }
-
-    public Collection<String> getParamsLabels() {
-        return params.keySet();
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/StateObjectHandler.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,604 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal;
-
-import org.openjdk.jmh.annotations.AuxCounters;
-import org.openjdk.jmh.annotations.Level;
-import org.openjdk.jmh.annotations.Param;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.Setup;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.TearDown;
-import org.openjdk.jmh.logic.Control;
-import org.openjdk.jmh.util.internal.HashMultimap;
-import org.openjdk.jmh.util.internal.Multimap;
-import org.openjdk.jmh.util.internal.TreesetMultimap;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-public class StateObjectHandler {
-
-    private final Multimap<String, StateObject> args;
-    private final Map<String, StateObject> implicits;
-    private final Set<StateObject> stateObjects;
-    private final Multimap<StateObject, HelperMethodInvocation> helpersByState;
-
-    private final Map<String, Integer> globalIndexByType = new HashMap<String, Integer>();
-    private final Map<String, Integer> groupIndexByType = new HashMap<String, Integer>();
-    private final Map<String, Integer> localIndexByType = new HashMap<String, Integer>();
-
-    private final HashMap<String, String> collapsedTypes = new HashMap<String, String>();
-    private int collapsedIndex = 0;
-
-    private final Set<String> claimedJmhTypes = new HashSet<String>();
-    private final HashMap<String, String> jmhTypes = new HashMap<String, String>();
-    private final Multimap<String, String> auxNames = new HashMultimap<String, String>();
-    private final Map<String, String> auxAccessors = new HashMap<String, String>();
-
-    public StateObjectHandler() {
-        this.args = new HashMultimap<String, StateObject>();
-        this.implicits = new HashMap<String, StateObject>();
-        this.stateObjects = new HashSet<StateObject>();
-        this.helpersByState = new TreesetMultimap<StateObject, HelperMethodInvocation>();
-    }
-
-    private String getJMHtype(String type) {
-        String jmhType = jmhTypes.get(type);
-        if (jmhType == null) {
-            int v = 1;
-            do {
-                jmhType = getBaseType(type) + "_" + v + "_jmh";
-                v++;
-            } while (!claimedJmhTypes.add(jmhType));
-            jmhTypes.put(type, jmhType);
-        }
-        return jmhType;
-    }
-
-    private String getBaseType(String type) {
-        return type.substring(type.lastIndexOf(".") + 1);
-    }
-
-    public void bindArg(MethodInfo mi, ParameterInfo pi) {
-        State ann = pi.getType().getAnnotation(State.class);
-        if (ann != null) {
-            bindState(mi, pi.getType(), ann.value(), null);
-        } else {
-            throw new IllegalStateException("The method parameter is not a @State: " + pi);
-        }
-    }
-
-    public void bindImplicit(ClassInfo ci, String label) {
-        bindImplicit(ci, label, Scope.Thread);
-    }
-
-    public void bindImplicit(ClassInfo ci, String label, Scope scope) {
-        State ann = ci.getAnnotation(State.class);
-        bindState(null, ci, (ann != null) ? ann.value() : scope, label);
-    }
-
-    private void bindState(MethodInfo execMethod, ClassInfo ci, Scope scope, String implicitLabel) {
-        Integer index;
-        String className = ci.getQualifiedName();
-        switch (scope) {
-            case Benchmark: {
-                index = globalIndexByType.get(className);
-                if (index == null) {
-                    index = 0;
-                    globalIndexByType.put(className, index);
-                }
-                break;
-            }
-            case Group:
-                index = groupIndexByType.get(className);
-                if (index == null) {
-                    index = 0;
-                    groupIndexByType.put(className, index);
-                }
-                break;
-            case Thread: {
-                index = localIndexByType.get(className);
-                if (index == null) {
-                    index = -1;
-                }
-                index++;
-                localIndexByType.put(className, index);
-                break;
-            }
-            default:
-                throw new IllegalStateException("Unknown scope: " + scope);
-        }
-
-        StateObject so;
-        if (implicitLabel != null) {
-            so = new StateObject(className, getJMHtype(className), scope, "f_" + implicitLabel, "l_" + implicitLabel);
-            implicits.put(implicitLabel, so);
-        } else {
-            String identifier = collapseTypeName(className) + index;
-            so = new StateObject(className, getJMHtype(className), scope, "f_" + identifier, "l_" + identifier);
-            args.put(execMethod.getName(), so);
-        }
-
-        // auxiliary result, produce the accessors
-        if (ci.getAnnotation(AuxCounters.class) != null) {
-            if (scope != Scope.Thread) {
-                throw new GenerationException("@" + AuxCounters.class.getSimpleName() +
-                        " can only be used with " + Scope.class.getSimpleName() + "." + Scope.Thread + " states.", ci);
-            }
-
-            for (FieldInfo sub : ci.getDeclaredFields()) {
-                if (sub.isPublic()) {
-                    String fieldType = sub.getType();
-                    if (fieldType.equals("int") || fieldType.equals("long")) {
-                        String name = sub.getName();
-                        String meth = execMethod.getName();
-                        auxNames.put(meth, name);
-                        String prev = auxAccessors.put(meth + name, so.localIdentifier + "." + name);
-                        if (prev != null) {
-                            throw new GenerationException("Conflicting @" + AuxCounters.class.getSimpleName() +
-                                " counters. Make sure there are no @" + State.class.getSimpleName() + "-s with the same counter " +
-                                " injected into this method.", sub);
-                        }
-                    }
-                }
-            }
-
-            for (MethodInfo sub : ci.getDeclaredMethods()) {
-                if (sub.isPublic()) {
-                    String returnType = sub.getReturnType();
-                    if (returnType.equals("int") || returnType.equals("long")) {
-                        String name = sub.getName();
-                        String meth = execMethod.getName();
-                        auxNames.put(meth, name);
-                        String prev = auxAccessors.put(meth + name, so.localIdentifier + "." + name + "()");
-                        if (prev != null) {
-                            throw new GenerationException("Conflicting @" + AuxCounters.class.getSimpleName() +
-                                    " counters. Make sure there are no @" + State.class.getSimpleName() + "-s with the same counter " +
-                                    " injected into this method.", sub);
-                        }
-                    }
-                }
-            }
-        }
-
-        stateObjects.add(so);
-
-        // walk the type hierarchy up to discover inherited @Params
-        for (FieldInfo fi : ci.getFields()) {
-            if (fi.getAnnotation(Param.class) != null) {
-                so.addParam(fi);
-            }
-        }
-
-        // put the @State objects helper methods
-        for (MethodInfo mi : ci.getMethods()) {
-            Setup setupAnn = mi.getAnnotation(Setup.class);
-            if (setupAnn != null) {
-                helpersByState.put(so, new HelperMethodInvocation(mi, so, setupAnn.value(), HelperType.SETUP));
-            }
-
-            TearDown tearDownAnn = mi.getAnnotation(TearDown.class);
-            if (tearDownAnn != null) {
-                helpersByState.put(so, new HelperMethodInvocation(mi, so, tearDownAnn.value(), HelperType.TEARDOWN));
-            }
-        }
-
-    }
-
-    public String getArgList(MethodInfo methodInfo) {
-        StringBuilder sb = new StringBuilder();
-
-        int i = 0;
-        for (StateObject so : args.get(methodInfo.getName())) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(so.toLocal());
-            i++;
-        }
-        return sb.toString();
-    }
-
-    public String getTypeArgList(MethodInfo methodInfo) {
-        StringBuilder sb = new StringBuilder();
-
-        int i = 0;
-        for (StateObject so : args.get(methodInfo.getName())) {
-            if (i != 0) {
-                sb.append(", ");
-            }
-            sb.append(so.toTypeDef());
-            i++;
-        }
-        return sb.toString();
-    }
-
-    public static Collection<StateObject> cons(Collection<StateObject>... colls) {
-        SortedSet<StateObject> r = new TreeSet<StateObject>(StateObject.ID_COMPARATOR);
-        for (Collection<StateObject> coll : colls) {
-            r.addAll(coll);
-        }
-        return r;
-    }
-
-    public Collection<String> getHelperBlock(MethodInfo method, Level helperLevel, HelperType type) {
-
-        Collection<StateObject> states = cons(args.get(method.getName()), implicits.values(), getControls());
-
-        // Look for the offending methods.
-        // This will be used to skip the irrelevant blocks for state objects down the stream.
-        Set<StateObject> hasHelpers = new HashSet<StateObject>();
-        for (StateObject so : states) {
-            for (HelperMethodInvocation hmi : helpersByState.get(so)) {
-                if (hmi.helperLevel == helperLevel) hasHelpers.add(so);
-            }
-        }
-
-        List<String> result = new ArrayList<String>();
-
-        // Handle Thread object helpers
-        for (StateObject so : states) {
-            if (so.scope != Scope.Thread) continue;
-            if (!hasHelpers.contains(so)) continue;
-
-            if (type == HelperType.SETUP) {
-                result.add("if (!" + so.localIdentifier + ".ready" + helperLevel + ") {");
-                for (HelperMethodInvocation mi : helpersByState.get(so)) {
-                    if (mi.helperLevel == helperLevel && mi.type == HelperType.SETUP) {
-                        result.add("    " + so.localIdentifier + "." + mi.method.getName() + "();");
-                    }
-                }
-                result.add("    " + so.localIdentifier + ".ready" + helperLevel + " = true;");
-                result.add("}");
-            }
-
-            if (type == HelperType.TEARDOWN) {
-                result.add("if (" + so.localIdentifier + ".ready" + helperLevel + ") {");
-                for (HelperMethodInvocation mi : helpersByState.get(so)) {
-                    if (mi.helperLevel == helperLevel && mi.type == HelperType.TEARDOWN) {
-                        result.add("    " + so.localIdentifier + "." + mi.method.getName() + "();");
-                    }
-                }
-                result.add("    " + so.localIdentifier + ".ready" + helperLevel + " = false;");
-                result.add("}");
-            }
-        }
-
-        // Handle Benchmark/Group object helpers
-        for (StateObject so : states) {
-            if (so.scope != Scope.Benchmark && so.scope != Scope.Group) continue;
-            if (!hasHelpers.contains(so)) continue;
-
-            if (type == HelperType.SETUP) {
-                result.add("while(!" + so.type + ".setup" + helperLevel + "MutexUpdater.compareAndSet(" + so.localIdentifier + ", 0, 1)) {");
-                result.add("    if (Thread.interrupted()) throw new InterruptedException();");
-                result.add("}");
-                result.add("try {");
-                result.add("    if (!" + so.localIdentifier + ".ready" + helperLevel + ") {");
-                for (HelperMethodInvocation mi : helpersByState.get(so)) {
-                    if (mi.helperLevel == helperLevel && mi.type == HelperType.SETUP) {
-                        result.add("        " + so.localIdentifier + "." + mi.method.getName() + "();");
-                    }
-                }
-                result.add("        " + so.localIdentifier + ".ready" + helperLevel + " = true;");
-                result.add("    }");
-                result.add("} finally {");
-                result.add("    " + so.type + ".setup" + helperLevel + "MutexUpdater.set(" + so.localIdentifier + ", 0);");
-                result.add("}");
-            }
-
-            if (type == HelperType.TEARDOWN) {
-                result.add("while(!" + so.type + ".tear" + helperLevel + "MutexUpdater.compareAndSet(" + so.localIdentifier + ", 0, 1)) {");
-                result.add("    if (Thread.interrupted()) throw new InterruptedException();");
-                result.add("}");
-                result.add("try {");
-                result.add("    if (" + so.localIdentifier + ".ready" + helperLevel + ") {");
-                for (HelperMethodInvocation mi : helpersByState.get(so)) {
-                    if (mi.helperLevel == helperLevel && mi.type == HelperType.TEARDOWN) {
-                        result.add("        " + so.localIdentifier + "." + mi.method.getName() + "();");
-                    }
-                }
-                result.add("        " + so.localIdentifier + ".ready" + helperLevel + " = false;");
-                result.add("    }");
-                result.add("} finally {");
-                result.add("    " + so.type + ".tear" + helperLevel + "MutexUpdater.set(" + so.localIdentifier + ", 0);");
-                result.add("}");
-            }
-        }
-
-        return result;
-    }
-
-    public Collection<String> getInvocationSetups(MethodInfo method) {
-        return getHelperBlock(method, Level.Invocation, HelperType.SETUP);
-    }
-
-    public Collection<String> getInvocationTearDowns(MethodInfo method) {
-        return getHelperBlock(method, Level.Invocation, HelperType.TEARDOWN);
-    }
-
-    public Collection<String> getIterationSetups(MethodInfo method) {
-        return getHelperBlock(method, Level.Iteration, HelperType.SETUP);
-    }
-
-    public Collection<String> getIterationTearDowns(MethodInfo method) {
-        return getHelperBlock(method, Level.Iteration, HelperType.TEARDOWN);
-    }
-
-    public Collection<String> getRunSetups(MethodInfo method) {
-        return getHelperBlock(method, Level.Trial, HelperType.SETUP);
-    }
-
-    public Collection<String> getRunTearDowns(MethodInfo method) {
-        return getHelperBlock(method, Level.Trial, HelperType.TEARDOWN);
-    }
-
-    public List<String> getStateInitializers() {
-        Collection<StateObject> sos = cons(stateObjects);
-
-        List<String> result = new ArrayList<String>();
-
-        for (StateObject so : sos) {
-            if (so.scope != Scope.Benchmark) continue;
-
-            result.add("");
-            result.add("static volatile " + so.type + " " + so.fieldIdentifier + ";");
-            result.add("");
-            result.add(so.type + " tryInit_" + so.fieldIdentifier + "(InfraControl control, " + so.type + " val) throws Throwable {");
-            result.add("    synchronized(this.getClass()) {");
-            result.add("        if (" + so.fieldIdentifier + " == null) {");
-            result.add("            " + so.fieldIdentifier + " = val;");
-            result.add("        }");
-            result.add("        if (!" + so.fieldIdentifier + ".ready" + Level.Trial + ") {");
-            for (String paramName : so.getParamsLabels()) {
-                result.add("            " + so.fieldIdentifier + "." + paramName + " = " + so.getParamAccessor(paramName) + ";");
-            }
-            for (HelperMethodInvocation hmi : helpersByState.get(so)) {
-                if (hmi.helperLevel != Level.Trial) continue;
-                if (hmi.type != HelperType.SETUP) continue;
-                result.add("            " + so.fieldIdentifier + "." + hmi.method.getName() + "();");
-            }
-            result.add("            " + so.fieldIdentifier + ".ready" + Level.Trial + " = true;");
-            result.add("        }");
-            result.add("    }");
-            result.add("    return " + so.fieldIdentifier + ";");
-            result.add("}");
-        }
-
-        for (StateObject so : sos) {
-            if (so.scope != Scope.Thread) continue;
-
-            result.add("");
-            result.add(so.type + " " + so.fieldIdentifier + ";");
-            result.add("");
-            result.add(so.type + " tryInit_" + so.fieldIdentifier + "(InfraControl control, " + so.type + " val) throws Throwable {");
-            result.add("    if (" + so.fieldIdentifier + " == null) {");
-            for (String paramName : so.getParamsLabels()) {
-                result.add("                val." + paramName + " = " + so.getParamAccessor(paramName) + ";");
-            }
-            for (HelperMethodInvocation hmi : helpersByState.get(so)) {
-                if (hmi.helperLevel != Level.Trial) continue;
-                if (hmi.type != HelperType.SETUP) continue;
-                result.add("                val." + hmi.method.getName() + "();");
-            }
-            result.add("                " + "val.ready" + Level.Trial + " = true;");
-            result.add("          " + so.fieldIdentifier + " = val;");
-            result.add("    }");
-            result.add("    return " + so.fieldIdentifier + ";");
-            result.add("}");
-        }
-
-        for (StateObject so : sos) {
-            if (so.scope != Scope.Group) continue;
-
-            result.add("");
-            result.add("static java.util.Map<Integer, " + so.type + "> " + so.fieldIdentifier + "_map = java.util.Collections.synchronizedMap(new java.util.HashMap<Integer, " + so.type + ">());");
-            result.add("");
-            result.add(so.type + " tryInit_" + so.fieldIdentifier + "(InfraControl control, int groupId, " + so.type + " val) throws Throwable {");
-            result.add("    synchronized(this.getClass()) {");
-            result.add("        " + so.type + " local = " + so.fieldIdentifier + "_map.get(groupId);");
-            result.add("        if (local == null) {");
-            result.add("            " + so.fieldIdentifier + "_map.put(groupId, val);");
-            result.add("            local = val;");
-            result.add("        }");
-            result.add("        if (!local.ready" + Level.Trial + ") {");
-            for (String paramName : so.getParamsLabels()) {
-                result.add("            local." + paramName + " = " + so.getParamAccessor(paramName) + ";");
-            }
-            for (HelperMethodInvocation hmi : helpersByState.get(so)) {
-                if (hmi.helperLevel != Level.Trial) continue;
-                if (hmi.type != HelperType.SETUP) continue;
-                result.add("            local." + hmi.method.getName() + "();");
-            }
-            result.add("            " + "local.ready" + Level.Trial + " = true;");
-            result.add("            " + so.fieldIdentifier + "_map.put(groupId, val);");
-            result.add("        }");
-            result.add("        return local;");
-            result.add("    }");
-            result.add("}");
-        }
-        return result;
-    }
-
-    public Collection<String> getStateDestructors(MethodInfo method) {
-        Collection<StateObject> sos = cons(args.get(method.getName()), implicits.values());
-
-        List<String> result = new ArrayList<String>();
-        for (StateObject so : sos) {
-            if (so.scope != Scope.Benchmark) continue;
-            result.add("synchronized(this.getClass()) {");
-            result.add("    " + so.fieldIdentifier + " = null;");
-            result.add("}");
-        }
-
-        for (StateObject so : sos) {
-            if (so.scope != Scope.Thread) continue;
-            result.add("" + so.fieldIdentifier + " = null;");
-        }
-
-        for (StateObject so : sos) {
-            if (so.scope != Scope.Group) continue;
-            result.add("synchronized(this.getClass()) {");
-            result.add("    " + so.fieldIdentifier + "_map.remove(threadControl.group);");
-            result.add("}");
-        }
-        return result;
-    }
-
-    public List<String> getStateGetters(MethodInfo method) {
-        List<String> result = new ArrayList<String>();
-        for (StateObject so : cons(args.get(method.getName()), implicits.values(), getControls())) {
-            switch (so.scope) {
-                case Benchmark:
-                case Thread:
-                    result.add(so.type + " " + so.localIdentifier + " = tryInit_" + so.fieldIdentifier + "(control, new " + so.type + "());");
-                    break;
-                case Group:
-                    result.add(so.type + " " + so.localIdentifier + " = tryInit_" + so.fieldIdentifier + "(control, threadControl.group, new " + so.type + "());");
-                    break;
-                default:
-                    throw new IllegalStateException("Unhandled scope: " + so.scope);
-            }
-        }
-        return result;
-    }
-
-    public List<String> getStateOverrides() {
-        Set<String> visited = new HashSet<String>();
-
-        List<String> result = new ArrayList<String>();
-        for (StateObject so : cons(stateObjects)) {
-            if (!visited.add(so.userType)) continue;
-            result.add("static class " + so.type + "_B1 extends " + so.userType + " {");
-            padding(result, "b1");
-            result.add("}");
-            result.add("");
-            result.add("static class " + so.type + "_B2 extends " + so.type + "_B1 {");
-
-
-            for (Level level : Level.values()) {
-                result.add("    public volatile int setup" + level + "Mutex;");
-                result.add("    public volatile int tear" + level + "Mutex;");
-                result.add("    public final static AtomicIntegerFieldUpdater setup" + level + "MutexUpdater = " +
-                        "AtomicIntegerFieldUpdater.newUpdater(" + so.type + "_B2.class, \"setup" + level + "Mutex\");");
-                result.add("    public final static AtomicIntegerFieldUpdater tear" + level + "MutexUpdater = " +
-                        "AtomicIntegerFieldUpdater.newUpdater(" + so.type + "_B2.class, \"tear" + level + "Mutex\");");
-                result.add("");
-            }
-
-            switch (so.scope) {
-                case Benchmark:
-                case Group:
-                    for (Level level : Level.values()) {
-                        result.add("    public volatile boolean ready" + level + ";");
-                    }
-                    break;
-                case Thread:
-                    for (Level level : Level.values()) {
-                        result.add("    public boolean ready" + level + ";");
-                    }
-                    break;
-                default:
-                    throw new IllegalStateException("Unknown state scope: " + so.scope);
-            }
-
-            result.add("}");
-            result.add("");
-            result.add("static class " + so.type + "_B3 extends " + so.type + "_B2 {");
-            padding(result, "b3");
-            result.add("}");
-            result.add("");
-            result.add("static final class " + so.type + " extends " + so.type + "_B3 {");
-            result.add("}");
-            result.add("");
-        }
-        return result;
-    }
-
-    public static void padding(List<String> lines, String suffix) {
-        for (int p = 0; p < 16; p++) {
-            StringBuilder sb = new StringBuilder();
-            sb.append("    boolean jmh_").append(suffix).append("_pad_").append(p);
-            for (int q = 1; q < 16; q++) {
-                sb.append(", jmh_").append(suffix).append("_pad_").append(p).append("_").append(q);
-            }
-            sb.append(";");
-            lines.add(sb.toString());
-        }
-    }
-
-    public void clearArgs() {
-        args.clear();
-    }
-
-    public Collection<String> getFields() {
-        return Collections.emptyList();
-    }
-
-    private String collapseTypeName(String e) {
-        if (collapsedTypes.containsKey(e)) {
-            return collapsedTypes.get(e);
-        }
-
-        String[] strings = e.split("\\.");
-        String name = strings[strings.length - 1].toLowerCase();
-
-        String collapsedName = name + (collapsedIndex++) + "_";
-        collapsedTypes.put(e, collapsedName);
-        return collapsedName;
-    }
-
-    public StateObject getImplicit(String label) {
-        return implicits.get(label);
-    }
-
-    public Collection<StateObject> getControls() {
-        Collection<StateObject> s = new ArrayList<StateObject>();
-        for (StateObject so : cons(args.values())) {
-            if (so.userType.equals(Control.class.getName())) {
-                s.add(so);
-            }
-        }
-        return s;
-    }
-
-    public Collection<String> getAuxResultNames(MethodInfo method) {
-        return auxNames.get(method.getName());
-    }
-
-    public String getAuxResultAccessor(MethodInfo method, String name) {
-        return auxAccessors.get(method.getName() + name);
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APClassInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal.annotations;
-
-import org.openjdk.jmh.processor.internal.ClassInfo;
-import org.openjdk.jmh.processor.internal.FieldInfo;
-import org.openjdk.jmh.processor.internal.MethodInfo;
-
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.util.ElementFilter;
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-public class APClassInfo extends APMetadataInfo implements ClassInfo {
-
-    private final TypeElement el;
-
-    public APClassInfo(ProcessingEnvironment processEnv, TypeElement element) {
-        super(processEnv, element);
-        this.el = element;
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotation(Class<T> annClass) {
-        return el.getAnnotation(annClass);
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotationRecursive(Class<T> annClass) {
-        return AnnUtils.getAnnotationRecursive(el, annClass);
-    }
-
-    @Override
-    public Collection<MethodInfo> getConstructors() {
-        Collection<MethodInfo> mis = new ArrayList<MethodInfo>();
-        for (ExecutableElement e : ElementFilter.constructorsIn(el.getEnclosedElements())) {
-            mis.add(new APMethodInfo(processEnv, this, e));
-        }
-        return mis;
-    }
-
-    @Override
-    public boolean isNested() {
-        return el.getNestingKind().isNested();
-    }
-
-    @Override
-    public String getNestedName() {
-        return AnnUtils.getNestedName(el);
-    }
-
-    @Override
-    public String getQualifiedName() {
-        return el.getQualifiedName().toString();
-    }
-
-    @Override
-    public Collection<FieldInfo> getDeclaredFields() {
-        List<FieldInfo> ls = new ArrayList<FieldInfo>();
-        for (VariableElement e : ElementFilter.fieldsIn(el.getEnclosedElements())) {
-            ls.add(new APFieldInfo(processEnv, e));
-        }
-        return ls;
-    }
-
-    @Override
-    public Collection<FieldInfo> getFields() {
-        List<FieldInfo> ls = new ArrayList<FieldInfo>();
-        ls.addAll(getDeclaredFields());
-        for (ClassInfo cl : getSuperclasses()) {
-            ls.addAll(cl.getDeclaredFields());
-        }
-        return ls;
-    }
-
-    @Override
-    public Collection<MethodInfo> getDeclaredMethods() {
-        Collection<MethodInfo> mis = new ArrayList<MethodInfo>();
-        for (ExecutableElement e : ElementFilter.methodsIn(el.getEnclosedElements())) {
-            mis.add(new APMethodInfo(processEnv, this, e));
-        }
-        return mis;
-    }
-
-    @Override
-    public Collection<MethodInfo> getMethods() {
-        List<MethodInfo> ls = new ArrayList<MethodInfo>();
-        ls.addAll(getDeclaredMethods());
-        for (ClassInfo cl : getSuperclasses()) {
-            ls.addAll(cl.getDeclaredMethods());
-        }
-        return ls;
-    }
-
-    @Override
-    public String getPackageName() {
-        return AnnUtils.getPackageName(el);
-    }
-
-    @Override
-    public Collection<ClassInfo> getSuperclasses() {
-        List<ClassInfo> list = new ArrayList<ClassInfo>();
-        TypeElement walk = el;
-        while ((walk = (TypeElement) processEnv.getTypeUtils().asElement(walk.getSuperclass())) != null) {
-            list.add(new APClassInfo(processEnv, walk));
-        }
-        return list;
-    }
-
-    @Override
-    public boolean isAbstract() {
-        return el.getModifiers().contains(Modifier.ABSTRACT);
-    }
-
-    @Override
-    public boolean isPublic() {
-        return el.getModifiers().contains(Modifier.PUBLIC);
-    }
-
-    @Override
-    public boolean isStatic() {
-        return el.getModifiers().contains(Modifier.STATIC);
-    }
-
-    @Override
-    public boolean isStrictFP() {
-        return el.getModifiers().contains(Modifier.STRICTFP);
-    }
-
-    public String toString() {
-        return getQualifiedName();
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APFieldInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal.annotations;
-
-import org.openjdk.jmh.processor.internal.ClassInfo;
-import org.openjdk.jmh.processor.internal.FieldInfo;
-
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import java.lang.annotation.Annotation;
-
-public class APFieldInfo extends APMetadataInfo implements FieldInfo {
-
-    private final VariableElement ve;
-
-    public APFieldInfo(ProcessingEnvironment processEnv, VariableElement ve) {
-        super(processEnv, ve);
-        this.ve = ve;
-    }
-
-    @Override
-    public String getName() {
-        return ve.getSimpleName().toString();
-    }
-
-    @Override
-    public String getType() {
-        return ve.asType().toString();
-    }
-
-    @Override
-    public boolean isPublic() {
-        return ve.getModifiers().contains(Modifier.PUBLIC);
-    }
-
-    @Override
-    public boolean isStatic() {
-        return ve.getModifiers().contains(Modifier.STATIC);
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotation(Class<T> annClass) {
-        return ve.getAnnotation(annClass);
-    }
-
-    @Override
-    public ClassInfo getOwner() {
-        return new APClassInfo(processEnv, (TypeElement)ve.getEnclosingElement());
-    }
-
-    public String toString() {
-        return getType() + " " + getName();
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APMetadataInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal.annotations;
-
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Element;
-
-public class APMetadataInfo {
-
-    protected final ProcessingEnvironment processEnv;
-    private final Element element;
-
-    public APMetadataInfo(ProcessingEnvironment processEnv, Element element) {
-        this.processEnv = processEnv;
-        this.element = element;
-    }
-
-    public Element getElement() {
-        return element;
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APMethodInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal.annotations;
-
-import org.openjdk.jmh.processor.internal.ClassInfo;
-import org.openjdk.jmh.processor.internal.MethodInfo;
-import org.openjdk.jmh.processor.internal.ParameterInfo;
-
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.VariableElement;
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.Collection;
-
-public class APMethodInfo extends APMetadataInfo implements MethodInfo {
-
-    private final ClassInfo ci;
-    private final ExecutableElement el;
-
-    public APMethodInfo(ProcessingEnvironment processEnv, ClassInfo ci, ExecutableElement el) {
-        super(processEnv, el);
-        this.ci = ci;
-        this.el = el;
-    }
-
-    @Override
-    public ClassInfo getOwner() {
-        return ci;
-    }
-
-    @Override
-    public String getName() {
-        return el.getSimpleName().toString();
-    }
-
-    @Override
-    public String getReturnType() {
-        return el.getReturnType().toString();
-    }
-
-    @Override
-    public Collection<ParameterInfo> getParameters() {
-        Collection<ParameterInfo> pis = new ArrayList<ParameterInfo>();
-        for (VariableElement v : el.getParameters()) {
-            pis.add(new APParameterInfo(processEnv, v));
-        }
-        return pis;
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotation(Class<T> annClass) {
-        return el.getAnnotation(annClass);
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotationRecursive(Class<T> annClass) {
-        return AnnUtils.getAnnotationRecursive(el, annClass);
-    }
-
-    @Override
-    public boolean isPublic() {
-        return el.getModifiers().contains(Modifier.PUBLIC);
-    }
-
-    @Override
-    public boolean isAbstract() {
-        return el.getModifiers().contains(Modifier.ABSTRACT);
-    }
-
-    @Override
-    public boolean isSynchronized() {
-        return el.getModifiers().contains(Modifier.SYNCHRONIZED);
-    }
-
-    @Override
-    public boolean isStrictFP() {
-        return el.getModifiers().contains(Modifier.STRICTFP);
-    }
-
-    @Override
-    public String getQualifiedName() {
-        return ci.getQualifiedName() + "." + el.toString();
-    }
-
-    @Override
-    public int compareTo(MethodInfo o) {
-        return getQualifiedName().compareTo(o.getQualifiedName());
-    }
-
-    public String toString() {
-        return getOwner() + " " + getName() ;
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/APParameterInfo.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal.annotations;
-
-import org.openjdk.jmh.processor.internal.ClassInfo;
-import org.openjdk.jmh.processor.internal.ParameterInfo;
-
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-
-public class APParameterInfo extends APMetadataInfo implements ParameterInfo {
-    private final VariableElement ve;
-    private final TypeElement stateType;
-
-    public APParameterInfo(ProcessingEnvironment processEnv, VariableElement ve) {
-        super(processEnv, ve);
-        this.ve = ve;
-        this.stateType = (TypeElement) processEnv.getTypeUtils().asElement(ve.asType());
-    }
-
-    @Override
-    public ClassInfo getType() {
-        return new APClassInfo(processEnv, stateType);
-    }
-
-    public String toString() {
-        return getType() + " " + ve.getSimpleName();
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/AnnProcessGeneratorSource.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal.annotations;
-
-import org.openjdk.jmh.processor.internal.ClassInfo;
-import org.openjdk.jmh.processor.internal.GeneratorSource;
-import org.openjdk.jmh.processor.internal.MetadataInfo;
-
-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.TypeElement;
-import javax.lang.model.util.ElementFilter;
-import javax.tools.Diagnostic;
-import javax.tools.StandardLocation;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
-import java.util.TreeSet;
-
-public class AnnProcessGeneratorSource implements GeneratorSource {
-
-    private final RoundEnvironment roundEnv;
-    private final ProcessingEnvironment processingEnv;
-
-    public AnnProcessGeneratorSource(RoundEnvironment roundEnv, ProcessingEnvironment processingEnv) {
-        this.roundEnv = roundEnv;
-        this.processingEnv = processingEnv;
-    }
-
-    @Override
-    public Collection<ClassInfo> getClasses() {
-        // Need to do a few rollovers to find all classes that have @GMB-annotated methods in their
-        // subclasses. This is mostly due to some of the nested classes not discoverable at once,
-        // when we need to discover the enclosing class first. With the potentially non-zero nesting
-        // depth, we need to do a few rounds. Hopefully we will just do a single stride in most
-        // cases.
-
-        Collection<TypeElement> discoveredClasses = new TreeSet<TypeElement>(new Comparator<TypeElement>() {
-            @Override
-            public int compare(TypeElement o1, TypeElement o2) {
-                return o1.getQualifiedName().toString().compareTo(o2.getQualifiedName().toString());
-            }
-        });
-
-        // Walk around until convergence...
-
-        int lastSize = -1;
-        while (discoveredClasses.size() > lastSize) {
-            lastSize = discoveredClasses.size();
-            for (Element e : roundEnv.getRootElements()) {
-                if (e.getKind() != ElementKind.CLASS) continue;
-                TypeElement walk = (TypeElement) e;
-                do {
-                    discoveredClasses.add(walk);
-                    for (TypeElement nested : ElementFilter.typesIn(walk.getEnclosedElements())) {
-                        discoveredClasses.add(nested);
-                    }
-                } while ((walk = (TypeElement) processingEnv.getTypeUtils().asElement(walk.getSuperclass())) != null);
-            }
-        }
-
-        return convert(discoveredClasses);
-    }
-
-    protected Collection<ClassInfo> convert(Collection<TypeElement> els) {
-        List<ClassInfo> list = new ArrayList<ClassInfo>();
-        for (TypeElement el : els) {
-            list.add(new APClassInfo(processingEnv, el));
-        }
-        return list;
-    }
-
-    @Override
-    public ClassInfo resolveClass(String className) {
-        return new APClassInfo(processingEnv, processingEnv.getElementUtils().getTypeElement(className));
-    }
-
-    @Override
-    public Writer newResource(String path) throws IOException {
-        return processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", path).openWriter();
-    }
-
-    @Override
-    public Writer newFile(String objectName) throws IOException {
-        return processingEnv.getFiler().createSourceFile(objectName).openWriter();
-    }
-
-    @Override
-    public void printError(String message) {
-        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message);
-    }
-
-    @Override
-    public void printError(String message, MetadataInfo element) {
-        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, ((APMetadataInfo)element).getElement());
-    }
-
-    @Override
-    public void printError(String message, Throwable throwable) {
-        printError(message + " " + throwable);
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/annotations/AnnUtils.java	Wed Feb 26 17:06:12 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.processor.internal.annotations;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import java.lang.annotation.Annotation;
-
-public class AnnUtils {
-
-    /**
-     * Recursively get the annotation, until found, or reached the top of hierarchy.
-     * @param root where to start
-     * @param annotation what to look for
-     * @param <A> type of what we look for
-     * @return annotation
-     */
-    public static <A extends Annotation> A getAnnotationRecursive(Element root, Class<A> annotation) {
-        Element walk = root;
-        A result = null;
-        while (walk != null && (result = walk.getAnnotation(annotation)) == null) {
-            walk = walk.getEnclosingElement();
-        }
-        return result;
-    }
-
-    /**
-     * Get the package name part of a class
-     *
-     * @param clazz the subject
-     * @return the package name or "" if no package
-     */
-    public static String getPackageName(TypeElement clazz) {
-        Element walk = clazz;
-        while (walk.getKind() != ElementKind.PACKAGE) {
-            walk = walk.getEnclosingElement();
-        }
-        return ((PackageElement)walk).getQualifiedName().toString();
-    }
-
-    /**
-     * Get the class name along with any nested class names
-     * @param clazz the subject
-     * @return the synthetic class name in form of "parent1_parent2_classname"
-     */
-    public static String getNestedName(TypeElement clazz) {
-        String name = "";
-        Element walk = clazz;
-        while (walk.getKind() != ElementKind.PACKAGE) {
-            name = walk.getSimpleName().toString() + (name.isEmpty() ? "" : "_" + name);
-            walk = walk.getEnclosingElement();
-        }
-        return name.substring(0, name.length());
-    }
-}
--- a/jmh-core/src/main/resources/META-INF/services/javax.annotation.processing.Processor	Wed Feb 26 17:06:12 2014 +0400
+++ b/jmh-core/src/main/resources/META-INF/services/javax.annotation.processing.Processor	Wed Feb 26 17:18:42 2014 +0400
@@ -21,4 +21,4 @@
 #    or visit www.oracle.com if you need additional information or have any
 #    questions.
 #
-org.openjdk.jmh.processor.internal.GenerateMicroBenchmarkProcessor
+org.openjdk.jmh.generators.GenerateMicroBenchmarkProcessor