changeset 345:52ba6df72cb3

Remove args4j in favor of jopt-simple.
author shade
date Tue, 14 Jan 2014 14:27:56 +0400
parents 85b9e57dc794
children e8dec4cc827e
files jmh-core/THIRD-PARTY jmh-core/pom.xml jmh-core/src/main/java/org/openjdk/jmh/Main.java jmh-core/src/main/java/org/openjdk/jmh/annotations/Mode.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptionException.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/OptionFormatter.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/BenchmarkModeTypeOptionHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/BooleanOptionHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/ForkOptionHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/ProfilersOptionHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/ThreadCountsOptionHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/ThreadsOptionHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/TimeUnitOptionHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/TimeValueOptionHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/parameters/TimeValue.java jmh-core/src/test/java/org/openjdk/jmh/TestMain.java jmh-core/src/test/java/org/openjdk/jmh/runner/options/TestOptions.java
diffstat 18 files changed, 592 insertions(+), 961 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/THIRD-PARTY	Tue Jan 14 01:26:27 2014 +0400
+++ b/jmh-core/THIRD-PARTY	Tue Jan 14 14:27:56 2014 +0400
@@ -1,17 +1,29 @@
-Copyright (c) 2012 Args4j
+DO NOT TRANSLATE OR LOCALIZE.
+-----------------------------
 
-Permission is hereby granted, free of charge, to any person obtaining a copy of this
-software and associated documentation files (the "Software"), to deal in the Software
-without restriction, including without limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-to whom the Software is furnished to do so, subject to the following conditions:
+%% This notice is provided with respect to JOpt-Simple v4.6
 
-The above copyright notice and this permission notice shall be included in all copies
-or substantial portions of the Software.
+--- begin of LICENSE ---
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
\ No newline at end of file
+Copyright (c) SourceForge
+
+The MIT License Copyright (c) Permission is hereby granted, free of
+charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use, copy,
+modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+--- end of LICENSE ---
--- a/jmh-core/pom.xml	Tue Jan 14 01:26:27 2014 +0400
+++ b/jmh-core/pom.xml	Tue Jan 14 14:27:56 2014 +0400
@@ -58,9 +58,9 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>args4j</groupId>
-            <artifactId>args4j</artifactId>
-            <version>2.0.16</version>
+            <groupId>net.sf.jopt-simple</groupId>
+            <artifactId>jopt-simple</artifactId>
+            <version>4.6</version>
         </dependency>
     </dependencies>
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/Main.java	Tue Jan 14 01:26:27 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/Main.java	Tue Jan 14 14:27:56 2014 +0400
@@ -24,13 +24,13 @@
  */
 package org.openjdk.jmh;
 
-import org.kohsuke.args4j.CmdLineException;
-import org.openjdk.jmh.output.results.ResultFormatType;
-import org.openjdk.jmh.profile.ProfilerFactory;
 import org.openjdk.jmh.runner.Runner;
 import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.CommandLineOptionException;
 import org.openjdk.jmh.runner.options.CommandLineOptions;
 
+import java.io.IOException;
+
 /**
  * Main program entry point
  *
@@ -44,66 +44,39 @@
      * @param argv Command line arguments
      */
     public static void main(String[] argv) {
-        CommandLineOptions cmdOptions = CommandLineOptions.newInstance();
+        try {
+            CommandLineOptions cmdOptions = new CommandLineOptions(argv);
 
-        try {
-            cmdOptions.parseArguments(argv);
+            Runner runner = new Runner(cmdOptions);
 
-            if (cmdOptions.shouldListResultFormats()) {
-                StringBuilder sb = new StringBuilder();
-
-                for (ResultFormatType f : ResultFormatType.values()) {
-                    sb.append(f.toString().toLowerCase());
-                    sb.append(", ");
-                }
-                sb.setLength(sb.length() - 2);
-
-                System.out.println("Available formats: " + sb.toString());
+            if (cmdOptions.shouldHelp()) {
+                cmdOptions.showHelp();
                 return;
             }
 
-            // list available profilers?
-            if (cmdOptions.shouldListProfilers()) {
-                StringBuilder sb = new StringBuilder();
-                for (String s : ProfilerFactory.getAvailableProfilers()) {
-                    if (ProfilerFactory.isSupported(s)) {
-                        sb.append(String.format("%10s: %s\n", s, ProfilerFactory.getDescription(s)));
-                    }
-                }
-                if (!sb.toString().isEmpty()) {
-                    System.out.println("Supported profilers:\n" + sb.toString());
-                }
-
-                sb = new StringBuilder();
-                for (String s : ProfilerFactory.getAvailableProfilers()) {
-                    if (!ProfilerFactory.isSupported(s)) {
-                        sb.append(String.format("%10s: %s\n", s, ProfilerFactory.getDescription(s)));
-                    }
-                }
-
-                if (!sb.toString().isEmpty()) {
-                    System.out.println("Unsupported profilers:\n" + sb.toString());
-                }
-                return;
-            }
-
-            if (cmdOptions.shouldHelp()) {
-                cmdOptions.printUsage("Displaying help");
-                return;
-            }
-
-            Runner runner = new Runner(cmdOptions);
-
             if (cmdOptions.shouldList()) {
                 runner.list();
                 return;
             }
 
+            if (cmdOptions.shouldListProfilers()) {
+                cmdOptions.listProfilers();
+                return;
+            }
+
+            if (cmdOptions.shouldListResultFormats()) {
+                cmdOptions.listResultFormats();
+                return;
+            }
+
             runner.run();
-        } catch (CmdLineException ex) {
-            cmdOptions.printUsage(ex.getMessage());
         } catch (RunnerException e) {
-            cmdOptions.printUsage(e.getMessage());
+            System.err.println(e.getMessage());
+        } catch (IOException e) {
+            System.err.println(e.getMessage());
+        } catch (CommandLineOptionException e) {
+            System.err.println("Error parsing command line:");
+            System.err.println(" " + e.getMessage());
         }
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/annotations/Mode.java	Tue Jan 14 01:26:27 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/annotations/Mode.java	Tue Jan 14 14:27:56 2014 +0400
@@ -109,10 +109,7 @@
     public static List<String> getKnown() {
         List<String> res = new ArrayList<String>();
         for (Mode type : Mode.values()) {
-            res.add(type.toString());
-        }
-        for (Mode type : Mode.values()) {
-            res.add(type.shortLabel());
+            res.add(type.toString() + "/" + type.shortLabel());
         }
         return res;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptionException.java	Tue Jan 14 14:27:56 2014 +0400
@@ -0,0 +1,36 @@
+/*
+ * 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.runner.options;
+
+public class CommandLineOptionException extends Exception {
+
+    public CommandLineOptionException(String message) {
+        super(message);
+    }
+
+    public CommandLineOptionException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java	Tue Jan 14 01:26:27 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java	Tue Jan 14 14:27:56 2014 +0400
@@ -24,25 +24,21 @@
  */
 package org.openjdk.jmh.runner.options;
 
-import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.Option;
+import joptsimple.OptionException;
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
 import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.Threads;
 import org.openjdk.jmh.output.results.ResultFormatType;
+import org.openjdk.jmh.profile.ProfilerFactory;
 import org.openjdk.jmh.profile.ProfilerType;
-import org.openjdk.jmh.runner.options.handlers.BenchmarkModeTypeOptionHandler;
-import org.openjdk.jmh.runner.options.handlers.BooleanOptionHandler;
-import org.openjdk.jmh.runner.options.handlers.ForkOptionHandler;
-import org.openjdk.jmh.runner.options.handlers.ProfilersOptionHandler;
-import org.openjdk.jmh.runner.options.handlers.ThreadCountsOptionHandler;
-import org.openjdk.jmh.runner.options.handlers.ThreadsOptionHandler;
-import org.openjdk.jmh.runner.options.handlers.TimeUnitOptionHandler;
-import org.openjdk.jmh.runner.options.handlers.TimeValueOptionHandler;
 import org.openjdk.jmh.runner.parameters.TimeValue;
 import org.openjdk.jmh.util.internal.Optional;
 
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -52,153 +48,372 @@
 import java.util.concurrent.TimeUnit;
 
 /**
- * Class that handles all the options and arguments specific to the harness JVM.
+ * Class that handles all the command line options.
  *
- * Boolean/boolean options getters name conventions:
- *   - method name is prefixed by "is" or "should" when the Option class gives exact answer
- *   - method name is prefixed by "get" when the method is just a getter and meaning of the option clarified somewhere else
- *
- * @author anders.astrand@oracle.com
- * @author sergey.kuksenko@oracle.com
+ * @author Anders Astrand
+ * @author Sergey Kuksenko
+ * @author Aleksey Shipilev
  */
 public class CommandLineOptions implements Options {
 
-        /*
-     *  Conventions for options processing (unless otherwise specified):
-     *  - int options:
-     *              negative value means unset
-     *  - Boolean options:
-     *              null means unset, TRUE/FALSE means true/false;
-     *              default values should be processed explicitly
-     *  - boolean options:
-     *              may be used only for options with false default value
-     *              may be set to true in cmdLine, can't be set to false explicitly
-     *
-     */
+    private final Optional<Integer> iterations;
+    private final Optional<TimeValue> runTime;
+    private final Optional<Integer> warmupIterations;
+    private final Optional<TimeValue> warmupTime;
+    private final List<Mode> benchMode = new ArrayList<Mode>();
+    private final Optional<Integer> threads;
+    private final List<Integer> threadGroups = new ArrayList<Integer>();
+    private final Optional<Boolean> synchIterations;
+    private final Optional<Boolean> gcEachIteration;
+    private final Optional<VerboseMode> verbose;
+    private final Optional<Boolean> failOnError;
+    private final Set<ProfilerType> profilers = EnumSet.noneOf(ProfilerType.class);
+    private final Optional<TimeUnit> timeUnit;
+    private final List<String> regexps = new ArrayList<String>();
+    private final Optional<Integer> fork;
+    private final Optional<Integer> warmupFork;
+    private final Optional<String> output;
+    private final Optional<String> result;
+    private final Optional<ResultFormatType> resultFormat;
+    private final Optional<String> jvm;
+    private final Optional<String> jvmArgs;
+    private final Optional<String> jvmClassPath;
+    private final List<String> excludes = new ArrayList<String>();
+    private final Optional<WarmupMode> warmupMode;
+    private final List<String> warmupMicros = new ArrayList<String>();
+    private final boolean list;
+    private final boolean listResultFormats;
+    private final boolean help;
+    private final boolean listProfilers;
 
-    @Option(name = "-i", aliases = {"--iterations"}, metaVar = "INT", usage = "Number of iterations.")
-    protected Integer iterations;
+    private final OptionParser parser;
 
-    @Option(name = "-r", aliases = {"--runtime"}, metaVar = "TIME", usage = "Run time for each iteration. Examples: 100s, 200ms", handler = TimeValueOptionHandler.class)
-    protected TimeValue runTime;
+    public CommandLineOptions(String... argv) throws CommandLineOptionException {
+        parser = new OptionParser();
+        parser.formatHelpWith(new OptionFormatter());
 
-    @Option(name = "-wi", aliases = {"--warmupiterations"}, metaVar = "INT", usage = "Number of warmup iterations to run.")
-    protected Integer warmupIterations;
+        OptionSpec<Integer> optMeasureCount = parser.accepts("i", "Number of measurement iterations to do.")
+                .withRequiredArg().ofType(Integer.class).describedAs("int");
 
-    @Option(name = "-w", aliases = {"--warmup"}, metaVar = "TIME", usage = "Run time for warmup iterations. Result not used when calculating score. Examples 100s, 200ms", handler = TimeValueOptionHandler.class)
-    protected TimeValue warmupTime;
+        OptionSpec<String> optMeasureTime = parser.accepts("r", "Time to spend at each measurement iteration.")
+                .withRequiredArg().ofType(String.class).describedAs("time");
 
-    @Option(name = "-bm", aliases = {"--mode"}, multiValued = false, metaVar = "MODE", usage = "Benchmark mode", handler = BenchmarkModeTypeOptionHandler.class)
-    protected List<Mode> benchMode = new ArrayList<Mode>();
+        OptionSpec<Integer> optWarmupCount = parser.accepts("wi", "Number of warmup iterations to do.")
+                .withRequiredArg().ofType(Integer.class).describedAs("int");
 
-    @Option(name = "-t", aliases = {"--threads"}, usage = "Number of threads to run the microbenchmark with. Special value \"max\" will use Runtime.availableProcessors()", handler = ThreadsOptionHandler.class)
-    protected Integer threads;
+        OptionSpec<String> optWarmupTime = parser.accepts("w", "Time to spend at each warmup iteration.")
+                .withRequiredArg().ofType(String.class).describedAs("time");
 
-    @Option(name = "-tg", aliases = {"--threadGroups"}, usage = "Thread group distribution", handler = ThreadCountsOptionHandler.class)
-    protected List<Integer> threadGroups = new ArrayList<Integer>();
+        OptionSpec<String> optThreads = parser.accepts("t", "Number of worker threads to run with.")
+                .withRequiredArg().ofType(String.class).describedAs("int");
 
-    @Option(name = "-si", aliases = {"--synciterations"}, usage = "Should the harness continue to load each thread with work untill all threads are done with their measured work?", handler = BooleanOptionHandler.class)
-    protected Boolean synchIterations;
+        OptionSpec<String> optBenchmarkMode = parser.accepts("bm", "Benchmark mode. Available modes are: " + Mode.getKnown())
+                .withRequiredArg().ofType(String.class).withValuesSeparatedBy(',').describedAs("mode");
 
-    @Option(name = "-gc", usage = "Should do System.gc() between iterations?", handler = BooleanOptionHandler.class)
-    protected Boolean gcEachIteration;
+        OptionSpec<Boolean> optSyncIters = parser.accepts("si", "Synchronize iterations?")
+                .withOptionalArg().ofType(Boolean.class).describedAs("bool");
 
-    @Option(name = "-v", aliases = {"--verbosity"}, metaVar = "LEVEL", usage = "Verbosity mode: (silent, normal, extra)")
-    protected VerboseMode verbose;
+        OptionSpec<Boolean> optGC = parser.accepts("gc", "Should JMH force GC between iterations?")
+                .withOptionalArg().ofType(Boolean.class).describedAs("bool");
 
-    @Option(name = "-foe", usage = "Fail the harness on benchmark erro?", handler = BooleanOptionHandler.class)
-    protected Boolean failOnError;
+        OptionSpec<Boolean> optFOE = parser.accepts("foe", "Should JMH fail immediately if any benchmark had" +
+                " experienced the unrecoverable error?")
+                .withOptionalArg().ofType(Boolean.class).describedAs("bool");
 
-    @Option(name = "-prof", aliases = {"--useprofiler"}, multiValued = false, usage = "Use profilers for collecting additional info, use --listProfilers to list available profilers", handler = ProfilersOptionHandler.class)
-    protected Set<ProfilerType> profilers = EnumSet.noneOf(ProfilerType.class);
+        OptionSpec<String> optVerboseMode = parser.accepts("v", "Verbosity mode. Available modes are: " + Arrays.toString(VerboseMode.values()))
+                .withRequiredArg().ofType(String.class).describedAs("mode");
 
-    @Option(name = "-tu", aliases = {"--timeunit"}, usage = "Output time unit. Available values: m, s, ms, us, ns", handler = TimeUnitOptionHandler.class)
-    protected TimeUnit timeUnit;
+        OptionSpec<String> optArgs = parser.nonOptions("Benchmarks to run (regexp+).")
+                .describedAs("regexp+");
 
-    // test selection options
-    @Argument(metaVar = "REGEXP", usage = "Microbenchmarks to run. Regexp filtering out classes or methods which are MicroBenchmarks.")
-    protected List<String> regexps = new ArrayList<String>();
+        OptionSpec<Integer> optForks = parser.accepts("f", "How many times to forks a single benchmark." +
+                " Use 0 to disable forking altogether (WARNING: disabling forking may have detrimental" +
+                " impact on benchmark and infrastructure reliability, you might want to use different" +
+                " warmup mode instead).")
+                .withOptionalArg().ofType(Integer.class).describedAs("int");
 
-    // micro options
+        OptionSpec<Integer> optWarmupForks = parser.accepts("wf", "How many warmup forks to make " +
+                "for a single benchmark. 0 to disable warmup forks.")
+                .withRequiredArg().ofType(Integer.class).describedAs("int");
 
-    @Option(name = "-f", aliases = {"--fork"}, metaVar = "{ INT }", usage = "Start each benchmark in new JVM, forking from the same JDK unless --jvm is set. Optional parameter specifies number of times harness should fork. Zero forks means \"no fork\", also \"false\" is accepted", handler = ForkOptionHandler.class)
-    protected Integer fork;
+        OptionSpec<String> optOutput = parser.accepts("o", "Redirect human-readable output to file.")
+                .withRequiredArg().ofType(String.class).describedAs("filename");
 
-    @Option(name = "-wf", aliases = {"--warmupfork"}, metaVar = "{ INT }", usage = "Number of warmup fork executions. (warmup fork execution results are ignored).")
-    protected Integer warmupFork;
+        OptionSpec<String> optOutputResults = parser.accepts("rff", "Write results to given file.")
+                .withRequiredArg().ofType(String.class).describedAs("filename");
 
-    @Option(name = "-o", aliases = {"--output"}, metaVar = "FILE", usage = "Redirect output to FILE")
-    protected String output;
+        OptionSpec<String> optProfilers = parser.accepts("prof", "Use profilers to collect additional data." +
+                " See the list of available profilers first.")
+                .withRequiredArg().withValuesSeparatedBy(',').ofType(String.class).describedAs("profiler+");
 
-    @Option(name = "-rff", aliases = {"--result"}, metaVar = "FILE", usage = "Redirect results to FILE")
-    protected String result;
+        OptionSpec<Integer> optThreadGroups = parser.accepts("tg", "Override thread group distribution for asymmetric benchmarks.")
+                .withRequiredArg().withValuesSeparatedBy(',').ofType(Integer.class).describedAs("int+");
 
-    @Option(name = "-rf", aliases = {"--resultformat"}, metaVar = "FORMAT", usage = "Format to use for results, use --listResultFormats to list available formats")
-    protected ResultFormatType resultFormat;
+        OptionSpec<String> optJvm = parser.accepts("jvm", "Custom JVM to use when forking.")
+                .withRequiredArg().ofType(String.class).describedAs("string");
 
-    @Option(name = "--jvm", metaVar = "JVM", usage = "Custom JVM to use with fork.")
-    protected String jvm;
+        OptionSpec<String> optJvmArgs = parser.accepts("jvmArgs", "Custom JVM args to use when forking.")
+                .withRequiredArg().ofType(String.class).describedAs("string");
 
-    @Option(name = "--jvmargs", metaVar = "JVMARGS", usage = "Custom JVM arguments for --jvm, default is to use parent process's arguments")
-    protected String jvmArgs;
+        OptionSpec<String> optJvmCP = parser.accepts("jvmClasspath", "Custom JVM classpath to use when forking.")
+                .withRequiredArg().ofType(String.class).describedAs("string");
 
-    @Option(name = "--jvmclasspath", metaVar = "CLASSPATH", usage = "Custom classpath for --jvm, default is to use parent process's classpath")
-    protected String jvmClassPath;
+        OptionSpec<String> optTU = parser.accepts("tu", "Output time unit. Available time units are: [m, s, ms, us, ns].")
+                .withRequiredArg().ofType(String.class).describedAs("TU");
 
-    @Option(name = "-e", aliases = {"--exclude"}, multiValued = true, metaVar = "REGEXP", usage = "Microbenchmarks to exclude. Regexp filtering out classes or methods which are MicroBenchmarks.")
-    protected List<String> excludes = new ArrayList<String>();
+        OptionSpec<String> optResultFormat = parser.accepts("rf", "Result format type. See the list of available result formats first.")
+                .withRequiredArg().ofType(String.class).describedAs("type");
 
-    @Option(name = "-wm", aliases = {"--warmupmode"}, usage = "Warmup mode for warming up selected micro benchmarks. Warmup modes are: BULK (before all benchmarks), INDI (before each benchmark), BULK_INDI (both)")
-    protected WarmupMode warmupMode;
+        OptionSpec<String> optWarmupMode = parser.accepts("wm", "Warmup mode for warming up selected benchmarks. Warmup modes are: " + Arrays.toString(WarmupMode.values()) + ".")
+                .withRequiredArg().ofType(String.class).describedAs("mode");
 
-    @Option(name = "-wmb", aliases = {"--warmupmicrobenchmarks"}, multiValued = true, metaVar = "REGEXP", usage = "Microbenchmarks to run for warmup before running any other benchmarks. These micros may be different from the target micros to warm up the harness or other parts of the JVM prior to running the target micro benchmarks. Regexp filtering out classes or methods which are MicroBenchmarks.")
-    protected List<String> warmupMicros = new ArrayList<String>();
+        OptionSpec<String> optExcludes = parser.accepts("e", "Benchmarks to exclude from the run.")
+                .withRequiredArg().withValuesSeparatedBy(',').ofType(String.class).describedAs("regexp+");
 
-    // show something options
-    @Option(name = "-l", aliases = {"--list"}, usage = "List available microbenchmarks and exit. Filter using available regexps.")
-    protected boolean list = false;
+        OptionSpec<String> optWarmupBenchmarks = parser.accepts("wmb", "Warmup benchmarks to include in the run " +
+                "in addition to already selected. JMH will not measure these benchmarks, but only use them" +
+                " for the warmup.")
+                .withRequiredArg().withValuesSeparatedBy(',').ofType(String.class).describedAs("regexp+");
 
-    @Option(name = "--listResultFormats", usage = "List available result formats")
-    protected boolean listResultFormats;
+        parser.accepts("l", "List matching benchmarks and exit.");
+        parser.accepts("lrf", "List result formats.");
+        parser.accepts("lprof", "List profilers.");
+        parser.accepts("h", "Display help.");
 
-    @Option(name = "-h", aliases = {"--help"}, usage = "Display help")
-    protected boolean help = false;
+        try {
+            OptionSet set = parser.parse(argv);
 
-    @Option(name = "--listProfilers", usage = "List available profilers")
-    protected boolean listProfilers;
+            if (set.has(optExcludes)) {
+                excludes.addAll(optExcludes.values(set));
+            }
 
-    /**
-     * Kawaguchi's parser
-     */
-    private transient CmdLineParser parser;
+            if (set.has(optWarmupBenchmarks)) {
+                warmupMicros.addAll(optWarmupBenchmarks.values(set));
+            }
 
-    public static CommandLineOptions newInstance() {
-        CommandLineOptions opts = new CommandLineOptions();
-        opts.parser = new CmdLineParser(opts);
-        return opts;
+            if (set.has(optTU)) {
+                String va = optTU.value(set);
+                TimeUnit tu;
+                if (va.equalsIgnoreCase("ns")) {
+                    tu = TimeUnit.NANOSECONDS;
+                } else if (va.equalsIgnoreCase("us")) {
+                    tu = TimeUnit.MICROSECONDS;
+                } else if (va.equalsIgnoreCase("ms")) {
+                    tu = TimeUnit.MILLISECONDS;
+                } else if (va.equalsIgnoreCase("s")) {
+                    tu = TimeUnit.SECONDS;
+                } else if (va.equalsIgnoreCase("m")) {
+                    tu = TimeUnit.MINUTES;
+                } else if (va.equalsIgnoreCase("h")) {
+                    tu = TimeUnit.HOURS;
+                } else {
+                    throw new CommandLineOptionException("Unknown time unit: " + va);
+                }
+                timeUnit = Optional.of(tu);
+            } else {
+                timeUnit = Optional.none();
+            }
+
+            if (set.has(optWarmupMode)) {
+                try {
+                    warmupMode = Optional.of(WarmupMode.valueOf(optWarmupMode.value(set)));
+                } catch (IllegalArgumentException iae) {
+                    throw new CommandLineOptionException(iae.getMessage(), iae);
+                }
+            } else {
+                warmupMode = Optional.none();
+            }
+
+            if (set.has(optResultFormat)) {
+                try {
+                    resultFormat = Optional.of(ResultFormatType.valueOf(optResultFormat.value(set)));
+                } catch (IllegalArgumentException iae) {
+                    throw new CommandLineOptionException(iae.getMessage(), iae);
+                }
+            } else {
+                resultFormat = Optional.none();
+            }
+
+            help = set.has("h");
+            list = set.has("l");
+            listResultFormats = set.has("lrf");
+            listProfilers = set.has("lprof");
+
+            iterations = Optional.eitherOf(optMeasureCount.value(set));
+
+            if (set.has(optMeasureTime)) {
+                String value = optMeasureTime.value(set);
+                try {
+                    runTime = Optional.of(TimeValue.fromString(value));
+                } catch (IllegalArgumentException iae) {
+                    throw new CommandLineOptionException(iae.getMessage(), iae);
+                }
+            } else {
+                runTime = Optional.none();
+            }
+
+            warmupIterations = Optional.eitherOf(optWarmupCount.value(set));
+
+            if (set.has(optWarmupTime)) {
+                String value = optWarmupTime.value(set);
+                try {
+                    warmupTime = Optional.of(TimeValue.fromString(value));
+                } catch (IllegalArgumentException iae) {
+                    throw new CommandLineOptionException(iae.getMessage(), iae);
+                }
+            } else {
+                warmupTime = Optional.none();
+            }
+
+            if (set.has(optThreads)) {
+                String v = optThreads.value(set);
+                if (v.equalsIgnoreCase("max")) {
+                    threads = Optional.of(Threads.MAX);
+                } else {
+                    try {
+                        threads = Optional.of(Integer.valueOf(v));
+                    } catch (IllegalArgumentException iae) {
+                        throw new CommandLineOptionException(iae.getMessage(), iae);
+                    }
+                }
+            } else {
+                threads = Optional.none();
+            }
+
+            if (set.has(optBenchmarkMode)) {
+                try {
+                    List<Mode> modes = new ArrayList<Mode>();
+                    for (String m : optBenchmarkMode.values(set)) {
+                        modes.add(Mode.deepValueOf(m));
+                    }
+                    benchMode.addAll(modes);
+                } catch (IllegalArgumentException iae) {
+                    throw new CommandLineOptionException(iae.getMessage(), iae);
+                }
+            }
+
+            if (set.has(optSyncIters)) {
+                if (set.hasArgument(optSyncIters)) {
+                    synchIterations = Optional.of(optSyncIters.value(set));
+                } else {
+                    synchIterations = Optional.of(true);
+                }
+            } else {
+                synchIterations = Optional.none();
+            }
+
+            if (set.has(optGC)) {
+                if (set.hasArgument(optGC)) {
+                    gcEachIteration = Optional.of(optGC.value(set));
+                } else {
+                    gcEachIteration = Optional.of(true);
+                }
+            } else {
+                gcEachIteration = Optional.none();
+            }
+
+            if (set.has(optFOE)) {
+                if (set.hasArgument(optFOE)) {
+                    failOnError = Optional.of(optFOE.value(set));
+                } else {
+                    failOnError = Optional.of(true);
+                }
+            } else {
+                failOnError = Optional.none();
+            }
+
+            if (set.has(optVerboseMode)) {
+                try {
+                    if (set.hasArgument(optVerboseMode)) {
+                        verbose = Optional.of(VerboseMode.valueOf(set.valueOf(optVerboseMode).toUpperCase()));
+                    } else {
+                        verbose = Optional.of(VerboseMode.EXTRA);
+                    }
+                } catch (IllegalArgumentException iae) {
+                    throw new CommandLineOptionException(iae.getMessage(), iae);
+                }
+            } else {
+                verbose = Optional.none();
+            }
+
+            regexps.addAll(set.valuesOf(optArgs));
+
+            if (set.has(optForks)) {
+                if (set.hasArgument(optForks)) {
+                    fork = Optional.of(optForks.value(set));
+                } else {
+                    fork = Optional.of(1);
+                }
+            } else {
+                fork = Optional.none();
+            }
+
+            warmupFork = Optional.eitherOf(optWarmupForks.value(set));
+            output = Optional.eitherOf(optOutput.value(set));
+            result = Optional.eitherOf(optOutputResults.value(set));
+
+            if (set.has(optProfilers)) {
+                try {
+                    Set<ProfilerType> profs = EnumSet.noneOf(ProfilerType.class);
+                    for (String m : optProfilers.values(set)) {
+                        profs.add(ProfilerType.valueOf(m.toUpperCase()));
+                    }
+                    profilers.addAll(profs);
+                } catch (IllegalArgumentException iae) {
+                    throw new CommandLineOptionException(iae.getMessage(), iae);
+                }
+            }
+
+            if (set.has(optThreadGroups)) {
+                threadGroups.addAll(set.valuesOf(optThreadGroups));
+            }
+
+            jvm = Optional.eitherOf(optJvm.value(set));
+            jvmArgs = Optional.eitherOf(optJvmArgs.value(set));
+            jvmClassPath = Optional.eitherOf(optJvmCP.value(set));
+
+        } catch (OptionException e) {
+            throw new CommandLineOptionException(e.getMessage(), e);
+        }
     }
 
-    protected CommandLineOptions() {
+    public void showHelp() throws IOException {
+        parser.printHelpOn(System.err);
     }
 
-    /**
-     * Print Usage
-     *
-     * @param message Message to print at the top
-     */
-    public void printUsage(String message) {
-        System.err.println(message);
-        System.err.println("Usage: [options] [benchmark regexp]*");
-        parser.printUsage(System.err);
+    public void listProfilers() {
+        StringBuilder sb = new StringBuilder();
+        for (String s : ProfilerFactory.getAvailableProfilers()) {
+            if (ProfilerFactory.isSupported(s)) {
+                sb.append(String.format("%10s: %s\n", s, ProfilerFactory.getDescription(s)));
+            }
+        }
+        if (!sb.toString().isEmpty()) {
+            System.out.println("Supported profilers:\n" + sb.toString());
+        }
+
+        sb = new StringBuilder();
+        for (String s : ProfilerFactory.getAvailableProfilers()) {
+            if (!ProfilerFactory.isSupported(s)) {
+                sb.append(String.format("%10s: %s\n", s, ProfilerFactory.getDescription(s)));
+            }
+        }
+
+        if (!sb.toString().isEmpty()) {
+            System.out.println("Unsupported profilers:\n" + sb.toString());
+        }
     }
 
-    /**
-     * parse arguments and set fields in the Options instance
-     *
-     * @throws CmdLineException
-     */
-    public void parseArguments(String[] argv) throws CmdLineException {
-        parser.parseArgument(argv);
+    public void listResultFormats() {
+        StringBuilder sb = new StringBuilder();
+
+        for (ResultFormatType f : ResultFormatType.values()) {
+            sb.append(f.toString().toLowerCase());
+            sb.append(", ");
+        }
+        sb.setLength(sb.length() - 2);
+
+        System.out.println("Available formats: " + sb.toString());
     }
 
     /**
@@ -208,7 +423,7 @@
      */
     @Override
     public Optional<WarmupMode> getWarmupMode() {
-        return Optional.eitherOf(warmupMode);
+        return warmupMode;
     }
 
     /**
@@ -243,11 +458,7 @@
      */
     @Override
     public List<String> getWarmupIncludes() {
-        if (warmupMicros == null) {
-            return Collections.emptyList();
-        } else {
-            return warmupMicros;
-        }
+        return warmupMicros;
     }
 
     /**
@@ -266,7 +477,7 @@
      */
     @Override
     public Optional<String> getJvm() {
-        return Optional.eitherOf(jvm);
+        return jvm;
     }
 
     /**
@@ -276,7 +487,7 @@
      */
     @Override
     public Optional<String> getJvmArgs() {
-        return Optional.eitherOf(jvmArgs);
+        return jvmArgs;
     }
 
     /**
@@ -286,7 +497,7 @@
      */
     @Override
     public Optional<String> getJvmClassPath() {
-        return Optional.eitherOf(jvmClassPath);
+        return jvmClassPath;
     }
 
     /**
@@ -296,7 +507,7 @@
      */
     @Override
     public Optional<Integer> getForkCount() {
-        return Optional.eitherOf(fork);
+        return fork;
     }
 
     /**
@@ -306,7 +517,7 @@
      */
     @Override
     public Optional<Integer> getWarmupForkCount() {
-        return Optional.eitherOf(warmupFork);
+        return warmupFork;
     }
 
     /**
@@ -316,17 +527,17 @@
      */
     @Override
     public Optional<String> getOutput() {
-        return Optional.eitherOf(output);
+        return output;
     }
 
     @Override
     public Optional<ResultFormatType> getResultFormat() {
-        return Optional.eitherOf(resultFormat);
+        return resultFormat;
     }
 
     @Override
     public Optional<String> getResult() {
-        return Optional.eitherOf(result);
+        return result;
     }
 
     public boolean shouldListResultFormats() {
@@ -359,7 +570,7 @@
      */
     @Override
     public Optional<Integer> getMeasurementIterations() {
-        return Optional.eitherOf(iterations);
+        return iterations;
     }
 
     /**
@@ -369,7 +580,7 @@
      */
     @Override
     public Optional<TimeValue> getMeasurementTime() {
-        return Optional.eitherOf(runTime);
+        return runTime;
     }
 
     /**
@@ -379,7 +590,7 @@
      */
     @Override
     public Optional<TimeValue> getWarmupTime() {
-        return Optional.eitherOf(warmupTime);
+        return warmupTime;
     }
 
     /**
@@ -389,7 +600,7 @@
      */
     @Override
     public Optional<Integer> getWarmupIterations() {
-        return Optional.eitherOf(warmupIterations);
+        return warmupIterations;
     }
 
     /**
@@ -399,7 +610,7 @@
      */
     @Override
     public Optional<Integer> getThreads() {
-        return Optional.eitherOf(threads);
+        return threads;
     }
 
     @Override
@@ -422,7 +633,7 @@
      */
     @Override
     public Optional<Boolean> shouldDoGC() {
-        return Optional.eitherOf(gcEachIteration);
+        return gcEachIteration;
     }
 
     /**
@@ -432,7 +643,7 @@
      */
     @Override
     public Optional<Boolean> shouldSyncIterations() {
-        return Optional.eitherOf(synchIterations);
+        return synchIterations;
     }
 
     /**
@@ -442,7 +653,7 @@
      */
     @Override
     public Optional<VerboseMode> verbosity() {
-        return Optional.eitherOf(verbose);
+        return verbose;
     }
 
     /**
@@ -452,7 +663,7 @@
      */
     @Override
     public Optional<TimeUnit> getTimeUnit() {
-        return Optional.eitherOf(timeUnit);
+        return timeUnit;
     }
 
     /**
@@ -461,7 +672,7 @@
      */
     @Override
     public Optional<Boolean> shouldFailOnError() {
-        return Optional.eitherOf(failOnError);
+        return failOnError;
     }
 
     /**
@@ -478,5 +689,4 @@
         return new HashSet<Mode>(benchMode);
     }
 
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/OptionFormatter.java	Tue Jan 14 14:27:56 2014 +0400
@@ -0,0 +1,112 @@
+/*
+ * 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.runner.options;
+
+import joptsimple.HelpFormatter;
+import joptsimple.OptionDescriptor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+public class OptionFormatter implements HelpFormatter {
+
+    public String format(Map<String, ? extends OptionDescriptor> options) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Usage: java -jar ... [regexp*] [options]");
+        sb.append("\n");
+        sb.append(" [opt] means optional argument.\n");
+        sb.append(" <opt> means required argument.\n");
+        sb.append(" \"+\" means comma-separated list of values.\n");
+        sb.append(" \"time\" arguments accept time suffixes, like \"100ms\".\n");
+        sb.append("\n");
+        for (OptionDescriptor each : options.values()) {
+            sb.append(lineFor(each));
+        }
+
+        return sb.toString();
+    }
+
+    private Collection<String> rewrap(String lines) {
+        Collection<String> result = new ArrayList<String>();
+        String[] words = lines.split("[ \n]");
+        String line = "";
+        int cols = 0;
+        for (String w : words) {
+            cols += w.length();
+            line += w + " ";
+            if (cols > 40) {
+                result.add(line);
+                line = "";
+                cols = 0;
+            }
+        }
+        result.add(line);
+        return result;
+    }
+
+    private String lineFor(OptionDescriptor d) {
+        StringBuilder line = new StringBuilder();
+
+        StringBuilder o = new StringBuilder();
+        o.append("  ");
+        for (String str : d.options()) {
+            if (!d.representsNonOptions()) {
+                o.append("-");
+            }
+            o.append(str);
+            if (d.acceptsArguments()) {
+                o.append(" ");
+                if (d.requiresArgument()) {
+                    o.append("<");
+                } else {
+                    o.append("[");
+                }
+                o.append(d.argumentDescription());
+                if (d.requiresArgument()) {
+                    o.append(">");
+                } else {
+                    o.append("]");
+                }
+            }
+        }
+
+        line.append(String.format("%-30s", o.toString()));
+        boolean first = true;
+        for (String l : rewrap(d.description())) {
+            if (first) {
+                first = false;
+            } else {
+                line.append("\n");
+                line.append(String.format("%-30s", ""));
+            }
+            line.append(l);
+        }
+
+        line.append(System.getProperty("line.separator"));
+        return line.toString();
+    }
+
+}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/BenchmarkModeTypeOptionHandler.java	Tue Jan 14 01:26:27 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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.runner.options.handlers;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.OptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
-import org.openjdk.jmh.annotations.Mode;
-
-/**
- * OptionHandler for Mode options.
- */
-public class BenchmarkModeTypeOptionHandler extends OptionHandler<Mode> {
-
-    /**
-     * Constructor
-     *
-     * @param parser CmdLineParser parent
-     * @param option Run-time copy of the Option
-     * @param setter Setter to feed back the value
-     */
-    public BenchmarkModeTypeOptionHandler(CmdLineParser parser, OptionDef option, Setter<Mode> setter) {
-        super(parser, option, setter);
-    }
-
-    @Override
-    public int parseArguments(Parameters params) throws CmdLineException {
-        if (params.size() > 0) {
-            String param = params.getParameter(0);
-            try {
-                String[] modes = param.split(",");
-                for (String c : modes) {
-                    Mode value = Mode.deepValueOf(c);
-                    setter.addValue(value);
-                }
-                return 1;
-            } catch (Exception e) {
-                throw new CmdLineException(owner, e.getMessage());
-            }
-        }
-        return 0;
-    }
-
-    @Override
-    public String getDefaultMetaVariable() {
-        return "MODE";
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/BooleanOptionHandler.java	Tue Jan 14 01:26:27 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.runner.options.handlers;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.OptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
-import org.openjdk.jmh.runner.parameters.Defaults;
-
-/**
- * OptionHandler for boolean options.
- * <p/>
- * Will set to TRUE if: - Option is called with -<option> true - Option is called alone: -<option>
- * <p/>
- * Will set to FALSE if: - Option is called with anything but true: -<option> <anything else>
- *
- * @author sergey.kuksenko@oracle.com
- */
-public class BooleanOptionHandler extends OptionHandler<Boolean> {
-
-    /**
-     * Constructor
-     *
-     * @param parser CmdLineParser parent
-     * @param option Run-time copy of the Option
-     * @param setter Setter to feed back the value
-     */
-    public BooleanOptionHandler(CmdLineParser parser, OptionDef option, Setter<Boolean> setter) {
-        super(parser, option, setter);
-    }
-
-    @Override
-    public int parseArguments(Parameters params) throws CmdLineException {
-        if (params.size() > 0) {
-            String param = params.getParameter(0).toLowerCase();
-            if(Defaults.TRUE_VALUES.contains(param)) {
-                setter.addValue(true);
-                return 1;
-            }
-            if(Defaults.FALSE_VALUES.contains(param)) {
-                setter.addValue(false);
-                return 1;
-            }
-        }
-        setter.addValue(true);
-        return 0;
-    }
-
-    @Override
-    public String getDefaultMetaVariable() {
-        return "BOOL";
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/ForkOptionHandler.java	Tue Jan 14 01:26:27 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +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.runner.options.handlers;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.IntOptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
-import org.openjdk.jmh.runner.parameters.Defaults;
-
-/**
- * OptionHandler -f options.
- * -f INT of -f
- * -f without arguments means 1.
- *
- * <p/>
- *
- * @author sergey.kuksenko@oracle.com
- */
-public class ForkOptionHandler extends IntOptionHandler {
-
-    /**
-     * Constructor
-     *
-     * @param parser CmdLineParser parent
-     * @param option Run-time copy of the Option
-     * @param setter Setter to feed back the value
-     */
-    public ForkOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super Integer> setter) {
-        super(parser, option, setter);
-    }
-
-    @Override
-    public int parseArguments(Parameters params) throws CmdLineException {
-        if (params.size() > 0) {
-            String param = params.getParameter(0);
-            if (Defaults.FALSE_VALUES.contains(param)) {
-                setter.addValue(0);
-                return 1;
-            }
-            if (param.startsWith("-")) {
-                setter.addValue(1);
-                return 0;
-            }
-            try {
-                final int value = Integer.parseInt(param);
-                setter.addValue(value);
-            } catch (NumberFormatException ex) {
-                throw new CmdLineException(owner, param + " could not be parsed: " + ex.getMessage());
-            }
-            return 1;
-        }
-        setter.addValue(1);
-        return 0;
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/ProfilersOptionHandler.java	Tue Jan 14 01:26:27 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +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.runner.options.handlers;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.OptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
-import org.openjdk.jmh.profile.ProfilerFactory;
-import org.openjdk.jmh.profile.ProfilerType;
-
-import java.util.EnumSet;
-
-/**
- * OptionHandler for the -prof option. Will parse the comma-separated string.
- *
- * @author sergey.kuksenko@oracle.com
- */
-public class ProfilersOptionHandler extends OptionHandler<EnumSet<ProfilerType>> {
-
-    /**
-     * Constructor
-     *
-     * @param parser CmdLineParser parent
-     * @param option Run-time copy of the Option
-     * @param setter Setter to feed back the value
-     */
-    public ProfilersOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super EnumSet<ProfilerType>> setter) {
-        super(parser, option, setter);
-    }
-
-    @Override
-    public int parseArguments(Parameters params) throws CmdLineException {
-        String param = params.getParameter(0);
-        String[] possibleProfilers = param.split(",");
-        EnumSet<ProfilerType> profSet = EnumSet.noneOf(ProfilerType.class);
-        for (String s : possibleProfilers) {
-            ProfilerType prof = ProfilerFactory.getProfiler(s);
-            if (prof == null) {
-                throw new CmdLineException(owner, param + "; unknown profiler: '" + s + '\'');
-            }
-            if (prof.isSupported()) {
-                profSet.add(prof);
-            } else {
-                // TODO warning that the profiler is not supported
-            }
-        }
-        setter.addValue(profSet);
-        return 1;
-    }
-
-    @Override
-    public String getDefaultMetaVariable() {
-        return "<profilers list>";
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/ThreadCountsOptionHandler.java	Tue Jan 14 01:26:27 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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.runner.options.handlers;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.OptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
-
-/**
- * OptionHandler for the -tc/--threadcounts option. Will parse the comma-separated string and create a list of
- * integers.
- *
- * @author anders.astrand@oracle.com
- */
-public class ThreadCountsOptionHandler extends OptionHandler<Integer> {
-
-    /**
-     * Constructor
-     *
-     * @param parser CmdLineParser parent
-     * @param option Run-time copy of the Option
-     * @param setter Setter to feed back the value
-     */
-    public ThreadCountsOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super Integer> setter) {
-        super(parser, option, setter);
-    }
-
-    @Override
-    public int parseArguments(Parameters params) throws CmdLineException {
-        String param = params.getParameter(0);
-        try {
-            String[] possibleCounts = param.split(",");
-            for (String c : possibleCounts) {
-                final int value = Integer.parseInt(c.trim());
-                setter.addValue(value);
-            }
-        } catch (NumberFormatException ex) {
-            throw new CmdLineException(owner, param + " could not be parsed: " + ex.getMessage());
-        }
-        return 1;
-    }
-
-    @Override
-    public String getDefaultMetaVariable() {
-        return "INT,INT,...,INT";
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/ThreadsOptionHandler.java	Tue Jan 14 01:26:27 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +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.runner.options.handlers;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.IntOptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
-import org.openjdk.jmh.annotations.Threads;
-
-/**
- * OptionHandler for the -t/--threads option. Will parse the special value "max" and assign
- * 0 if set (later 0 will be changed to Runtime.availableProcessors()),
- * else treat it like normal integer parsing.
- *
- * @author anders.astrand@oracle.com
- */
-public class ThreadsOptionHandler extends IntOptionHandler {
-
-    /**
-     * Constructor
-     *
-     * @param parser CmdLineParser parent
-     * @param option Run-time copy of the Option
-     * @param setter Setter to feed back the value
-     */
-    public ThreadsOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super Integer> setter) {
-        super(parser, option, setter);
-    }
-
-    @Override
-    public int parseArguments(Parameters params) throws CmdLineException {
-        if ("max".equals(params.getParameter(0))) {
-            setter.addValue(Threads.MAX);
-            return 1;
-        } else {
-            return super.parseArguments(params);
-        }
-    }
-
-    @Override
-    public String getDefaultMetaVariable() {
-        return "INT (or \"max\")";
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/TimeUnitOptionHandler.java	Tue Jan 14 01:26:27 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +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.runner.options.handlers;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.OptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * OptionHandler for TimeValue options.
- */
-public class TimeUnitOptionHandler extends OptionHandler<TimeUnit> {
-
-    /**
-     * Constructor
-     *
-     * @param parser CmdLineParser parent
-     * @param option Run-time copy of the Option
-     * @param setter Setter to feed back the value
-     */
-    public TimeUnitOptionHandler(CmdLineParser parser, OptionDef option, Setter<TimeUnit> setter) {
-        super(parser, option, setter);
-    }
-
-    @Override
-    public int parseArguments(Parameters params) throws CmdLineException {
-        if (params.size() > 0) {
-            String param = params.getParameter(0).toLowerCase();
-            try {
-                setter.addValue(fromString(param));
-                return 1;
-            } catch (Exception e) {
-                throw new CmdLineException(owner, param + "; unknown time format.");
-            }
-        }
-        return 0;
-    }
-
-    @Override
-    public String getDefaultMetaVariable() {
-        return "TIME";
-    }
-
-    public static TimeUnit fromString(String timeString) {
-        if (timeString == null) {
-            return null;
-        }
-        if ("ns".equalsIgnoreCase(timeString)) {
-            return TimeUnit.NANOSECONDS;
-        }
-        if ("ms".equalsIgnoreCase(timeString)) {
-            return TimeUnit.MILLISECONDS;
-        }
-        if ("us".equalsIgnoreCase(timeString)) {
-            return TimeUnit.MICROSECONDS;
-        }
-        if ("s".equalsIgnoreCase(timeString)) {
-            return TimeUnit.SECONDS;
-        }
-        if ("m".equalsIgnoreCase(timeString)) {
-            return TimeUnit.MINUTES;
-        }
-        throw new IllegalArgumentException("unknown timeunit format: " + timeString);
-    }
-
-   public static String toString(TimeUnit timeUnit) {
-        switch(timeUnit) {
-            case SECONDS:
-                return "s";
-            case MILLISECONDS:
-                return "ms";
-            case MICROSECONDS:
-                return "us";
-            case NANOSECONDS:
-                return "ns";
-            case MINUTES:
-                return "m";
-            default:
-                return "s";
-        }
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/TimeValueOptionHandler.java	Tue Jan 14 01:26:27 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.runner.options.handlers;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.OptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
-import org.openjdk.jmh.runner.parameters.TimeValue;
-
-/**
- * OptionHandler for TimeValue options.
- */
-public class TimeValueOptionHandler extends OptionHandler<TimeValue> {
-
-    /**
-     * Constructor
-     *
-     * @param parser CmdLineParser parent
-     * @param option Run-time copy of the Option
-     * @param setter Setter to feed back the value
-     */
-    public TimeValueOptionHandler(CmdLineParser parser, OptionDef option, Setter<TimeValue> setter) {
-        super(parser, option, setter);
-    }
-
-    @Override
-    public int parseArguments(Parameters params) throws CmdLineException {
-        if (params.size() > 0) {
-            String param = params.getParameter(0).toLowerCase();
-            try {
-                TimeValue timeValue = TimeValue.fromString(param);
-                setter.addValue(timeValue);
-                return 1;
-            } catch (Exception e) {
-                throw new CmdLineException(owner, param + "; unknown time format.");
-            }
-        }
-        return 0;
-    }
-
-    @Override
-    public String getDefaultMetaVariable() {
-        return "TimeUnit";
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/parameters/TimeValue.java	Tue Jan 14 01:26:27 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/parameters/TimeValue.java	Tue Jan 14 14:27:56 2014 +0400
@@ -149,7 +149,7 @@
 
     public static TimeValue fromString(String timeString) {
         if (timeString == null) {
-            return new TimeValue(-1, null);
+            throw new IllegalArgumentException("String is null");
         }
         timeString = timeString.replaceAll(" ", "").toLowerCase();
         if (timeString.contains("ns")) {
--- a/jmh-core/src/test/java/org/openjdk/jmh/TestMain.java	Tue Jan 14 01:26:27 2014 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +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;
-
-import org.junit.Test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * Tests for Main
- *
- * @author anders.astrand@oracle.com
- *
- */
-public class TestMain {
-
-    @Test
-    public void testFaultyArgs() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        PrintStream tmp = System.err;
-
-        System.setErr(new PrintStream(baos));
-        Main.main(new String[] {"-kakor"});
-        System.setErr(tmp);
-
-        String s = baos.toString();
-        assertTrue(s, s.contains("\"-kakor\""));
-        assertTrue(s, s.contains("Usage"));
-        baos.close();
-    }
-
-    @Test
-    public void testHelp() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        PrintStream tmp = System.err;
-
-        System.setErr(new PrintStream(baos));
-        Main.main(new String[] {"-h"});
-        System.setErr(tmp);
-
-        String s = baos.toString();
-        assertTrue(s, s.contains("Usage: [options]"));
-        baos.close();
-    }
-
-}
--- a/jmh-core/src/test/java/org/openjdk/jmh/runner/options/TestOptions.java	Tue Jan 14 01:26:27 2014 +0400
+++ b/jmh-core/src/test/java/org/openjdk/jmh/runner/options/TestOptions.java	Tue Jan 14 14:27:56 2014 +0400
@@ -44,21 +44,15 @@
     private Options EMPTY_BUILDER;
     private CommandLineOptions EMPTY_CMDLINE;
 
-    private static CommandLineOptions getOptions(String[] argv) throws Exception {
-        CommandLineOptions opts = CommandLineOptions.newInstance();
-        opts.parseArguments(argv);
-        return opts;
-    }
-
     @Before
     public void setUp() throws Exception {
-        EMPTY_CMDLINE = getOptions(new String[]{});
+        EMPTY_CMDLINE = new CommandLineOptions();
         EMPTY_BUILDER = new OptionsBuilder().build();
     }
 
     @Test
     public void testIncludes() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{".*", ".*test.*", "test"});
+        CommandLineOptions cmdLine = new CommandLineOptions(".*", ".*test.*", "test");
         Options builder = new OptionsBuilder().include(".*").include(".*test.*").include("test").build();
         Assert.assertEquals(builder.getIncludes(), cmdLine.getIncludes());
     }
@@ -70,7 +64,7 @@
 
     @Test
     public void testExcludes() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-e", ".*", "-e", ".*test.*", "-e", "test"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-e", ".*", "-e", ".*test.*", "-e", "test");
         Options builder = new OptionsBuilder().exclude(".*").exclude(".*test.*").exclude("test").build();
         Assert.assertEquals(builder.getExcludes(), cmdLine.getExcludes());
     }
@@ -82,7 +76,7 @@
 
     @Test
     public void testOutput() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-o", "sample.out"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-o", "sample.out");
         Options builder = new OptionsBuilder().output("sample.out").build();
         Assert.assertEquals(builder.getOutput(), cmdLine.getOutput());
     }
@@ -95,7 +89,7 @@
     @Test
     public void testResultFormats() throws Exception {
         for (ResultFormatType type : ResultFormatType.values()) {
-            CommandLineOptions cmdLine = getOptions(new String[]{ "-rf", type.toString()});
+            CommandLineOptions cmdLine = new CommandLineOptions("-rf", type.toString());
             Options builder = new OptionsBuilder().resultFormat(type).build();
             Assert.assertEquals(builder.getResultFormat(), cmdLine.getResultFormat());
         }
@@ -108,7 +102,7 @@
 
     @Test
     public void testResult() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-rff", "sample.out"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-rff", "sample.out");
         Options builder = new OptionsBuilder().result("sample.out").build();
         Assert.assertEquals(builder.getOutput(), cmdLine.getOutput());
     }
@@ -120,21 +114,21 @@
 
     @Test
     public void testGC_Set() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-gc"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-gc");
         Options builder = new OptionsBuilder().shouldDoGC(true).build();
         Assert.assertEquals(builder.getOutput(), cmdLine.getOutput());
     }
 
     @Test
     public void testGC_True() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-gc", "true"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-gc", "true");
         Options builder = new OptionsBuilder().shouldDoGC(true).build();
         Assert.assertEquals(builder.getOutput(), cmdLine.getOutput());
     }
 
     @Test
     public void testGC_False() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-gc", "false"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-gc", "false");
         Options builder = new OptionsBuilder().shouldDoGC(false).build();
         Assert.assertEquals(builder.getOutput(), cmdLine.getOutput());
     }
@@ -147,7 +141,7 @@
     @Test
     public void testProfilers() throws Exception {
         // TODO: Should be able to accept multiple values without concat?
-        CommandLineOptions cmdLine = getOptions(new String[]{"-prof", ProfilerType.CL.id() + "," + ProfilerType.COMP.id()});
+        CommandLineOptions cmdLine = new CommandLineOptions("-prof", ProfilerType.CL.id() + "," + ProfilerType.COMP.id());
         Options builder = new OptionsBuilder().addProfiler(ProfilerType.CL).addProfiler(ProfilerType.COMP).build();
         Assert.assertEquals(builder.getProfilers(), cmdLine.getProfilers());
     }
@@ -160,7 +154,7 @@
     @Test
     public void testVerbose() throws Exception {
         for (VerboseMode mode : VerboseMode.values()) {
-            CommandLineOptions cmdLine = getOptions(new String[]{"-v", mode.toString()});
+            CommandLineOptions cmdLine = new CommandLineOptions("-v", mode.toString());
             Options builder = new OptionsBuilder().verbosity(mode).build();
             Assert.assertEquals(builder.verbosity(), cmdLine.verbosity());
         }
@@ -169,7 +163,7 @@
     @Test
     public void testVerbose_LC() throws Exception {
         for (VerboseMode mode : VerboseMode.values()) {
-            CommandLineOptions cmdLine = getOptions(new String[]{"-v", mode.toString().toLowerCase()});
+            CommandLineOptions cmdLine = new CommandLineOptions("-v", mode.toString().toLowerCase());
             Options builder = new OptionsBuilder().verbosity(mode).build();
             Assert.assertEquals(builder.verbosity(), cmdLine.verbosity());
         }
@@ -178,7 +172,7 @@
     @Test
     public void testVerbose_UC() throws Exception {
         for (VerboseMode mode : VerboseMode.values()) {
-            CommandLineOptions cmdLine = getOptions(new String[]{"-v", mode.toString().toUpperCase()});
+            CommandLineOptions cmdLine = new CommandLineOptions("-v", mode.toString().toUpperCase());
             Options builder = new OptionsBuilder().verbosity(mode).build();
             Assert.assertEquals(builder.verbosity(), cmdLine.verbosity());
         }
@@ -191,21 +185,21 @@
 
     @Test
     public void testSFOE_Set() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-foe"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-foe");
         Options builder = new OptionsBuilder().shouldFailOnError(true).build();
         Assert.assertEquals(builder.shouldFailOnError(), cmdLine.shouldFailOnError());
     }
 
     @Test
     public void testSFOE_True() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-foe", "true"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-foe", "true");
         Options builder = new OptionsBuilder().shouldFailOnError(true).build();
         Assert.assertEquals(builder.shouldFailOnError(), cmdLine.shouldFailOnError());
     }
 
     @Test
     public void testSFOE_False() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-foe", "false"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-foe", "false");
         Options builder = new OptionsBuilder().shouldFailOnError(false).build();
         Assert.assertEquals(builder.shouldFailOnError(), cmdLine.shouldFailOnError());
     }
@@ -217,14 +211,14 @@
 
     @Test
     public void testThreads_Set() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-t", "2"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-t", "2");
         Options builder = new OptionsBuilder().threads(2).build();
         Assert.assertEquals(builder.getThreads(), cmdLine.getThreads());
     }
 
     @Test
     public void testThreads_Max() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-t", "max"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-t", "max");
         Options builder = new OptionsBuilder().threads(Threads.MAX).build();
         Assert.assertEquals(builder.getThreads(), cmdLine.getThreads());
     }
@@ -236,7 +230,7 @@
 
     @Test
     public void testThreadGroups() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-tg", "3,4"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-tg", "3,4");
         Options builder = new OptionsBuilder().threadGroups(3, 4).build();
         Assert.assertEquals(builder.getThreads(), cmdLine.getThreads());
     }
@@ -248,21 +242,21 @@
 
     @Test
     public void testSynchIterations_Set() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-si"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-si");
         Options builder = new OptionsBuilder().syncIterations(true).build();
         Assert.assertEquals(builder.shouldSyncIterations(), cmdLine.shouldSyncIterations());
     }
 
     @Test
     public void testSynchIterations_True() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-si", "true"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-si", "true");
         Options builder = new OptionsBuilder().syncIterations(true).build();
         Assert.assertEquals(builder.shouldSyncIterations(), cmdLine.shouldSyncIterations());
     }
 
     @Test
     public void testSynchIterations_False() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-si", "false"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-si", "false");
         Options builder = new OptionsBuilder().syncIterations(false).build();
         Assert.assertEquals(builder.shouldSyncIterations(), cmdLine.shouldSyncIterations());
     }
@@ -274,7 +268,7 @@
 
     @Test
     public void testWarmupIterations() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-wi", "34"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-wi", "34");
         Options builder = new OptionsBuilder().warmupIterations(34).build();
         Assert.assertEquals(builder.getWarmupIterations(), cmdLine.getWarmupIterations());
     }
@@ -286,7 +280,7 @@
 
     @Test
     public void testWarmupTime() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-w", "34ms"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-w", "34ms");
         Options builder = new OptionsBuilder().warmupTime(TimeValue.milliseconds(34)).build();
         Assert.assertEquals(builder.getWarmupTime(), cmdLine.getWarmupTime());
     }
@@ -298,7 +292,7 @@
 
     @Test
     public void testRuntimeIterations() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-i", "34"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-i", "34");
         Options builder = new OptionsBuilder().measurementIterations(34).build();
         Assert.assertEquals(builder.getMeasurementIterations(), cmdLine.getMeasurementIterations());
     }
@@ -310,7 +304,7 @@
 
     @Test
     public void testRuntime() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-r", "34ms"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-r", "34ms");
         Options builder = new OptionsBuilder().measurementTime(TimeValue.milliseconds(34)).build();
         Assert.assertEquals(builder.getMeasurementTime(), cmdLine.getMeasurementTime());
     }
@@ -322,7 +316,7 @@
 
     @Test
     public void testWarmupMicros() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-wmb", ".*", "-wmb", ".*test.*", "-wmb", "test"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-wmb", ".*", "-wmb", ".*test.*", "-wmb", "test");
         Options builder = new OptionsBuilder().includeWarmup(".*").includeWarmup(".*test.*").includeWarmup("test").build();
         Assert.assertEquals(builder.getWarmupIncludes(), cmdLine.getWarmupIncludes());
     }
@@ -335,7 +329,7 @@
     @Test
     public void testBenchModes() throws Exception {
         // TODO: Accept multiple options instead of concatenation?
-        CommandLineOptions cmdLine = getOptions(new String[]{"-bm", Mode.AverageTime.shortLabel() + "," + Mode.Throughput.shortLabel()});
+        CommandLineOptions cmdLine = new CommandLineOptions("-bm", Mode.AverageTime.shortLabel() + "," + Mode.Throughput.shortLabel());
         Options builder = new OptionsBuilder().mode(Mode.AverageTime).mode(Mode.Throughput).build();
         Assert.assertEquals(builder.getBenchModes(), cmdLine.getBenchModes());
     }
@@ -347,7 +341,7 @@
 
     @Test
     public void testTimeunit() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-tu", "ns"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-tu", "ns");
         Options builder = new OptionsBuilder().timeUnit(TimeUnit.NANOSECONDS).build();
         Assert.assertEquals(builder.getTimeUnit(), cmdLine.getTimeUnit());
     }
@@ -359,21 +353,21 @@
 
     @Test
     public void testFork() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-f"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-f");
         Options builder = new OptionsBuilder().forks(1).build();
         Assert.assertEquals(builder.getForkCount(), cmdLine.getForkCount());
     }
 
     @Test
     public void testFork_0() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-f", "0"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-f", "0");
         Options builder = new OptionsBuilder().forks(0).build();
         Assert.assertEquals(builder.getForkCount(), cmdLine.getForkCount());
     }
 
     @Test
     public void testFork_1() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-f", "1"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-f", "1");
         Options builder = new OptionsBuilder().forks(1).build();
         Assert.assertEquals(builder.getForkCount(), cmdLine.getForkCount());
     }
@@ -385,14 +379,14 @@
 
     @Test
     public void testWarmupFork_0() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-wf", "0"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-wf", "0");
         Options builder = new OptionsBuilder().warmupForks(0).build();
         Assert.assertEquals(builder.getWarmupForkCount(), cmdLine.getWarmupForkCount());
     }
 
     @Test
     public void testWarmupFork_1() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"-wf", "1"});
+        CommandLineOptions cmdLine = new CommandLineOptions("-wf", "1");
         Options builder = new OptionsBuilder().warmupForks(1).build();
         Assert.assertEquals(builder.getWarmupForkCount(), cmdLine.getWarmupForkCount());
     }
@@ -404,7 +398,7 @@
 
     @Test
     public void testJvmClasspath() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"--jvmclasspath", "sample.jar"});
+        CommandLineOptions cmdLine = new CommandLineOptions("--jvmClasspath", "sample.jar");
         Options builder = new OptionsBuilder().jvmClasspath("sample.jar").build();
         Assert.assertEquals(builder.getJvmClassPath(), cmdLine.getJvmClassPath());
     }
@@ -416,7 +410,7 @@
 
     @Test
     public void testJvm() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"--jvm", "sample.jar"});
+        CommandLineOptions cmdLine = new CommandLineOptions("--jvm", "sample.jar");
         Options builder = new OptionsBuilder().jvm("sample.jar").build();
         Assert.assertEquals(builder.getJvm(), cmdLine.getJvm());
     }
@@ -428,7 +422,7 @@
 
     @Test
     public void testJvmArgs() throws Exception {
-        CommandLineOptions cmdLine = getOptions(new String[]{"--jvmargs", "sample.jar"});
+        CommandLineOptions cmdLine = new CommandLineOptions("--jvmArgs", "sample.jar");
         Options builder = new OptionsBuilder().jvmArgs("sample.jar").build();
         Assert.assertEquals(builder.getJvmArgs(), cmdLine.getJvmArgs());
     }