8148154: Integrate JOpt Simple for internal usage by JDK tools
authorchegar
Tue, 26 Jan 2016 09:18:51 +0000
changeset 35377 462f93ab37f2
parent 35361 4a652e4ca952
child 35378 7e19fa0e4e5b
8148154: Integrate JOpt Simple for internal usage by JDK tools Reviewed-by: alanb, redestad, rriggs
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AbstractOptionSpec.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AlternativeLongOptionSpec.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentAcceptingOptionSpec.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentList.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/BuiltinHelpFormatter.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatter.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/IllegalOptionSpecificationException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MultipleArgumentsForOptionException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NoArgumentOptionSpec.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NonOptionArgumentSpec.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionArgumentConversionException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDeclarer.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDescriptor.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionMissingRequiredArgumentException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParser.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParserState.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSet.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpec.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecBuilder.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecTokenizer.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionalArgumentOptionSpec.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ParserRules.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/README
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/RequiredArgumentOptionSpec.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnacceptableNumberOfNonOptionsException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnconfiguredOptionException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnrecognizedOptionException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConversionException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConverter.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/AbbreviationMap.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Classes.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Columns.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ConstructorInvokingValueConverter.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/MethodInvokingValueConverter.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Objects.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Reflection.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ReflectionException.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Row.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Rows.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Strings.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/DateConverter.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/InetAddressConverter.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/KeyValuePair.java
jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/RegexMatcher.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AbstractOptionSpec.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static java.util.Collections.*;
+
+import jdk.internal.joptsimple.internal.Reflection;
+import jdk.internal.joptsimple.internal.ReflectionException;
+
+import static jdk.internal.joptsimple.internal.Strings.*;
+
+/**
+ * @param <V> represents the type of the arguments this option accepts
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+abstract class AbstractOptionSpec<V> implements OptionSpec<V>, OptionDescriptor {
+    private final List<String> options = new ArrayList<String>();
+    private final String description;
+    private boolean forHelp;
+
+    protected AbstractOptionSpec( String option ) {
+        this( singletonList( option ), EMPTY );
+    }
+
+    protected AbstractOptionSpec( Collection<String> options, String description ) {
+        arrangeOptions( options );
+
+        this.description = description;
+    }
+
+    public final Collection<String> options() {
+        return unmodifiableList( options );
+    }
+
+    public final List<V> values( OptionSet detectedOptions ) {
+        return detectedOptions.valuesOf( this );
+    }
+
+    public final V value( OptionSet detectedOptions ) {
+        return detectedOptions.valueOf( this );
+    }
+
+    public String description() {
+        return description;
+    }
+
+    public final AbstractOptionSpec<V> forHelp() {
+        forHelp = true;
+        return this;
+    }
+
+    public final boolean isForHelp() {
+        return forHelp;
+    }
+
+    public boolean representsNonOptions() {
+        return false;
+    }
+
+    protected abstract V convert( String argument );
+
+    protected V convertWith( ValueConverter<V> converter, String argument ) {
+        try {
+            return Reflection.convertWith( converter, argument );
+        }
+        catch ( ReflectionException ex ) {
+            throw new OptionArgumentConversionException( options(), argument, ex );
+        }
+        catch ( ValueConversionException ex ) {
+            throw new OptionArgumentConversionException( options(), argument, ex );
+        }
+    }
+
+    protected String argumentTypeIndicatorFrom( ValueConverter<V> converter ) {
+        if ( converter == null )
+            return null;
+
+        String pattern = converter.valuePattern();
+        return pattern == null ? converter.valueType().getName() : pattern;
+    }
+
+    abstract void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions,
+        String detectedArgument );
+
+    private void arrangeOptions( Collection<String> unarranged ) {
+        if ( unarranged.size() == 1 ) {
+            options.addAll( unarranged );
+            return;
+        }
+
+        List<String> shortOptions = new ArrayList<String>();
+        List<String> longOptions = new ArrayList<String>();
+
+        for ( String each : unarranged ) {
+            if ( each.length() == 1 )
+                shortOptions.add( each );
+            else
+                longOptions.add( each );
+        }
+
+        sort( shortOptions );
+        sort( longOptions );
+
+        options.addAll( shortOptions );
+        options.addAll( longOptions );
+    }
+
+    @Override
+    public boolean equals( Object that ) {
+        if ( !( that instanceof AbstractOptionSpec<?> ) )
+            return false;
+
+        AbstractOptionSpec<?> other = (AbstractOptionSpec<?>) that;
+        return options.equals( other.options );
+    }
+
+    @Override
+    public int hashCode() {
+        return options.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return options.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AlternativeLongOptionSpec.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import static java.util.Collections.*;
+
+import static jdk.internal.joptsimple.ParserRules.*;
+
+/**
+ * Represents the <kbd>"-W"</kbd> form of long option specification.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class AlternativeLongOptionSpec extends ArgumentAcceptingOptionSpec<String> {
+    AlternativeLongOptionSpec() {
+        super( singletonList( RESERVED_FOR_EXTENSIONS ), true, "Alternative form of long options" );
+
+        describedAs( "opt=value" );
+    }
+
+    @Override
+    protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
+        if ( !arguments.hasMore() )
+            throw new OptionMissingRequiredArgumentException( options() );
+
+        arguments.treatNextAsLongOption();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentAcceptingOptionSpec.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import static java.util.Collections.*;
+
+import static jdk.internal.joptsimple.internal.Objects.*;
+import static jdk.internal.joptsimple.internal.Reflection.*;
+import static jdk.internal.joptsimple.internal.Strings.*;
+
+/**
+ * <p>Specification of an option that accepts an argument.</p>
+ *
+ * <p>Instances are returned from {@link OptionSpecBuilder} methods to allow the formation of parser directives as
+ * sentences in a "fluent interface" language. For example:</p>
+ *
+ * <pre>
+ *   <code>
+ *   OptionParser parser = new OptionParser();
+ *   parser.accepts( "c" ).withRequiredArg().<strong>ofType( Integer.class )</strong>;
+ *   </code>
+ * </pre>
+ *
+ * <p>If no methods are invoked on an instance of this class, then that instance's option will treat its argument as
+ * a {@link String}.</p>
+ *
+ * @param <V> represents the type of the arguments this option accepts
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public abstract class ArgumentAcceptingOptionSpec<V> extends AbstractOptionSpec<V> {
+    private static final char NIL_VALUE_SEPARATOR = '\u0000';
+
+    private boolean optionRequired;
+    private final boolean argumentRequired;
+    private ValueConverter<V> converter;
+    private String argumentDescription = "";
+    private String valueSeparator = String.valueOf( NIL_VALUE_SEPARATOR );
+    private final List<V> defaultValues = new ArrayList<V>();
+
+    ArgumentAcceptingOptionSpec( String option, boolean argumentRequired ) {
+        super( option );
+
+        this.argumentRequired = argumentRequired;
+    }
+
+    ArgumentAcceptingOptionSpec( Collection<String> options, boolean argumentRequired, String description ) {
+        super( options, description );
+
+        this.argumentRequired = argumentRequired;
+    }
+
+    /**
+     * <p>Specifies a type to which arguments of this spec's option are to be converted.</p>
+     *
+     * <p>JOpt Simple accepts types that have either:</p>
+     *
+     * <ol>
+     *   <li>a public static method called {@code valueOf} which accepts a single argument of type {@link String}
+     *   and whose return type is the same as the class on which the method is declared.  The {@code java.lang}
+     *   primitive wrapper classes have such methods.</li>
+     *
+     *   <li>a public constructor which accepts a single argument of type {@link String}.</li>
+     * </ol>
+     *
+     * <p>This class converts arguments using those methods in that order; that is, {@code valueOf} would be invoked
+     * before a one-{@link String}-arg constructor would.</p>
+     *
+     * <p>Invoking this method will trump any previous calls to this method or to
+     * {@link #withValuesConvertedBy(ValueConverter)}.</p>
+     *
+     * @param <T> represents the runtime class of the desired option argument type
+     * @param argumentType desired type of arguments to this spec's option
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws NullPointerException if the type is {@code null}
+     * @throws IllegalArgumentException if the type does not have the standard conversion methods
+     */
+    public final <T> ArgumentAcceptingOptionSpec<T> ofType( Class<T> argumentType ) {
+        return withValuesConvertedBy( findConverter( argumentType ) );
+    }
+
+    /**
+     * <p>Specifies a converter to use to translate arguments of this spec's option into Java objects.  This is useful
+     * when converting to types that do not have the requisite factory method or constructor for
+     * {@link #ofType(Class)}.</p>
+     *
+     * <p>Invoking this method will trump any previous calls to this method or to {@link #ofType(Class)}.
+     *
+     * @param <T> represents the runtime class of the desired option argument type
+     * @param aConverter the converter to use
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws NullPointerException if the converter is {@code null}
+     */
+    @SuppressWarnings( "unchecked" )
+    public final <T> ArgumentAcceptingOptionSpec<T> withValuesConvertedBy( ValueConverter<T> aConverter ) {
+        if ( aConverter == null )
+            throw new NullPointerException( "illegal null converter" );
+
+        converter = (ValueConverter<V>) aConverter;
+        return (ArgumentAcceptingOptionSpec<T>) this;
+    }
+
+    /**
+     * <p>Specifies a description for the argument of the option that this spec represents.  This description is used
+     * when generating help information about the parser.</p>
+     *
+     * @param description describes the nature of the argument of this spec's option
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     */
+    public final ArgumentAcceptingOptionSpec<V> describedAs( String description ) {
+        argumentDescription = description;
+        return this;
+    }
+
+    /**
+     * <p>Specifies a value separator for the argument of the option that this spec represents.  This allows a single
+     * option argument to represent multiple values for the option.  For example:</p>
+     *
+     * <pre>
+     *   <code>
+     *   parser.accepts( "z" ).withRequiredArg()
+     *       .<strong>withValuesSeparatedBy( ',' )</strong>;
+     *   OptionSet options = parser.parse( new String[] { "-z", "foo,bar,baz", "-z",
+     *       "fizz", "-z", "buzz" } );
+     *   </code>
+     * </pre>
+     *
+     * <p>Then {@code options.valuesOf( "z" )} would yield the list {@code [foo, bar, baz, fizz, buzz]}.</p>
+     *
+     * <p>You cannot use Unicode U+0000 as the separator.</p>
+     *
+     * @param separator a character separator
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws IllegalArgumentException if the separator is Unicode U+0000
+     */
+    public final ArgumentAcceptingOptionSpec<V> withValuesSeparatedBy( char separator ) {
+        if ( separator == NIL_VALUE_SEPARATOR )
+            throw new IllegalArgumentException( "cannot use U+0000 as separator" );
+
+        valueSeparator = String.valueOf( separator );
+        return this;
+    }
+
+    /**
+     * <p>Specifies a value separator for the argument of the option that this spec represents.  This allows a single
+     * option argument to represent multiple values for the option.  For example:</p>
+     *
+     * <pre>
+     *   <code>
+     *   parser.accepts( "z" ).withRequiredArg()
+     *       .<strong>withValuesSeparatedBy( ":::" )</strong>;
+     *   OptionSet options = parser.parse( new String[] { "-z", "foo:::bar:::baz", "-z",
+     *       "fizz", "-z", "buzz" } );
+     *   </code>
+     * </pre>
+     *
+     * <p>Then {@code options.valuesOf( "z" )} would yield the list {@code [foo, bar, baz, fizz, buzz]}.</p>
+     *
+     * <p>You cannot use Unicode U+0000 in the separator.</p>
+     *
+     * @param separator a string separator
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws IllegalArgumentException if the separator contains Unicode U+0000
+     */
+    public final ArgumentAcceptingOptionSpec<V> withValuesSeparatedBy( String separator ) {
+        if ( separator.indexOf( NIL_VALUE_SEPARATOR ) != -1 )
+            throw new IllegalArgumentException( "cannot use U+0000 in separator" );
+
+        valueSeparator = separator;
+        return this;
+    }
+
+    /**
+     * Specifies a set of default values for the argument of the option that this spec represents.
+     *
+     * @param value the first in the set of default argument values for this spec's option
+     * @param values the (optional) remainder of the set of default argument values for this spec's option
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws NullPointerException if {@code value}, {@code values}, or any elements of {@code values} are
+     * {@code null}
+     */
+    @SuppressWarnings("unchecked")
+    public ArgumentAcceptingOptionSpec<V> defaultsTo( V value, V... values ) {
+        addDefaultValue( value );
+        defaultsTo( values );
+
+        return this;
+    }
+
+    /**
+     * Specifies a set of default values for the argument of the option that this spec represents.
+     *
+     * @param values the set of default argument values for this spec's option
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws NullPointerException if {@code values} or any elements of {@code values} are {@code null}
+     */
+    public ArgumentAcceptingOptionSpec<V> defaultsTo( V[] values ) {
+        for ( V each : values )
+            addDefaultValue( each );
+
+        return this;
+    }
+
+    /**
+     * Marks this option as required. An {@link OptionException} will be thrown when
+     * {@link OptionParser#parse(java.lang.String...)} is called, if an option is marked as required and not specified
+     * on the command line.
+     *
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     */
+    public ArgumentAcceptingOptionSpec<V> required() {
+        optionRequired = true;
+        return this;
+    }
+
+    public boolean isRequired() {
+        return optionRequired;
+    }
+
+    private void addDefaultValue( V value ) {
+        ensureNotNull( value );
+        defaultValues.add( value );
+    }
+
+    @Override
+    final void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions,
+        String detectedArgument ) {
+
+        if ( isNullOrEmpty( detectedArgument ) )
+            detectOptionArgument( parser, arguments, detectedOptions );
+        else
+            addArguments( detectedOptions, detectedArgument );
+    }
+
+    protected void addArguments( OptionSet detectedOptions, String detectedArgument ) {
+        StringTokenizer lexer = new StringTokenizer( detectedArgument, valueSeparator );
+        if ( !lexer.hasMoreTokens() )
+            detectedOptions.addWithArgument( this, detectedArgument );
+        else {
+            while ( lexer.hasMoreTokens() )
+                detectedOptions.addWithArgument( this, lexer.nextToken() );
+        }
+    }
+
+    protected abstract void detectOptionArgument( OptionParser parser, ArgumentList arguments,
+        OptionSet detectedOptions );
+
+    @Override
+    protected final V convert( String argument ) {
+        return convertWith( converter, argument );
+    }
+
+    protected boolean canConvertArgument( String argument ) {
+        StringTokenizer lexer = new StringTokenizer( argument, valueSeparator );
+
+        try {
+            while ( lexer.hasMoreTokens() )
+                convert( lexer.nextToken() );
+            return true;
+        }
+        catch ( OptionException ignored ) {
+            return false;
+        }
+    }
+
+    protected boolean isArgumentOfNumberType() {
+        return converter != null && Number.class.isAssignableFrom( converter.valueType() );
+    }
+
+    public boolean acceptsArguments() {
+        return true;
+    }
+
+    public boolean requiresArgument() {
+        return argumentRequired;
+    }
+
+    public String argumentDescription() {
+        return argumentDescription;
+    }
+
+    public String argumentTypeIndicator() {
+        return argumentTypeIndicatorFrom( converter );
+    }
+
+    public List<V> defaultValues() {
+        return unmodifiableList( defaultValues );
+    }
+
+    @Override
+    public boolean equals( Object that ) {
+        if ( !super.equals( that ) )
+            return false;
+
+        ArgumentAcceptingOptionSpec<?> other = (ArgumentAcceptingOptionSpec<?>) that;
+        return requiresArgument() == other.requiresArgument();
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ ( argumentRequired ? 0 : 1 );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ArgumentList.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import static jdk.internal.joptsimple.ParserRules.*;
+
+/**
+ * <p>Wrapper for an array of command line arguments.</p>
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class ArgumentList {
+    private final String[] arguments;
+    private int currentIndex;
+
+    ArgumentList( String... arguments ) {
+        this.arguments = arguments.clone();
+    }
+
+    boolean hasMore() {
+        return currentIndex < arguments.length;
+    }
+
+    String next() {
+        return arguments[ currentIndex++ ];
+    }
+
+    String peek() {
+        return arguments[ currentIndex ];
+    }
+
+    void treatNextAsLongOption() {
+        if ( HYPHEN_CHAR != arguments[ currentIndex ].charAt( 0 ) )
+            arguments[ currentIndex ] = DOUBLE_HYPHEN + arguments[ currentIndex ];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/BuiltinHelpFormatter.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import jdk.internal.joptsimple.internal.Rows;
+import jdk.internal.joptsimple.internal.Strings;
+
+import static jdk.internal.joptsimple.ParserRules.*;
+import static jdk.internal.joptsimple.internal.Classes.*;
+import static jdk.internal.joptsimple.internal.Strings.*;
+
+/**
+ * <p>A help formatter that allows configuration of overall row width and column separator width.</p>
+ *
+ * <p>The formatter produces a two-column output. The left column is for the options, and the right column for their
+ * descriptions. The formatter will allow as much space as possible for the descriptions, by minimizing the option
+ * column's width, no greater than slightly less than half the overall desired width.</p>
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public class BuiltinHelpFormatter implements HelpFormatter {
+    private final Rows nonOptionRows;
+    private final Rows optionRows;
+
+    /**
+     * Makes a formatter with a pre-configured overall row width and column separator width.
+     */
+    BuiltinHelpFormatter() {
+        this( 80, 2 );
+    }
+
+    /**
+     * Makes a formatter with a given overall row width and column separator width.
+     *
+     * @param desiredOverallWidth how many characters wide to make the overall help display
+     * @param desiredColumnSeparatorWidth how many characters wide to make the separation between option column and
+     * description column
+     */
+    public BuiltinHelpFormatter( int desiredOverallWidth, int desiredColumnSeparatorWidth ) {
+        nonOptionRows = new Rows( desiredOverallWidth * 2, 0 );
+        optionRows = new Rows( desiredOverallWidth, desiredColumnSeparatorWidth );
+    }
+
+    public String format( Map<String, ? extends OptionDescriptor> options ) {
+        Comparator<OptionDescriptor> comparator =
+            new Comparator<OptionDescriptor>() {
+                public int compare( OptionDescriptor first, OptionDescriptor second ) {
+                    return first.options().iterator().next().compareTo( second.options().iterator().next() );
+                }
+            };
+
+        Set<OptionDescriptor> sorted = new TreeSet<OptionDescriptor>( comparator );
+        sorted.addAll( options.values() );
+
+        addRows( sorted );
+
+        return formattedHelpOutput();
+    }
+
+    private String formattedHelpOutput() {
+        StringBuilder formatted = new StringBuilder();
+        String nonOptionDisplay = nonOptionRows.render();
+        if ( !Strings.isNullOrEmpty( nonOptionDisplay ) )
+            formatted.append( nonOptionDisplay ).append( LINE_SEPARATOR );
+        formatted.append( optionRows.render() );
+
+        return formatted.toString();
+    }
+
+    private void addRows( Collection<? extends OptionDescriptor> options ) {
+        addNonOptionsDescription( options );
+
+        if ( options.isEmpty() )
+            optionRows.add( "No options specified", "" );
+        else {
+            addHeaders( options );
+            addOptions( options );
+        }
+
+        fitRowsToWidth();
+    }
+
+    private void addNonOptionsDescription( Collection<? extends OptionDescriptor> options ) {
+        OptionDescriptor nonOptions = findAndRemoveNonOptionsSpec( options );
+        if ( shouldShowNonOptionArgumentDisplay( nonOptions ) ) {
+            nonOptionRows.add( "Non-option arguments:", "" );
+            nonOptionRows.add(createNonOptionArgumentsDisplay(nonOptions), "");
+        }
+    }
+
+    private boolean shouldShowNonOptionArgumentDisplay( OptionDescriptor nonOptions ) {
+        return !Strings.isNullOrEmpty( nonOptions.description() )
+            || !Strings.isNullOrEmpty( nonOptions.argumentTypeIndicator() )
+            || !Strings.isNullOrEmpty( nonOptions.argumentDescription() );
+    }
+
+    private String createNonOptionArgumentsDisplay(OptionDescriptor nonOptions) {
+        StringBuilder buffer = new StringBuilder();
+        maybeAppendOptionInfo( buffer, nonOptions );
+        maybeAppendNonOptionsDescription( buffer, nonOptions );
+
+        return buffer.toString();
+    }
+
+    private void maybeAppendNonOptionsDescription( StringBuilder buffer, OptionDescriptor nonOptions ) {
+        buffer.append( buffer.length() > 0 && !Strings.isNullOrEmpty( nonOptions.description() ) ? " -- " : "" )
+            .append( nonOptions.description() );
+    }
+
+    private OptionDescriptor findAndRemoveNonOptionsSpec( Collection<? extends OptionDescriptor> options ) {
+        for ( Iterator<? extends OptionDescriptor> it = options.iterator(); it.hasNext(); ) {
+            OptionDescriptor next = it.next();
+            if ( next.representsNonOptions() ) {
+                it.remove();
+                return next;
+            }
+        }
+
+        throw new AssertionError( "no non-options argument spec" );
+    }
+
+    private void addHeaders( Collection<? extends OptionDescriptor> options ) {
+        if ( hasRequiredOption( options ) ) {
+            optionRows.add("Option (* = required)", "Description");
+            optionRows.add("---------------------", "-----------");
+        } else {
+            optionRows.add("Option", "Description");
+            optionRows.add("------", "-----------");
+        }
+    }
+
+    private boolean hasRequiredOption( Collection<? extends OptionDescriptor> options ) {
+        for ( OptionDescriptor each : options ) {
+            if ( each.isRequired() )
+                return true;
+        }
+
+        return false;
+    }
+
+    private void addOptions( Collection<? extends OptionDescriptor> options ) {
+        for ( OptionDescriptor each : options ) {
+            if ( !each.representsNonOptions() )
+                optionRows.add( createOptionDisplay( each ), createDescriptionDisplay( each ) );
+        }
+    }
+
+    private String createOptionDisplay( OptionDescriptor descriptor ) {
+        StringBuilder buffer = new StringBuilder( descriptor.isRequired() ? "* " : "" );
+
+        for ( Iterator<String> i = descriptor.options().iterator(); i.hasNext(); ) {
+            String option = i.next();
+            buffer.append( option.length() > 1 ? DOUBLE_HYPHEN : HYPHEN );
+            buffer.append( option );
+
+            if ( i.hasNext() )
+                buffer.append( ", " );
+        }
+
+        maybeAppendOptionInfo( buffer, descriptor );
+
+        return buffer.toString();
+    }
+
+    private void maybeAppendOptionInfo( StringBuilder buffer, OptionDescriptor descriptor ) {
+        String indicator = extractTypeIndicator( descriptor );
+        String description = descriptor.argumentDescription();
+        if ( indicator != null || !isNullOrEmpty( description ) )
+            appendOptionHelp( buffer, indicator, description, descriptor.requiresArgument() );
+    }
+
+    private String extractTypeIndicator( OptionDescriptor descriptor ) {
+        String indicator = descriptor.argumentTypeIndicator();
+
+        if ( !isNullOrEmpty( indicator ) && !String.class.getName().equals( indicator ) )
+            return shortNameOf( indicator );
+
+        return null;
+    }
+
+    private void appendOptionHelp( StringBuilder buffer, String typeIndicator, String description, boolean required ) {
+        if ( required )
+            appendTypeIndicator( buffer, typeIndicator, description, '<', '>' );
+        else
+            appendTypeIndicator( buffer, typeIndicator, description, '[', ']' );
+    }
+
+    private void appendTypeIndicator( StringBuilder buffer, String typeIndicator, String description,
+                                      char start, char end ) {
+        buffer.append( ' ' ).append( start );
+        if ( typeIndicator != null )
+            buffer.append( typeIndicator );
+
+        if ( !Strings.isNullOrEmpty( description ) ) {
+            if ( typeIndicator != null )
+                buffer.append( ": " );
+
+            buffer.append( description );
+        }
+
+        buffer.append( end );
+    }
+
+    private String createDescriptionDisplay( OptionDescriptor descriptor ) {
+        List<?> defaultValues = descriptor.defaultValues();
+        if ( defaultValues.isEmpty() )
+            return descriptor.description();
+
+        String defaultValuesDisplay = createDefaultValuesDisplay( defaultValues );
+        return ( descriptor.description() + ' ' + surround( "default: " + defaultValuesDisplay, '(', ')' ) ).trim();
+    }
+
+    private String createDefaultValuesDisplay( List<?> defaultValues ) {
+        return defaultValues.size() == 1 ? defaultValues.get( 0 ).toString() : defaultValues.toString();
+    }
+
+    private void fitRowsToWidth() {
+        nonOptionRows.fitToWidth();
+        optionRows.fitToWidth();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/HelpFormatter.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Map;
+
+/**
+ * <p>Represents objects charged with taking a set of option descriptions and producing some help text from them.</p>
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public interface HelpFormatter {
+    /**
+     * Produces help text, given a set of option descriptors.
+     *
+     * @param options descriptors for the configured options of a parser
+     * @return text to be used as help
+     * @see OptionParser#printHelpOn(java.io.Writer)
+     * @see OptionParser#formatHelpWith(HelpFormatter)
+     */
+    String format( Map<String, ? extends OptionDescriptor> options );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/IllegalOptionSpecificationException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import static java.util.Collections.*;
+
+/**
+ * Thrown when the option parser is asked to recognize an option with illegal characters in it.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class IllegalOptionSpecificationException extends OptionException {
+    private static final long serialVersionUID = -1L;
+
+    IllegalOptionSpecificationException( String option ) {
+        super( singletonList( option ) );
+    }
+
+    @Override
+    public String getMessage() {
+        return singleOptionMessage() + " is not a legal option character";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MissingRequiredOptionException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+
+/**
+ * Thrown when an option is marked as required, but not specified on the command line.
+ *
+ * @author <a href="https://github.com/TC1">Emils Solmanis</a>
+ */
+class MissingRequiredOptionException extends OptionException {
+    private static final long serialVersionUID = -1L;
+
+    protected MissingRequiredOptionException( Collection<String> options ) {
+        super( options );
+    }
+
+    @Override
+    public String getMessage() {
+        return "Missing required option(s) " + multipleOptionMessage();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/MultipleArgumentsForOptionException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+
+/**
+ * Thrown when asking an {@link OptionSet} for a single argument of an option when many have been specified.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class MultipleArgumentsForOptionException extends OptionException {
+    private static final long serialVersionUID = -1L;
+
+    MultipleArgumentsForOptionException( Collection<String> options ) {
+        super( options );
+    }
+
+    @Override
+    public String getMessage() {
+        return "Found multiple arguments for option " + multipleOptionMessage() + ", but you asked for only one";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NoArgumentOptionSpec.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+import java.util.List;
+
+import static java.util.Collections.*;
+
+/**
+ * A specification for an option that does not accept arguments.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class NoArgumentOptionSpec extends AbstractOptionSpec<Void> {
+    NoArgumentOptionSpec( String option ) {
+        this( singletonList( option ), "" );
+    }
+
+    NoArgumentOptionSpec( Collection<String> options, String description ) {
+        super( options, description );
+    }
+
+    @Override
+    void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions,
+        String detectedArgument ) {
+
+        detectedOptions.add( this );
+    }
+
+    public boolean acceptsArguments() {
+        return false;
+    }
+
+    public boolean requiresArgument() {
+        return false;
+    }
+
+    public boolean isRequired() {
+        return false;
+    }
+
+    public String argumentDescription() {
+        return "";
+    }
+
+    public String argumentTypeIndicator() {
+        return "";
+    }
+
+    @Override
+    protected Void convert( String argument ) {
+        return null;
+    }
+
+    public List<Void> defaultValues() {
+        return emptyList();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/NonOptionArgumentSpec.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.List;
+
+import static java.util.Arrays.*;
+import static java.util.Collections.*;
+import static jdk.internal.joptsimple.internal.Reflection.*;
+
+/**
+ * <p>Specification of a command line's non-option arguments.</p>
+ *
+ * <p>Instances are returned from {@link OptionParser} methods to allow the formation of parser directives as
+ * sentences in a "fluent interface" language. For example:</p>
+ *
+ * <pre>
+ *   <code>
+ *   OptionParser parser = new OptionParser();
+ *   parser.nonOptions( "files to be processed" ).<strong>ofType( File.class )</strong>;
+ *   </code>
+ * </pre>
+ *
+ * <p>If no methods are invoked on an instance of this class, then that instance's option will treat the non-option
+ * arguments as {@link String}s.</p>
+ *
+ * @param <V> represents the type of the non-option arguments
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public class NonOptionArgumentSpec<V> extends AbstractOptionSpec<V> {
+    static final String NAME = "[arguments]";
+
+    private ValueConverter<V> converter;
+    private String argumentDescription = "";
+
+    NonOptionArgumentSpec() {
+        this("");
+    }
+
+    NonOptionArgumentSpec( String description ) {
+        super( asList( NAME ), description );
+    }
+
+    /**
+     * <p>Specifies a type to which the non-option arguments are to be converted.</p>
+     *
+     * <p>JOpt Simple accepts types that have either:</p>
+     *
+     * <ol>
+     *   <li>a public static method called {@code valueOf} which accepts a single argument of type {@link String}
+     *   and whose return type is the same as the class on which the method is declared.  The {@code java.lang}
+     *   primitive wrapper classes have such methods.</li>
+     *
+     *   <li>a public constructor which accepts a single argument of type {@link String}.</li>
+     * </ol>
+     *
+     * <p>This class converts arguments using those methods in that order; that is, {@code valueOf} would be invoked
+     * before a one-{@link String}-arg constructor would.</p>
+     *
+     * <p>Invoking this method will trump any previous calls to this method or to
+     * {@link #withValuesConvertedBy(ValueConverter)}.</p>
+     *
+     * @param <T> represents the runtime class of the desired option argument type
+     * @param argumentType desired type of arguments to this spec's option
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws NullPointerException if the type is {@code null}
+     * @throws IllegalArgumentException if the type does not have the standard conversion methods
+     */
+    @SuppressWarnings( "unchecked" )
+    public <T> NonOptionArgumentSpec<T> ofType( Class<T> argumentType ) {
+        converter = (ValueConverter<V>) findConverter( argumentType );
+        return (NonOptionArgumentSpec<T>) this;
+    }
+
+    /**
+     * <p>Specifies a converter to use to translate non-option arguments into Java objects.  This is useful
+     * when converting to types that do not have the requisite factory method or constructor for
+     * {@link #ofType(Class)}.</p>
+     *
+     * <p>Invoking this method will trump any previous calls to this method or to {@link #ofType(Class)}.
+     *
+     * @param <T> represents the runtime class of the desired non-option argument type
+     * @param aConverter the converter to use
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws NullPointerException if the converter is {@code null}
+     */
+    @SuppressWarnings( "unchecked" )
+    public final <T> NonOptionArgumentSpec<T> withValuesConvertedBy( ValueConverter<T> aConverter ) {
+        if ( aConverter == null )
+            throw new NullPointerException( "illegal null converter" );
+
+        converter = (ValueConverter<V>) aConverter;
+        return (NonOptionArgumentSpec<T>) this;
+    }
+
+    /**
+     * <p>Specifies a description for the non-option arguments that this spec represents.  This description is used
+     * when generating help information about the parser.</p>
+     *
+     * @param description describes the nature of the argument of this spec's option
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     */
+    public NonOptionArgumentSpec<V> describedAs( String description ) {
+        argumentDescription = description;
+        return this;
+    }
+
+    @Override
+    protected final V convert( String argument ) {
+        return convertWith( converter, argument );
+    }
+
+    @Override
+    void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions,
+        String detectedArgument ) {
+
+        detectedOptions.addWithArgument( this, detectedArgument );
+    }
+
+    public List<?> defaultValues() {
+        return emptyList();
+    }
+
+    public boolean isRequired() {
+        return false;
+    }
+
+    public boolean acceptsArguments() {
+        return false;
+    }
+
+    public boolean requiresArgument() {
+        return false;
+    }
+
+    public String argumentDescription() {
+        return argumentDescription;
+    }
+
+    public String argumentTypeIndicator() {
+        return argumentTypeIndicatorFrom( converter );
+    }
+
+    public boolean representsNonOptions() {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionArgumentConversionException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+
+/**
+ * Thrown when a problem occurs converting an argument of an option from {@link String} to another type.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class OptionArgumentConversionException extends OptionException {
+    private static final long serialVersionUID = -1L;
+
+    private final String argument;
+
+    OptionArgumentConversionException( Collection<String> options, String argument, Throwable cause ) {
+        super( options, cause );
+
+        this.argument = argument;
+    }
+
+    @Override
+    public String getMessage() {
+        return "Cannot parse argument '" + argument + "' of option " + multipleOptionMessage();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDeclarer.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2009, 2015, 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 jdk.internal.joptsimple;
+
+import java.util.Collection;
+
+/**
+ * Trains the option parser. This interface aids integration with other code which may expose declaration of options but
+ * not actual command-line parsing.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ * @see OptionParser
+ */
+public interface OptionDeclarer {
+    /**
+     * Tells the parser to recognize the given option.
+     *
+     * <p>This method returns an instance of {@link OptionSpecBuilder} to allow the formation of parser directives
+     * as sentences in a fluent interface language. For example:</p>
+     *
+     * <pre><code>
+     *   OptionDeclarer parser = new OptionParser();
+     *   parser.<strong>accepts( "c" )</strong>.withRequiredArg().ofType( Integer.class );
+     * </code></pre>
+     *
+     * <p>If no methods are invoked on the returned {@link OptionSpecBuilder}, then the parser treats the option as
+     * accepting no argument.</p>
+     *
+     * @param option the option to recognize
+     * @return an object that can be used to flesh out more detail about the option
+     * @throws OptionException if the option contains illegal characters
+     * @throws NullPointerException if the option is {@code null}
+     */
+    OptionSpecBuilder accepts( String option );
+
+    /**
+     * Tells the parser to recognize the given option.
+     *
+     * @see #accepts(String)
+     * @param option the option to recognize
+     * @param description a string that describes the purpose of the option. This is used when generating help
+     * information about the parser.
+     * @return an object that can be used to flesh out more detail about the option
+     * @throws OptionException if the option contains illegal characters
+     * @throws NullPointerException if the option is {@code null}
+     */
+    OptionSpecBuilder accepts( String option, String description );
+
+    /**
+     * Tells the parser to recognize the given options, and treat them as synonymous.
+     *
+     * @see #accepts(String)
+     * @param options the options to recognize and treat as synonymous
+     * @return an object that can be used to flesh out more detail about the options
+     * @throws OptionException if any of the options contain illegal characters
+     * @throws NullPointerException if the option list or any of its elements are {@code null}
+     */
+    OptionSpecBuilder acceptsAll( Collection<String> options );
+
+    /**
+     * Tells the parser to recognize the given options, and treat them as synonymous.
+     *
+     * @see #acceptsAll(Collection)
+     * @param options the options to recognize and treat as synonymous
+     * @param description a string that describes the purpose of the option.  This is used when generating help
+     * information about the parser.
+     * @return an object that can be used to flesh out more detail about the options
+     * @throws OptionException if any of the options contain illegal characters
+     * @throws NullPointerException if the option list or any of its elements are {@code null}
+     * @throws IllegalArgumentException if the option list is empty
+     */
+    OptionSpecBuilder acceptsAll( Collection<String> options, String description );
+
+    /**
+     * Gives an object that represents an access point for non-option arguments on a command line.
+     *
+     * @return an object that can be used to flesh out more detail about the non-option arguments
+     */
+    NonOptionArgumentSpec<String> nonOptions();
+
+    /**
+     * Gives an object that represents an access point for non-option arguments on a command line.
+     *
+     * @see #nonOptions()
+     * @param description a string that describes the purpose of the non-option arguments. This is used when generating
+     * help information about the parser.
+     * @return an object that can be used to flesh out more detail about the non-option arguments
+     */
+    NonOptionArgumentSpec<String> nonOptions( String description );
+
+    /**
+     * Tells the parser whether or not to behave "POSIX-ly correct"-ly.
+     *
+     * @param setting {@code true} if the parser should behave "POSIX-ly correct"-ly
+     */
+    void posixlyCorrect( boolean setting );
+
+    /**
+     * <p>Tells the parser to treat unrecognized options as non-option arguments.</p>
+     *
+     * <p>If not called, then the parser raises an {@link OptionException} when it encounters an unrecognized
+     * option.</p>
+     */
+    void allowsUnrecognizedOptions();
+
+    /**
+     * Tells the parser either to recognize or ignore <kbd>"-W"</kbd>-style long options.
+     *
+     * @param recognize {@code true} if the parser is to recognize the special style of long options
+     */
+    void recognizeAlternativeLongOptions( boolean recognize );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionDescriptor.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Describes options that an option parser recognizes, in ways that might be useful to {@linkplain HelpFormatter
+ * help screens}.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public interface OptionDescriptor {
+    /**
+     * A set of options that are mutually synonymous.
+     *
+     * @return synonymous options
+     */
+    Collection<String> options();
+
+    /**
+     * Description of this option's purpose.
+     *
+     * @return a description for the option
+     */
+    String description();
+
+    /**
+     * What values will the option take if none are specified on the command line?
+     *
+     * @return any default values for the option
+     */
+    List<?> defaultValues();
+
+    /**
+     * Is this option {@linkplain ArgumentAcceptingOptionSpec#required() required} on a command line?
+     *
+     * @return whether the option is required
+     */
+    boolean isRequired();
+
+    /**
+     * Does this option {@linkplain ArgumentAcceptingOptionSpec accept arguments}?
+     *
+     * @return whether the option accepts arguments
+     */
+    boolean acceptsArguments();
+
+    /**
+     * Does this option {@linkplain OptionSpecBuilder#withRequiredArg() require an argument}?
+     *
+     * @return whether the option requires an argument
+     */
+    boolean requiresArgument();
+
+    /**
+     * Gives a short {@linkplain ArgumentAcceptingOptionSpec#describedAs(String) description} of the option's argument.
+     *
+     * @return a description for the option's argument
+     */
+    String argumentDescription();
+
+    /**
+     * Gives an indication of the {@linkplain ArgumentAcceptingOptionSpec#ofType(Class) expected type} of the option's
+     * argument.
+     *
+     * @return a description for the option's argument type
+     */
+    String argumentTypeIndicator();
+
+    /**
+     * Tells whether this object represents the non-option arguments of a command line.
+     *
+     * @return {@code true} if this represents non-option arguments
+     */
+    boolean representsNonOptions();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import static java.util.Collections.*;
+
+import static jdk.internal.joptsimple.internal.Strings.*;
+
+/**
+ * Thrown when a problem occurs during option parsing.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public abstract class OptionException extends RuntimeException {
+    private static final long serialVersionUID = -1L;
+
+    private final List<String> options = new ArrayList<String>();
+
+    protected OptionException( Collection<String> options ) {
+        this.options.addAll( options );
+    }
+
+    protected OptionException( Collection<String> options, Throwable cause ) {
+        super( cause );
+
+        this.options.addAll( options );
+    }
+
+    /**
+     * Gives the option being considered when the exception was created.
+     *
+     * @return the option being considered when the exception was created
+     */
+    public Collection<String> options() {
+        return unmodifiableCollection( options );
+    }
+
+    protected final String singleOptionMessage() {
+        return singleOptionMessage( options.get( 0 ) );
+    }
+
+    protected final String singleOptionMessage( String option ) {
+        return SINGLE_QUOTE + option + SINGLE_QUOTE;
+    }
+
+    protected final String multipleOptionMessage() {
+        StringBuilder buffer = new StringBuilder( "[" );
+
+        for ( Iterator<String> iter = options.iterator(); iter.hasNext(); ) {
+            buffer.append( singleOptionMessage( iter.next() ) );
+            if ( iter.hasNext() )
+                buffer.append( ", " );
+        }
+
+        buffer.append( ']' );
+
+        return buffer.toString();
+    }
+
+    static OptionException unrecognizedOption( String option ) {
+        return new UnrecognizedOptionException( option );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionMissingRequiredArgumentException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+
+/**
+ * Thrown when the option parser discovers an option that requires an argument, but that argument is missing.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class OptionMissingRequiredArgumentException extends OptionException {
+    private static final long serialVersionUID = -1L;
+
+    OptionMissingRequiredArgumentException( Collection<String> options ) {
+        super( options );
+    }
+
+    @Override
+    public String getMessage() {
+        return "Option " + multipleOptionMessage() + " requires an argument";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParser.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,580 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import jdk.internal.joptsimple.internal.AbbreviationMap;
+import jdk.internal.joptsimple.util.KeyValuePair;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static java.util.Collections.*;
+import static jdk.internal.joptsimple.OptionException.*;
+import static jdk.internal.joptsimple.OptionParserState.*;
+import static jdk.internal.joptsimple.ParserRules.*;
+
+/**
+ * <p>Parses command line arguments, using a syntax that attempts to take from the best of POSIX {@code getopt()}
+ * and GNU {@code getopt_long()}.</p>
+ *
+ * <p>This parser supports short options and long options.</p>
+ *
+ * <ul>
+ *   <li><dfn>Short options</dfn> begin with a single hyphen ("<kbd>-</kbd>") followed by a single letter or digit,
+ *   or question mark ("<kbd>?</kbd>"), or dot ("<kbd>.</kbd>").</li>
+ *
+ *   <li>Short options can accept single arguments. The argument can be made required or optional. The option's
+ *   argument can occur:
+ *     <ul>
+ *       <li>in the slot after the option, as in <kbd>-d /tmp</kbd></li>
+ *       <li>right up against the option, as in <kbd>-d/tmp</kbd></li>
+ *       <li>right up against the option separated by an equals sign (<kbd>"="</kbd>), as in <kbd>-d=/tmp</kbd></li>
+ *     </ul>
+ *   To specify <em>n</em> arguments for an option, specify the option <em>n</em> times, once for each argument,
+ *   as in <kbd>-d /tmp -d /var -d /opt</kbd>; or, when using the
+ *   {@linkplain ArgumentAcceptingOptionSpec#withValuesSeparatedBy(char) "separated values"} clause of the "fluent
+ *   interface" (see below), give multiple values separated by a given character as a single argument to the
+ *   option.</li>
+ *
+ *   <li>Short options can be clustered, so that <kbd>-abc</kbd> is treated as <kbd>-a -b -c</kbd>. If a short option
+ *   in the cluster can accept an argument, the remaining characters are interpreted as the argument for that
+ *   option.</li>
+ *
+ *   <li>An argument consisting only of two hyphens (<kbd>"--"</kbd>) signals that the remaining arguments are to be
+ *   treated as non-options.</li>
+ *
+ *   <li>An argument consisting only of a single hyphen is considered a non-option argument (though it can be an
+ *   argument of an option). Many Unix programs treat single hyphens as stand-ins for the standard input or standard
+ *   output streams.</li>
+ *
+ *   <li><dfn>Long options</dfn> begin with two hyphens (<kbd>"--"</kbd>), followed by multiple letters, digits,
+ *   hyphens, question marks, or dots. A hyphen cannot be the first character of a long option specification when
+ *   configuring the parser.</li>
+ *
+ *   <li>You can abbreviate long options, so long as the abbreviation is unique.</li>
+ *
+ *   <li>Long options can accept single arguments.  The argument can be made required or optional.  The option's
+ *   argument can occur:
+ *     <ul>
+ *       <li>in the slot after the option, as in <kbd>--directory /tmp</kbd></li>
+ *       <li>right up against the option separated by an equals sign (<kbd>"="</kbd>), as in
+ *       <kbd>--directory=/tmp</kbd>
+ *     </ul>
+ *   Specify multiple arguments for a long option in the same manner as for short options (see above).</li>
+ *
+ *   <li>You can use a single hyphen (<kbd>"-"</kbd>) instead of a double hyphen (<kbd>"--"</kbd>) for a long
+ *   option.</li>
+ *
+ *   <li>The option <kbd>-W</kbd> is reserved.  If you tell the parser to {@linkplain
+ *   #recognizeAlternativeLongOptions(boolean) recognize alternative long options}, then it will treat, for example,
+ *   <kbd>-W foo=bar</kbd> as the long option <kbd>foo</kbd> with argument <kbd>bar</kbd>, as though you had written
+ *   <kbd>--foo=bar</kbd>.</li>
+ *
+ *   <li>You can specify <kbd>-W</kbd> as a valid short option, or use it as an abbreviation for a long option, but
+ *   {@linkplain #recognizeAlternativeLongOptions(boolean) recognizing alternative long options} will always supersede
+ *   this behavior.</li>
+ *
+ *   <li>You can specify a given short or long option multiple times on a single command line. The parser collects
+ *   any arguments specified for those options as a list.</li>
+ *
+ *   <li>If the parser detects an option whose argument is optional, and the next argument "looks like" an option,
+ *   that argument is not treated as the argument to the option, but as a potentially valid option. If, on the other
+ *   hand, the optional argument is typed as a derivative of {@link Number}, then that argument is treated as the
+ *   negative number argument of the option, even if the parser recognizes the corresponding numeric option.
+ *   For example:
+ *   <pre><code>
+ *     OptionParser parser = new OptionParser();
+ *     parser.accepts( "a" ).withOptionalArg().ofType( Integer.class );
+ *     parser.accepts( "2" );
+ *     OptionSet options = parser.parse( "-a", "-2" );
+ *   </code></pre>
+ *   In this case, the option set contains <kbd>"a"</kbd> with argument <kbd>-2</kbd>, not both <kbd>"a"</kbd> and
+ *   <kbd>"2"</kbd>. Swapping the elements in the <em>args</em> array gives the latter.</li>
+ * </ul>
+ *
+ * <p>There are two ways to tell the parser what options to recognize:</p>
+ *
+ * <ol>
+ *   <li>A "fluent interface"-style API for specifying options, available since version 2. Sentences in this fluent
+ *   interface language begin with a call to {@link #accepts(String) accepts} or {@link #acceptsAll(Collection)
+ *   acceptsAll} methods; calls on the ensuing chain of objects describe whether the options can take an argument,
+ *   whether the argument is required or optional, to what type arguments of the options should be converted if any,
+ *   etc. Since version 3, these calls return an instance of {@link OptionSpec}, which can subsequently be used to
+ *   retrieve the arguments of the associated option in a type-safe manner.</li>
+ *
+ *   <li>Since version 1, a more concise way of specifying short options has been to use the special {@linkplain
+ *   #OptionParser(String) constructor}. Arguments of options specified in this manner will be of type {@link String}.
+ *   Here are the rules for the format of the specification strings this constructor accepts:
+ *
+ *     <ul>
+ *       <li>Any letter or digit is treated as an option character.</li>
+ *
+ *       <li>An option character can be immediately followed by an asterisk (*) to indicate that the option is a
+ *       "help" option.</li>
+ *
+ *       <li>If an option character (with possible trailing asterisk) is followed by a single colon (<kbd>":"</kbd>),
+ *       then the option requires an argument.</li>
+ *
+ *       <li>If an option character (with possible trailing asterisk) is followed by two colons (<kbd>"::"</kbd>),
+ *       then the option accepts an optional argument.</li>
+ *
+ *       <li>Otherwise, the option character accepts no argument.</li>
+ *
+ *       <li>If the option specification string begins with a plus sign (<kbd>"+"</kbd>), the parser will behave
+ *       "POSIX-ly correct".</li>
+ *
+ *       <li>If the option specification string contains the sequence <kbd>"W;"</kbd> (capital W followed by a
+ *       semicolon), the parser will recognize the alternative form of long options.</li>
+ *     </ul>
+ *   </li>
+ * </ol>
+ *
+ * <p>Each of the options in a list of options given to {@link #acceptsAll(Collection) acceptsAll} is treated as a
+ * synonym of the others.  For example:
+ *   <pre>
+ *     <code>
+ *     OptionParser parser = new OptionParser();
+ *     parser.acceptsAll( asList( "w", "interactive", "confirmation" ) );
+ *     OptionSet options = parser.parse( "-w" );
+ *     </code>
+ *   </pre>
+ * In this case, <code>options.{@link OptionSet#has(String) has}</code> would answer {@code true} when given arguments
+ * <kbd>"w"</kbd>, <kbd>"interactive"</kbd>, and <kbd>"confirmation"</kbd>. The {@link OptionSet} would give the same
+ * responses to these arguments for its other methods as well.</p>
+ *
+ * <p>By default, as with GNU {@code getopt()}, the parser allows intermixing of options and non-options. If, however,
+ * the parser has been created to be "POSIX-ly correct", then the first argument that does not look lexically like an
+ * option, and is not a required argument of a preceding option, signals the end of options. You can still bind
+ * optional arguments to their options using the abutting (for short options) or <kbd>=</kbd> syntax.</p>
+ *
+ * <p>Unlike GNU {@code getopt()}, this parser does not honor the environment variable {@code POSIXLY_CORRECT}.
+ * "POSIX-ly correct" parsers are configured by either:</p>
+ *
+ * <ol>
+ *   <li>using the method {@link #posixlyCorrect(boolean)}, or</li>
+ *
+ *   <li>using the {@linkplain #OptionParser(String) constructor} with an argument whose first character is a plus sign
+ *   (<kbd>"+"</kbd>)</li>
+ * </ol>
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ * @see <a href="http://www.gnu.org/software/libc/manual">The GNU C Library</a>
+ */
+public class OptionParser implements OptionDeclarer {
+    private final AbbreviationMap<AbstractOptionSpec<?>> recognizedOptions;
+    private final Map<Collection<String>, Set<OptionSpec<?>>> requiredIf;
+    private final Map<Collection<String>, Set<OptionSpec<?>>> requiredUnless;
+    private OptionParserState state;
+    private boolean posixlyCorrect;
+    private boolean allowsUnrecognizedOptions;
+    private HelpFormatter helpFormatter = new BuiltinHelpFormatter();
+
+    /**
+     * Creates an option parser that initially recognizes no options, and does not exhibit "POSIX-ly correct"
+     * behavior.
+     */
+    public OptionParser() {
+        recognizedOptions = new AbbreviationMap<AbstractOptionSpec<?>>();
+        requiredIf = new HashMap<Collection<String>, Set<OptionSpec<?>>>();
+        requiredUnless = new HashMap<Collection<String>, Set<OptionSpec<?>>>();
+        state = moreOptions( false );
+
+        recognize( new NonOptionArgumentSpec<String>() );
+    }
+
+    /**
+     * Creates an option parser and configures it to recognize the short options specified in the given string.
+     *
+     * Arguments of options specified this way will be of type {@link String}.
+     *
+     * @param optionSpecification an option specification
+     * @throws NullPointerException if {@code optionSpecification} is {@code null}
+     * @throws OptionException if the option specification contains illegal characters or otherwise cannot be
+     * recognized
+     */
+    public OptionParser( String optionSpecification ) {
+        this();
+
+        new OptionSpecTokenizer( optionSpecification ).configure( this );
+    }
+
+    public OptionSpecBuilder accepts( String option ) {
+        return acceptsAll( singletonList( option ) );
+    }
+
+    public OptionSpecBuilder accepts( String option, String description ) {
+        return acceptsAll( singletonList( option ), description );
+    }
+
+    public OptionSpecBuilder acceptsAll( Collection<String> options ) {
+        return acceptsAll( options, "" );
+    }
+
+    public OptionSpecBuilder acceptsAll( Collection<String> options, String description ) {
+        if ( options.isEmpty() )
+            throw new IllegalArgumentException( "need at least one option" );
+
+        ensureLegalOptions( options );
+
+        return new OptionSpecBuilder( this, options, description );
+    }
+
+    public NonOptionArgumentSpec<String> nonOptions() {
+        NonOptionArgumentSpec<String> spec = new NonOptionArgumentSpec<String>();
+
+        recognize( spec );
+
+        return spec;
+    }
+
+    public NonOptionArgumentSpec<String> nonOptions( String description ) {
+        NonOptionArgumentSpec<String> spec = new NonOptionArgumentSpec<String>( description );
+
+        recognize( spec );
+
+        return spec;
+    }
+
+    public void posixlyCorrect( boolean setting ) {
+        posixlyCorrect = setting;
+        state = moreOptions( setting );
+    }
+
+    boolean posixlyCorrect() {
+        return posixlyCorrect;
+    }
+
+    public void allowsUnrecognizedOptions() {
+        allowsUnrecognizedOptions = true;
+    }
+
+    boolean doesAllowsUnrecognizedOptions() {
+        return allowsUnrecognizedOptions;
+    }
+
+    public void recognizeAlternativeLongOptions( boolean recognize ) {
+        if ( recognize )
+            recognize( new AlternativeLongOptionSpec() );
+        else
+            recognizedOptions.remove( String.valueOf( RESERVED_FOR_EXTENSIONS ) );
+    }
+
+    void recognize( AbstractOptionSpec<?> spec ) {
+        recognizedOptions.putAll( spec.options(), spec );
+    }
+
+    /**
+     * Writes information about the options this parser recognizes to the given output sink.
+     *
+     * The output sink is flushed, but not closed.
+     *
+     * @param sink the sink to write information to
+     * @throws IOException if there is a problem writing to the sink
+     * @throws NullPointerException if {@code sink} is {@code null}
+     * @see #printHelpOn(Writer)
+     */
+    public void printHelpOn( OutputStream sink ) throws IOException {
+        printHelpOn( new OutputStreamWriter( sink ) );
+    }
+
+    /**
+     * Writes information about the options this parser recognizes to the given output sink.
+     *
+     * The output sink is flushed, but not closed.
+     *
+     * @param sink the sink to write information to
+     * @throws IOException if there is a problem writing to the sink
+     * @throws NullPointerException if {@code sink} is {@code null}
+     * @see #printHelpOn(OutputStream)
+     */
+    public void printHelpOn( Writer sink ) throws IOException {
+        sink.write( helpFormatter.format( recognizedOptions.toJavaUtilMap() ) );
+        sink.flush();
+    }
+
+    /**
+     * Tells the parser to use the given formatter when asked to {@linkplain #printHelpOn(java.io.Writer) print help}.
+     *
+     * @param formatter the formatter to use for printing help
+     * @throws NullPointerException if the formatter is {@code null}
+     */
+    public void formatHelpWith( HelpFormatter formatter ) {
+        if ( formatter == null )
+            throw new NullPointerException();
+
+        helpFormatter = formatter;
+    }
+
+    /**
+     * Retrieves all the options which have been configured for the parser.
+     *
+     * @return a {@link Map} containing all the configured options and their corresponding {@link OptionSpec}
+     */
+    public Map<String, OptionSpec<?>> recognizedOptions() {
+        return new HashMap<String, OptionSpec<?>>( recognizedOptions.toJavaUtilMap() );
+    }
+
+    /**
+     * Parses the given command line arguments according to the option specifications given to the parser.
+     *
+     * @param arguments arguments to parse
+     * @return an {@link OptionSet} describing the parsed options, their arguments, and any non-option arguments found
+     * @throws OptionException if problems are detected while parsing
+     * @throws NullPointerException if the argument list is {@code null}
+     */
+    public OptionSet parse( String... arguments ) {
+        ArgumentList argumentList = new ArgumentList( arguments );
+        OptionSet detected = new OptionSet( recognizedOptions.toJavaUtilMap() );
+        detected.add( recognizedOptions.get( NonOptionArgumentSpec.NAME ) );
+
+        while ( argumentList.hasMore() )
+            state.handleArgument( this, argumentList, detected );
+
+        reset();
+
+        ensureRequiredOptions( detected );
+
+        return detected;
+    }
+
+    private void ensureRequiredOptions( OptionSet options ) {
+        Collection<String> missingRequiredOptions = missingRequiredOptions( options );
+        boolean helpOptionPresent = isHelpOptionPresent( options );
+
+        if ( !missingRequiredOptions.isEmpty() && !helpOptionPresent )
+            throw new MissingRequiredOptionException( missingRequiredOptions );
+    }
+
+    private Collection<String> missingRequiredOptions( OptionSet options ) {
+        Collection<String> missingRequiredOptions = new HashSet<String>();
+
+        for ( AbstractOptionSpec<?> each : recognizedOptions.toJavaUtilMap().values() ) {
+            if ( each.isRequired() && !options.has( each ) )
+                missingRequiredOptions.addAll( each.options() );
+        }
+
+        for ( Map.Entry<Collection<String>, Set<OptionSpec<?>>> eachEntry : requiredIf.entrySet() ) {
+            AbstractOptionSpec<?> required = specFor( eachEntry.getKey().iterator().next() );
+
+            if ( optionsHasAnyOf( options, eachEntry.getValue() ) && !options.has( required ) ) {
+                missingRequiredOptions.addAll( required.options() );
+            }
+        }
+
+        for ( Map.Entry<Collection<String>, Set<OptionSpec<?>>> eachEntry : requiredUnless.entrySet() ) {
+            AbstractOptionSpec<?> required = specFor( eachEntry.getKey().iterator().next() );
+
+            if ( !optionsHasAnyOf( options, eachEntry.getValue() ) && !options.has( required ) ) {
+                missingRequiredOptions.addAll( required.options() );
+            }
+        }
+
+        return missingRequiredOptions;
+    }
+
+    private boolean optionsHasAnyOf( OptionSet options, Collection<OptionSpec<?>> specs ) {
+        for ( OptionSpec<?> each : specs ) {
+            if ( options.has( each ) )
+                return true;
+        }
+
+        return false;
+    }
+
+    private boolean isHelpOptionPresent( OptionSet options ) {
+        boolean helpOptionPresent = false;
+        for ( AbstractOptionSpec<?> each : recognizedOptions.toJavaUtilMap().values() ) {
+            if ( each.isForHelp() && options.has( each ) ) {
+                helpOptionPresent = true;
+                break;
+            }
+        }
+        return helpOptionPresent;
+    }
+
+    void handleLongOptionToken( String candidate, ArgumentList arguments, OptionSet detected ) {
+        KeyValuePair optionAndArgument = parseLongOptionWithArgument( candidate );
+
+        if ( !isRecognized( optionAndArgument.key ) )
+            throw unrecognizedOption( optionAndArgument.key );
+
+        AbstractOptionSpec<?> optionSpec = specFor( optionAndArgument.key );
+        optionSpec.handleOption( this, arguments, detected, optionAndArgument.value );
+    }
+
+    void handleShortOptionToken( String candidate, ArgumentList arguments, OptionSet detected ) {
+        KeyValuePair optionAndArgument = parseShortOptionWithArgument( candidate );
+
+        if ( isRecognized( optionAndArgument.key ) ) {
+            specFor( optionAndArgument.key ).handleOption( this, arguments, detected, optionAndArgument.value );
+        }
+        else
+            handleShortOptionCluster( candidate, arguments, detected );
+    }
+
+    private void handleShortOptionCluster( String candidate, ArgumentList arguments, OptionSet detected ) {
+        char[] options = extractShortOptionsFrom( candidate );
+        validateOptionCharacters( options );
+
+        for ( int i = 0; i < options.length; i++ ) {
+            AbstractOptionSpec<?> optionSpec = specFor( options[ i ] );
+
+            if ( optionSpec.acceptsArguments() && options.length > i + 1 ) {
+                String detectedArgument = String.valueOf( options, i + 1, options.length - 1 - i );
+                optionSpec.handleOption( this, arguments, detected, detectedArgument );
+                break;
+            }
+
+            optionSpec.handleOption( this, arguments, detected, null );
+        }
+    }
+
+    void handleNonOptionArgument( String candidate, ArgumentList arguments, OptionSet detectedOptions ) {
+        specFor( NonOptionArgumentSpec.NAME ).handleOption( this, arguments, detectedOptions, candidate );
+    }
+
+    void noMoreOptions() {
+        state = OptionParserState.noMoreOptions();
+    }
+
+    boolean looksLikeAnOption( String argument ) {
+        return isShortOptionToken( argument ) || isLongOptionToken( argument );
+    }
+
+    boolean isRecognized( String option ) {
+        return recognizedOptions.contains( option );
+    }
+
+    void requiredIf( Collection<String> precedentSynonyms, String required ) {
+        requiredIf( precedentSynonyms, specFor( required ) );
+    }
+
+    void requiredIf( Collection<String> precedentSynonyms, OptionSpec<?> required ) {
+        putRequiredOption( precedentSynonyms, required, requiredIf );
+    }
+
+    void requiredUnless( Collection<String> precedentSynonyms, String required ) {
+        requiredUnless( precedentSynonyms, specFor( required ) );
+    }
+
+    void requiredUnless( Collection<String> precedentSynonyms, OptionSpec<?> required ) {
+        putRequiredOption( precedentSynonyms, required, requiredUnless );
+    }
+
+    private void putRequiredOption( Collection<String> precedentSynonyms, OptionSpec<?> required,
+        Map<Collection<String>, Set<OptionSpec<?>>> target ) {
+
+        for ( String each : precedentSynonyms ) {
+            AbstractOptionSpec<?> spec = specFor( each );
+            if ( spec == null )
+                throw new UnconfiguredOptionException( precedentSynonyms );
+        }
+
+        Set<OptionSpec<?>> associated = target.get( precedentSynonyms );
+        if ( associated == null ) {
+            associated = new HashSet<OptionSpec<?>>();
+            target.put( precedentSynonyms, associated );
+        }
+
+        associated.add( required );
+    }
+
+    private AbstractOptionSpec<?> specFor( char option ) {
+        return specFor( String.valueOf( option ) );
+    }
+
+    private AbstractOptionSpec<?> specFor( String option ) {
+        return recognizedOptions.get( option );
+    }
+
+    private void reset() {
+        state = moreOptions( posixlyCorrect );
+    }
+
+    private static char[] extractShortOptionsFrom( String argument ) {
+        char[] options = new char[ argument.length() - 1 ];
+        argument.getChars( 1, argument.length(), options, 0 );
+
+        return options;
+    }
+
+    private void validateOptionCharacters( char[] options ) {
+        for ( char each : options ) {
+            String option = String.valueOf( each );
+
+            if ( !isRecognized( option ) )
+                throw unrecognizedOption( option );
+
+            if ( specFor( option ).acceptsArguments() )
+                return;
+        }
+    }
+
+    private static KeyValuePair parseLongOptionWithArgument( String argument ) {
+        return KeyValuePair.valueOf( argument.substring( 2 ) );
+    }
+
+    private static KeyValuePair parseShortOptionWithArgument( String argument ) {
+        return KeyValuePair.valueOf( argument.substring( 1 ) );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionParserState.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import static jdk.internal.joptsimple.ParserRules.*;
+
+/**
+ * Abstraction of parser state; mostly serves to model how a parser behaves depending on whether end-of-options
+ * has been detected.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+abstract class OptionParserState {
+    static OptionParserState noMoreOptions() {
+        return new OptionParserState() {
+            @Override
+            protected void handleArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
+                parser.handleNonOptionArgument( arguments.next(), arguments, detectedOptions );
+            }
+        };
+    }
+
+    static OptionParserState moreOptions( final boolean posixlyCorrect ) {
+        return new OptionParserState() {
+            @Override
+            protected void handleArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
+                String candidate = arguments.next();
+                try {
+                    if ( isOptionTerminator( candidate ) ) {
+                        parser.noMoreOptions();
+                        return;
+                    } else if ( isLongOptionToken( candidate ) ) {
+                        parser.handleLongOptionToken( candidate, arguments, detectedOptions );
+                        return;
+                    } else if ( isShortOptionToken( candidate ) ) {
+                        parser.handleShortOptionToken( candidate, arguments, detectedOptions );
+                        return;
+                    }
+                } catch ( UnrecognizedOptionException e ) {
+                    if ( !parser.doesAllowsUnrecognizedOptions() )
+                        throw e;
+                }
+
+                if ( posixlyCorrect )
+                    parser.noMoreOptions();
+
+                parser.handleNonOptionArgument( candidate, arguments, detectedOptions );
+            }
+        };
+    }
+
+    protected abstract void handleArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSet.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.*;
+
+import static java.util.Collections.*;
+
+import static jdk.internal.joptsimple.internal.Objects.*;
+
+/**
+ * Representation of a group of detected command line options, their arguments, and non-option arguments.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public class OptionSet {
+    private final List<OptionSpec<?>> detectedSpecs;
+    private final Map<String, AbstractOptionSpec<?>> detectedOptions;
+    private final Map<AbstractOptionSpec<?>, List<String>> optionsToArguments;
+    private final Map<String, AbstractOptionSpec<?>> recognizedSpecs;
+    private final Map<String, List<?>> defaultValues;
+
+    /*
+     * Package-private because clients don't create these.
+     */
+    OptionSet( Map<String, AbstractOptionSpec<?>> recognizedSpecs ) {
+        detectedSpecs = new ArrayList<OptionSpec<?>>();
+        detectedOptions = new HashMap<String, AbstractOptionSpec<?>>();
+        optionsToArguments = new IdentityHashMap<AbstractOptionSpec<?>, List<String>>();
+        defaultValues = defaultValues( recognizedSpecs );
+        this.recognizedSpecs = recognizedSpecs;
+    }
+
+    /**
+     * Tells whether any options were detected.
+     *
+     * @return {@code true} if any options were detected
+     */
+    public boolean hasOptions() {
+        return !detectedOptions.isEmpty();
+    }
+
+    /**
+     * Tells whether the given option was detected.
+     *
+     * @param option the option to search for
+     * @return {@code true} if the option was detected
+     * @see #has(OptionSpec)
+     */
+    public boolean has( String option ) {
+        return detectedOptions.containsKey( option );
+    }
+
+    /**
+     * Tells whether the given option was detected.
+     *
+     * <p>This method recognizes only instances of options returned from the fluent interface methods.</p>
+     *
+     * <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[])} default argument value}
+     * for an option does not cause this method to return {@code true} if the option was not detected on the command
+     * line.</p>
+     *
+     * @param option the option to search for
+     * @return {@code true} if the option was detected
+     * @see #has(String)
+     */
+    public boolean has( OptionSpec<?> option ) {
+        return optionsToArguments.containsKey( option );
+    }
+
+    /**
+     * Tells whether there are any arguments associated with the given option.
+     *
+     * @param option the option to search for
+     * @return {@code true} if the option was detected and at least one argument was detected for the option
+     * @see #hasArgument(OptionSpec)
+     */
+    public boolean hasArgument( String option ) {
+        AbstractOptionSpec<?> spec = detectedOptions.get( option );
+        return spec != null && hasArgument( spec );
+    }
+
+    /**
+     * Tells whether there are any arguments associated with the given option.
+     *
+     * <p>This method recognizes only instances of options returned from the fluent interface methods.</p>
+     *
+     * <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value}
+     * for an option does not cause this method to return {@code true} if the option was not detected on the command
+     * line, or if the option can take an optional argument but did not have one on the command line.</p>
+     *
+     * @param option the option to search for
+     * @return {@code true} if the option was detected and at least one argument was detected for the option
+     * @throws NullPointerException if {@code option} is {@code null}
+     * @see #hasArgument(String)
+     */
+    public boolean hasArgument( OptionSpec<?> option ) {
+        ensureNotNull( option );
+
+        List<String> values = optionsToArguments.get( option );
+        return values != null && !values.isEmpty();
+    }
+
+    /**
+     * Gives the argument associated with the given option.  If the option was given an argument type, the argument
+     * will take on that type; otherwise, it will be a {@link String}.
+     *
+     * <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value}
+     * for an option will cause this method to return that default value even if the option was not detected on the
+     * command line, or if the option can take an optional argument but did not have one on the command line.</p>
+     *
+     * @param option the option to search for
+     * @return the argument of the given option; {@code null} if no argument is present, or that option was not
+     * detected
+     * @throws NullPointerException if {@code option} is {@code null}
+     * @throws OptionException if more than one argument was detected for the option
+     */
+    public Object valueOf( String option ) {
+        ensureNotNull( option );
+
+        AbstractOptionSpec<?> spec = detectedOptions.get( option );
+        if ( spec == null ) {
+            List<?> defaults = defaultValuesFor( option );
+            return defaults.isEmpty() ? null : defaults.get( 0 );
+        }
+
+        return valueOf( spec );
+    }
+
+    /**
+     * Gives the argument associated with the given option.
+     *
+     * <p>This method recognizes only instances of options returned from the fluent interface methods.</p>
+     *
+     * @param <V> represents the type of the arguments the given option accepts
+     * @param option the option to search for
+     * @return the argument of the given option; {@code null} if no argument is present, or that option was not
+     * detected
+     * @throws OptionException if more than one argument was detected for the option
+     * @throws NullPointerException if {@code option} is {@code null}
+     * @throws ClassCastException if the arguments of this option are not of the expected type
+     */
+    public <V> V valueOf( OptionSpec<V> option ) {
+        ensureNotNull( option );
+
+        List<V> values = valuesOf( option );
+        switch ( values.size() ) {
+            case 0:
+                return null;
+            case 1:
+                return values.get( 0 );
+            default:
+                throw new MultipleArgumentsForOptionException( option.options() );
+        }
+    }
+
+    /**
+     * <p>Gives any arguments associated with the given option.  If the option was given an argument type, the
+     * arguments will take on that type; otherwise, they will be {@link String}s.</p>
+     *
+     * @param option the option to search for
+     * @return the arguments associated with the option, as a list of objects of the type given to the arguments; an
+     * empty list if no such arguments are present, or if the option was not detected
+     * @throws NullPointerException if {@code option} is {@code null}
+     */
+    public List<?> valuesOf( String option ) {
+        ensureNotNull( option );
+
+        AbstractOptionSpec<?> spec = detectedOptions.get( option );
+        return spec == null ? defaultValuesFor( option ) : valuesOf( spec );
+    }
+
+    /**
+     * <p>Gives any arguments associated with the given option.  If the option was given an argument type, the
+     * arguments will take on that type; otherwise, they will be {@link String}s.</p>
+     *
+     * <p>This method recognizes only instances of options returned from the fluent interface methods.</p>
+     *
+     * @param <V> represents the type of the arguments the given option accepts
+     * @param option the option to search for
+     * @return the arguments associated with the option; an empty list if no such arguments are present, or if the
+     * option was not detected
+     * @throws NullPointerException if {@code option} is {@code null}
+     * @throws OptionException if there is a problem converting the option's arguments to the desired type; for
+     * example, if the type does not implement a correct conversion constructor or method
+     */
+    public <V> List<V> valuesOf( OptionSpec<V> option ) {
+        ensureNotNull( option );
+
+        List<String> values = optionsToArguments.get( option );
+        if ( values == null || values.isEmpty() )
+            return defaultValueFor( option );
+
+        AbstractOptionSpec<V> spec = (AbstractOptionSpec<V>) option;
+        List<V> convertedValues = new ArrayList<V>();
+        for ( String each : values )
+            convertedValues.add( spec.convert( each ) );
+
+        return unmodifiableList( convertedValues );
+    }
+
+    /**
+     * Gives the set of options that were detected, in the form of {@linkplain OptionSpec}s, in the order in which the
+     * options were found on the command line.
+     *
+     * @return the set of detected command line options
+     */
+    public List<OptionSpec<?>> specs() {
+        List<OptionSpec<?>> specs = detectedSpecs;
+        specs.remove( detectedOptions.get( NonOptionArgumentSpec.NAME ) );
+
+        return unmodifiableList( specs );
+    }
+
+    /**
+     * Gives all declared options as a map of string to {@linkplain OptionSpec}.
+     *
+     * @return the declared options as a map
+     */
+    public Map<OptionSpec<?>, List<?>> asMap() {
+        Map<OptionSpec<?>, List<?>> map = new HashMap<OptionSpec<?>, List<?>>();
+        for ( AbstractOptionSpec<?> spec : recognizedSpecs.values() )
+            if ( !spec.representsNonOptions() )
+                map.put( spec, valuesOf( spec ) );
+        return unmodifiableMap( map );
+    }
+
+    /**
+     * @return the detected non-option arguments
+     */
+    public List<?> nonOptionArguments() {
+        return unmodifiableList( valuesOf( detectedOptions.get( NonOptionArgumentSpec.NAME ) ) );
+    }
+
+    void add( AbstractOptionSpec<?> spec ) {
+        addWithArgument( spec, null );
+    }
+
+    void addWithArgument( AbstractOptionSpec<?> spec, String argument ) {
+        detectedSpecs.add( spec );
+
+        for ( String each : spec.options() )
+            detectedOptions.put( each, spec );
+
+        List<String> optionArguments = optionsToArguments.get( spec );
+
+        if ( optionArguments == null ) {
+            optionArguments = new ArrayList<String>();
+            optionsToArguments.put( spec, optionArguments );
+        }
+
+        if ( argument != null )
+            optionArguments.add( argument );
+    }
+
+    @Override
+    public boolean equals( Object that ) {
+        if ( this == that )
+            return true;
+
+        if ( that == null || !getClass().equals( that.getClass() ) )
+            return false;
+
+        OptionSet other = (OptionSet) that;
+        Map<AbstractOptionSpec<?>, List<String>> thisOptionsToArguments =
+            new HashMap<AbstractOptionSpec<?>, List<String>>( optionsToArguments );
+        Map<AbstractOptionSpec<?>, List<String>> otherOptionsToArguments =
+            new HashMap<AbstractOptionSpec<?>, List<String>>( other.optionsToArguments );
+        return detectedOptions.equals( other.detectedOptions )
+            && thisOptionsToArguments.equals( otherOptionsToArguments );
+    }
+
+    @Override
+    public int hashCode() {
+        Map<AbstractOptionSpec<?>, List<String>> thisOptionsToArguments =
+            new HashMap<AbstractOptionSpec<?>, List<String>>( optionsToArguments );
+        return detectedOptions.hashCode() ^ thisOptionsToArguments.hashCode();
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private <V> List<V> defaultValuesFor( String option ) {
+        if ( defaultValues.containsKey( option ) )
+            return (List<V>) defaultValues.get( option );
+
+        return emptyList();
+    }
+
+    private <V> List<V> defaultValueFor( OptionSpec<V> option ) {
+        return defaultValuesFor( option.options().iterator().next() );
+    }
+
+    private static Map<String, List<?>> defaultValues( Map<String, AbstractOptionSpec<?>> recognizedSpecs ) {
+        Map<String, List<?>> defaults = new HashMap<String, List<?>>();
+        for ( Map.Entry<String, AbstractOptionSpec<?>> each : recognizedSpecs.entrySet() )
+            defaults.put( each.getKey(), each.getValue().defaultValues() );
+        return defaults;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpec.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Describes options that an option parser recognizes.
+ *
+ * <p>Instances of this interface are returned by the "fluent interface" methods to allow retrieval of option arguments
+ * in a type-safe manner.  Here's an example:</p>
+ *
+ * <pre><code>
+ *     OptionParser parser = new OptionParser();
+ *     <strong>OptionSpec&lt;Integer&gt;</strong> count =
+ *         parser.accepts( "count" ).withRequiredArg().ofType( Integer.class );
+ *     OptionSet options = parser.parse( "--count", "2" );
+ *     assert options.has( count );
+ *     int countValue = options.valueOf( count );
+ *     assert countValue == count.value( options );
+ *     List&lt;Integer&gt; countValues = options.valuesOf( count );
+ *     assert countValues.equals( count.values( options ) );
+ * </code></pre>
+ *
+ * @param <V> represents the type of the arguments this option accepts
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public interface OptionSpec<V> {
+    /**
+     * Gives any arguments associated with the given option in the given set of detected options.
+     *
+     * <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value}
+     * for this option will cause this method to return that default value even if this option was not detected on the
+     * command line, or if this option can take an optional argument but did not have one on the command line.</p>
+     *
+     * @param detectedOptions the detected options to search in
+     * @return the arguments associated with this option; an empty list if no such arguments are present, or if this
+     * option was not detected
+     * @throws OptionException if there is a problem converting this option's arguments to the desired type; for
+     * example, if the type does not implement a correct conversion constructor or method
+     * @throws NullPointerException if {@code detectedOptions} is {@code null}
+     * @see OptionSet#valuesOf(OptionSpec)
+     */
+    List<V> values( OptionSet detectedOptions );
+
+    /**
+     * Gives the argument associated with the given option in the given set of detected options.
+     *
+     * <p>Specifying a {@linkplain ArgumentAcceptingOptionSpec#defaultsTo(Object, Object[]) default argument value}
+     * for this option will cause this method to return that default value even if this option was not detected on the
+     * command line, or if this option can take an optional argument but did not have one on the command line.</p>
+     *
+     * @param detectedOptions the detected options to search in
+     * @return the argument of the this option; {@code null} if no argument is present, or that option was not detected
+     * @throws OptionException if more than one argument was detected for the option
+     * @throws NullPointerException if {@code detectedOptions} is {@code null}
+     * @throws ClassCastException if the arguments of this option are not of the expected type
+     * @see OptionSet#valueOf(OptionSpec)
+     */
+    V value( OptionSet detectedOptions );
+
+    /**
+     * @return the string representations of this option
+     */
+    Collection<String> options();
+
+    /**
+     * Tells whether this option is designated as a "help" option. The presence of a "help" option on a command line
+     * means that missing "required" options will not cause parsing to fail.
+     *
+     * @return whether this option is designated as a "help" option
+     */
+    boolean isForHelp();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecBuilder.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Allows callers to specify whether a given option accepts arguments (required or optional).
+ *
+ * <p>Instances are returned from {@link OptionParser#accepts(String)} to allow the formation of parser directives as
+ * sentences in a "fluent interface" language.  For example:</p>
+ *
+ * <pre><code>
+ *   OptionParser parser = new OptionParser();
+ *   parser.accepts( "c" ).<strong>withRequiredArg()</strong>.ofType( Integer.class );
+ * </code></pre>
+ *
+ * <p>If no methods are invoked on an instance of this class, then that instance's option will accept no argument.</p>
+ *
+ * <p>Note that you should not use the fluent interface clauses in a way that would defeat the typing of option
+ * arguments:</p>
+ *
+ * <pre><code>
+ *   OptionParser parser = new OptionParser();
+ *   ArgumentAcceptingOptionSpec&lt;String&gt; optionC =
+ *       parser.accepts( "c" ).withRequiredArg();
+ *   <strong>optionC.ofType( Integer.class );  // DON'T THROW AWAY THE TYPE!</strong>
+ *
+ *   String value = parser.parse( "-c", "2" ).valueOf( optionC );  // ClassCastException
+ * </code></pre>
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public class OptionSpecBuilder extends NoArgumentOptionSpec {
+    private final OptionParser parser;
+
+    OptionSpecBuilder( OptionParser parser, Collection<String> options, String description ) {
+        super( options, description );
+
+        this.parser = parser;
+        attachToParser();
+    }
+
+    private void attachToParser() {
+        parser.recognize( this );
+    }
+
+    /**
+     * Informs an option parser that this builder's option requires an argument.
+     *
+     * @return a specification for the option
+     */
+    public ArgumentAcceptingOptionSpec<String> withRequiredArg() {
+        ArgumentAcceptingOptionSpec<String> newSpec =
+            new RequiredArgumentOptionSpec<String>( options(), description() );
+        parser.recognize( newSpec );
+
+        return newSpec;
+    }
+
+    /**
+     * Informs an option parser that this builder's option accepts an optional argument.
+     *
+     * @return a specification for the option
+     */
+    public ArgumentAcceptingOptionSpec<String> withOptionalArg() {
+        ArgumentAcceptingOptionSpec<String> newSpec =
+            new OptionalArgumentOptionSpec<String>( options(), description() );
+        parser.recognize( newSpec );
+
+        return newSpec;
+    }
+
+    /**
+     * <p>Informs an option parser that this builder's option is required if the given option is present on the command
+     * line.</p>
+     *
+     * <p>For a given option, you <em>should not</em> mix this with {@link #requiredUnless(String, String...)
+     * requiredUnless} to avoid conflicts.</p>
+     *
+     * @param dependent an option whose presence on a command line makes this builder's option required
+     * @param otherDependents other options whose presence on a command line makes this builder's option required
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws OptionException if any of the dependent options haven't been configured in the parser yet
+     */
+    public OptionSpecBuilder requiredIf( String dependent, String... otherDependents ) {
+        List<String> dependents = validatedDependents( dependent, otherDependents );
+        for ( String each : dependents ) {
+            parser.requiredIf( options(), each );
+        }
+
+        return this;
+    }
+
+    /**
+     * <p>Informs an option parser that this builder's option is required if the given option is present on the command
+     * line.</p>
+     *
+     * <p>For a given option, you <em>should not</em> mix this with {@link #requiredUnless(OptionSpec, OptionSpec[])
+     * requiredUnless} to avoid conflicts.</p>
+     *
+     * <p>This method recognizes only instances of options returned from the fluent interface methods.</p>
+     *
+     * @param dependent the option whose presence on a command line makes this builder's option required
+     * @param otherDependents other options whose presence on a command line makes this builder's option required
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     */
+    public OptionSpecBuilder requiredIf( OptionSpec<?> dependent, OptionSpec<?>... otherDependents ) {
+        parser.requiredIf( options(), dependent );
+        for ( OptionSpec<?> each : otherDependents )
+            parser.requiredIf( options(), each );
+
+        return this;
+    }
+
+    /**
+     * <p>Informs an option parser that this builder's option is required if the given option is absent on the command
+     * line.</p>
+     *
+     * <p>For a given option, you <em>should not</em> mix this with {@link #requiredIf(OptionSpec, OptionSpec[])
+     * requiredIf} to avoid conflicts.</p>
+     *
+     * @param dependent an option whose absence on a command line makes this builder's option required
+     * @param otherDependents other options whose absence on a command line makes this builder's option required
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     * @throws OptionException if any of the dependent options haven't been configured in the parser yet
+     */
+    public OptionSpecBuilder requiredUnless( String dependent, String... otherDependents ) {
+        List<String> dependents = validatedDependents( dependent, otherDependents );
+        for ( String each : dependents ) {
+            parser.requiredUnless( options(), each );
+        }
+        return this;
+    }
+
+    /**
+     * <p>Informs an option parser that this builder's option is required if the given option is absent on the command
+     * line.</p>
+     *
+     * <p>For a given option, you <em>should not</em> mix this with {@link #requiredIf(OptionSpec, OptionSpec[])
+     * requiredIf} to avoid conflicts.</p>
+     *
+     * <p>This method recognizes only instances of options returned from the fluent interface methods.</p>
+     *
+     * @param dependent the option whose absence on a command line makes this builder's option required
+     * @param otherDependents other options whose absence on a command line makes this builder's option required
+     * @return self, so that the caller can add clauses to the fluent interface sentence
+     */
+    public OptionSpecBuilder requiredUnless( OptionSpec<?> dependent, OptionSpec<?>... otherDependents ) {
+        parser.requiredUnless( options(), dependent );
+        for ( OptionSpec<?> each : otherDependents )
+            parser.requiredUnless( options(), each );
+
+        return this;
+    }
+
+    private List<String> validatedDependents( String dependent, String... otherDependents ) {
+        List<String> dependents = new ArrayList<String>();
+        dependents.add( dependent );
+        Collections.addAll( dependents, otherDependents );
+
+        for ( String each : dependents ) {
+            if ( !parser.isRecognized( each ) )
+                throw new UnconfiguredOptionException( each );
+        }
+
+        return dependents;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionSpecTokenizer.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.NoSuchElementException;
+
+import static jdk.internal.joptsimple.ParserRules.*;
+
+/**
+ * Tokenizes a short option specification string.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class OptionSpecTokenizer {
+    private static final char POSIXLY_CORRECT_MARKER = '+';
+    private static final char HELP_MARKER = '*';
+
+    private String specification;
+    private int index;
+
+    OptionSpecTokenizer( String specification ) {
+        if ( specification == null )
+            throw new NullPointerException( "null option specification" );
+
+        this.specification = specification;
+    }
+
+    boolean hasMore() {
+        return index < specification.length();
+    }
+
+    AbstractOptionSpec<?> next() {
+        if ( !hasMore() )
+            throw new NoSuchElementException();
+
+
+        String optionCandidate = String.valueOf( specification.charAt( index ) );
+        index++;
+
+        AbstractOptionSpec<?> spec;
+        if ( RESERVED_FOR_EXTENSIONS.equals( optionCandidate ) ) {
+            spec = handleReservedForExtensionsToken();
+
+            if ( spec != null )
+                return spec;
+        }
+
+        ensureLegalOption( optionCandidate );
+
+        if ( hasMore() ) {
+            boolean forHelp = false;
+            if ( specification.charAt( index ) == HELP_MARKER ) {
+                forHelp = true;
+                ++index;
+            }
+            spec = hasMore() && specification.charAt( index ) == ':'
+                ? handleArgumentAcceptingOption( optionCandidate )
+                : new NoArgumentOptionSpec( optionCandidate );
+            if ( forHelp )
+                spec.forHelp();
+        } else
+            spec = new NoArgumentOptionSpec( optionCandidate );
+
+        return spec;
+    }
+
+    void configure( OptionParser parser ) {
+        adjustForPosixlyCorrect( parser );
+
+        while ( hasMore() )
+            parser.recognize( next() );
+    }
+
+    private void adjustForPosixlyCorrect( OptionParser parser ) {
+        if ( POSIXLY_CORRECT_MARKER == specification.charAt( 0 ) ) {
+            parser.posixlyCorrect( true );
+            specification = specification.substring( 1 );
+        }
+    }
+
+    private AbstractOptionSpec<?> handleReservedForExtensionsToken() {
+        if ( !hasMore() )
+            return new NoArgumentOptionSpec( RESERVED_FOR_EXTENSIONS );
+
+        if ( specification.charAt( index ) == ';' ) {
+            ++index;
+            return new AlternativeLongOptionSpec();
+        }
+
+        return null;
+    }
+
+    private AbstractOptionSpec<?> handleArgumentAcceptingOption( String candidate ) {
+        index++;
+
+        if ( hasMore() && specification.charAt( index ) == ':' ) {
+            index++;
+            return new OptionalArgumentOptionSpec<String>( candidate );
+        }
+
+        return new RequiredArgumentOptionSpec<String>( candidate );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/OptionalArgumentOptionSpec.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+
+/**
+ * Specification of an option that accepts an optional argument.
+ *
+ * @param <V> represents the type of the arguments this option accepts
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class OptionalArgumentOptionSpec<V> extends ArgumentAcceptingOptionSpec<V> {
+    OptionalArgumentOptionSpec( String option ) {
+        super( option, false );
+    }
+
+    OptionalArgumentOptionSpec( Collection<String> options, String description ) {
+        super( options, false, description );
+    }
+
+    @Override
+    protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
+        if ( arguments.hasMore() ) {
+            String nextArgument = arguments.peek();
+
+            if ( !parser.looksLikeAnOption( nextArgument ) )
+                handleOptionArgument( parser, detectedOptions, arguments );
+            else if ( isArgumentOfNumberType() && canConvertArgument( nextArgument ) )
+                addArguments( detectedOptions, arguments.next() );
+            else
+                detectedOptions.add( this );
+        }
+        else
+            detectedOptions.add( this );
+    }
+
+    private void handleOptionArgument( OptionParser parser, OptionSet detectedOptions, ArgumentList arguments ) {
+        if ( parser.posixlyCorrect() ) {
+            detectedOptions.add( this );
+            parser.noMoreOptions();
+        }
+        else
+            addArguments( detectedOptions, arguments.next() );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ParserRules.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+
+import static java.lang.Character.*;
+
+/**
+ * Can tell whether or not options are well-formed.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+final class ParserRules {
+    static final char HYPHEN_CHAR = '-';
+    static final String HYPHEN = String.valueOf( HYPHEN_CHAR );
+    static final String DOUBLE_HYPHEN = "--";
+    static final String OPTION_TERMINATOR = DOUBLE_HYPHEN;
+    static final String RESERVED_FOR_EXTENSIONS = "W";
+
+    private ParserRules() {
+        throw new UnsupportedOperationException();
+    }
+
+    static boolean isShortOptionToken( String argument ) {
+        return argument.startsWith( HYPHEN )
+            && !HYPHEN.equals( argument )
+            && !isLongOptionToken( argument );
+    }
+
+    static boolean isLongOptionToken( String argument ) {
+        return argument.startsWith( DOUBLE_HYPHEN ) && !isOptionTerminator( argument );
+    }
+
+    static boolean isOptionTerminator( String argument ) {
+        return OPTION_TERMINATOR.equals( argument );
+    }
+
+    static void ensureLegalOption( String option ) {
+        if ( option.startsWith( HYPHEN ) )
+            throw new IllegalOptionSpecificationException( String.valueOf( option ) );
+
+        for ( int i = 0; i < option.length(); ++i )
+            ensureLegalOptionCharacter( option.charAt( i ) );
+    }
+
+    static void ensureLegalOptions( Collection<String> options ) {
+        for ( String each : options )
+            ensureLegalOption( each );
+    }
+
+    private static void ensureLegalOptionCharacter( char option ) {
+        if ( !( isLetterOrDigit( option ) || isAllowedPunctuation( option ) ) )
+            throw new IllegalOptionSpecificationException( String.valueOf( option ) );
+    }
+
+    private static boolean isAllowedPunctuation( char option ) {
+        String allowedPunctuation = "?." + HYPHEN_CHAR;
+        return allowedPunctuation.indexOf( option ) != -1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/README	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,3 @@
+JOpt Simple, Version 4.6
+https://pholser.github.io/jopt-simple/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/RequiredArgumentOptionSpec.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+
+/**
+ * Specification of an option that accepts a required argument.
+ *
+ * @param <V> represents the type of the arguments this option accepts
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class RequiredArgumentOptionSpec<V> extends ArgumentAcceptingOptionSpec<V> {
+    RequiredArgumentOptionSpec( String option ) {
+        super( option, true );
+    }
+
+    RequiredArgumentOptionSpec( Collection<String> options, String description ) {
+        super( options, true, description );
+    }
+
+    @Override
+    protected void detectOptionArgument( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions ) {
+        if ( !arguments.hasMore() )
+            throw new OptionMissingRequiredArgumentException( options() );
+
+        addArguments( detectedOptions, arguments.next() );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnacceptableNumberOfNonOptionsException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import static java.util.Collections.*;
+
+/**
+ * Thrown when the option parser detects an unacceptable number of {@code linkplain NonOptionArgumentSpec
+ * non-option arguments}.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class UnacceptableNumberOfNonOptionsException extends OptionException {
+    private static final long serialVersionUID = -1L;
+    private final int minimum;
+    private final int maximum;
+    private final int actual;
+
+    UnacceptableNumberOfNonOptionsException( int minimum, int maximum, int actual ) {
+        super( singletonList( NonOptionArgumentSpec.NAME ) );
+
+        this.minimum = minimum;
+        this.maximum = maximum;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getMessage() {
+        return String.format( "actual = %d, minimum = %d, maximum = %d", actual, minimum, maximum );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnconfiguredOptionException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import java.util.Collection;
+
+import static java.util.Collections.*;
+
+/**
+ * Thrown when an option parser refers to an option that is not in fact configured already on the parser.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class UnconfiguredOptionException extends OptionException {
+    private static final long serialVersionUID = -1L;
+
+    UnconfiguredOptionException( String option ) {
+        this( singletonList( option ) );
+    }
+
+    UnconfiguredOptionException( Collection<String> options ) {
+        super( options );
+    }
+
+    @Override
+    public String getMessage() {
+        return "Option " + multipleOptionMessage() + " has not been configured on this parser";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/UnrecognizedOptionException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+import static java.util.Collections.*;
+
+/**
+ * Thrown when the option parser encounters an unrecognized option.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class UnrecognizedOptionException extends OptionException {
+    private static final long serialVersionUID = -1L;
+
+    UnrecognizedOptionException( String option ) {
+        super( singletonList( option ) );
+    }
+
+    @Override
+    public String getMessage() {
+        return singleOptionMessage() + " is not a recognized option";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConversionException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+/**
+ * Thrown by {@link ValueConverter}s when problems occur in converting string values to other Java types.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public class ValueConversionException extends RuntimeException {
+    private static final long serialVersionUID = -1L;
+
+    /**
+     * Creates a new exception with the specified detail message.
+     *
+     * @param message the detail message
+     */
+    public ValueConversionException( String message ) {
+        this( message, null );
+    }
+
+    /**
+     * Creates a new exception with the specified detail message and cause.
+     *
+     * @param message the detail message
+     * @param cause the original exception
+     */
+    public ValueConversionException( String message, Throwable cause ) {
+        super( message, cause );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/ValueConverter.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple;
+
+/**
+ * Instances of this interface are used to convert arguments of options into specific Java types.
+ *
+ * @param <V> constraint on the type of values being converted to
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public interface ValueConverter<V> {
+    /**
+     * Converts the given string value into a Java type.
+     *
+     * @param value the string to convert
+     * @return the converted value
+     * @throws ValueConversionException if a problem occurs while converting the value
+     */
+    V convert( String value );
+
+    /**
+     * Gives the class of the type of values this converter converts to.
+     *
+     * @return the target class for conversion
+     */
+    Class<V> valueType();
+
+    /**
+     * Gives a string that describes the pattern of the values this converter expects, if any.  For example, a date
+     * converter can respond with a {@link java.text.SimpleDateFormat date format string}.
+     *
+     * @return a value pattern, or {@code null} if there's nothing interesting here
+     */
+    String valuePattern();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/AbbreviationMap.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * <p>A map whose keys are strings; when a key/value pair is added to the map, the longest unique abbreviations of that
+ * key are added as well, and associated with the value. Thus:</p>
+ *
+ * <pre>
+ *   <code>
+ *   abbreviations.put( "good", "bye" );
+ *   </code>
+ * </pre>
+ *
+ * <p>would make it such that you could retrieve the value {@code "bye"} from the map using the keys {@code "good"},
+ * {@code "goo"}, {@code "go"}, and {@code "g"}. A subsequent invocation of:</p>
+ * <pre>
+ *   <code>
+ *   abbreviations.put( "go", "fish" );
+ *   </code>
+ * </pre>
+ *
+ * <p>would make it such that you could retrieve the value {@code "bye"} using the keys {@code "good"} and
+ * {@code "goo"}, and the value {@code "fish"} using the key {@code "go"}.  The key {@code "g"} would yield
+ * {@code null}, since it would no longer be a unique abbreviation.</p>
+ *
+ * <p>The data structure is much like a "trie".</p>
+ *
+ * @param <V> a constraint on the types of the values in the map
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ * @see <a href="http://www.perldoc.com/perl5.8.0/lib/Text/Abbrev.html">Perl's Text::Abbrev module</a>
+ */
+public class AbbreviationMap<V> {
+    private String key;
+    private V value;
+    private final Map<Character, AbbreviationMap<V>> children = new TreeMap<Character, AbbreviationMap<V>>();
+    private int keysBeyond;
+
+    /**
+     * <p>Tells whether the given key is in the map, or whether the given key is a unique
+     * abbreviation of a key that is in the map.</p>
+     *
+     * @param aKey key to look up
+     * @return {@code true} if {@code key} is present in the map
+     * @throws NullPointerException if {@code key} is {@code null}
+     */
+    public boolean contains( String aKey ) {
+        return get( aKey ) != null;
+    }
+
+    /**
+     * <p>Answers the value associated with the given key.  The key can be a unique
+     * abbreviation of a key that is in the map. </p>
+     *
+     * @param aKey key to look up
+     * @return the value associated with {@code aKey}; or {@code null} if there is no
+     * such value or {@code aKey} is not a unique abbreviation of a key in the map
+     * @throws NullPointerException if {@code aKey} is {@code null}
+     */
+    public V get( String aKey ) {
+        char[] chars = charsOf( aKey );
+
+        AbbreviationMap<V> child = this;
+        for ( char each : chars ) {
+            child = child.children.get( each );
+            if ( child == null )
+                return null;
+        }
+
+        return child.value;
+    }
+
+    /**
+     * <p>Associates a given value with a given key.  If there was a previous
+     * association, the old value is replaced with the new one.</p>
+     *
+     * @param aKey key to create in the map
+     * @param newValue value to associate with the key
+     * @throws NullPointerException if {@code aKey} or {@code newValue} is {@code null}
+     * @throws IllegalArgumentException if {@code aKey} is a zero-length string
+     */
+    public void put( String aKey, V newValue ) {
+        if ( newValue == null )
+            throw new NullPointerException();
+        if ( aKey.length() == 0 )
+            throw new IllegalArgumentException();
+
+        char[] chars = charsOf( aKey );
+        add( chars, newValue, 0, chars.length );
+    }
+
+    /**
+     * <p>Associates a given value with a given set of keys.  If there was a previous
+     * association, the old value is replaced with the new one.</p>
+     *
+     * @param keys keys to create in the map
+     * @param newValue value to associate with the key
+     * @throws NullPointerException if {@code keys} or {@code newValue} is {@code null}
+     * @throws IllegalArgumentException if any of {@code keys} is a zero-length string
+     */
+    public void putAll( Iterable<String> keys, V newValue ) {
+        for ( String each : keys )
+            put( each, newValue );
+    }
+
+    private boolean add( char[] chars, V newValue, int offset, int length ) {
+        if ( offset == length ) {
+            value = newValue;
+            boolean wasAlreadyAKey = key != null;
+            key = new String( chars );
+            return !wasAlreadyAKey;
+        }
+
+        char nextChar = chars[ offset ];
+        AbbreviationMap<V> child = children.get( nextChar );
+        if ( child == null ) {
+            child = new AbbreviationMap<V>();
+            children.put( nextChar, child );
+        }
+
+        boolean newKeyAdded = child.add( chars, newValue, offset + 1, length );
+
+        if ( newKeyAdded )
+            ++keysBeyond;
+
+        if ( key == null )
+            value = keysBeyond > 1 ? null : newValue;
+
+        return newKeyAdded;
+    }
+
+    /**
+     * <p>If the map contains the given key, dissociates the key from its value.</p>
+     *
+     * @param aKey key to remove
+     * @throws NullPointerException if {@code aKey} is {@code null}
+     * @throws IllegalArgumentException if {@code aKey} is a zero-length string
+     */
+    public void remove( String aKey ) {
+        if ( aKey.length() == 0 )
+            throw new IllegalArgumentException();
+
+        char[] keyChars = charsOf( aKey );
+        remove( keyChars, 0, keyChars.length );
+    }
+
+    private boolean remove( char[] aKey, int offset, int length ) {
+        if ( offset == length )
+            return removeAtEndOfKey();
+
+        char nextChar = aKey[ offset ];
+        AbbreviationMap<V> child = children.get( nextChar );
+        if ( child == null || !child.remove( aKey, offset + 1, length ) )
+            return false;
+
+        --keysBeyond;
+        if ( child.keysBeyond == 0 )
+            children.remove( nextChar );
+        if ( keysBeyond == 1 && key == null )
+            setValueToThatOfOnlyChild();
+
+        return true;
+    }
+
+    private void setValueToThatOfOnlyChild() {
+        Map.Entry<Character, AbbreviationMap<V>> entry = children.entrySet().iterator().next();
+        AbbreviationMap<V> onlyChild = entry.getValue();
+        value = onlyChild.value;
+    }
+
+    private boolean removeAtEndOfKey() {
+        if ( key == null )
+            return false;
+
+        key = null;
+        if ( keysBeyond == 1 )
+            setValueToThatOfOnlyChild();
+        else
+            value = null;
+
+        return true;
+    }
+
+    /**
+     * Gives a Java map representation of this abbreviation map.
+     *
+     * @return a Java map corresponding to this abbreviation map
+     */
+    public Map<String, V> toJavaUtilMap() {
+        Map<String, V> mappings = new TreeMap<String, V>();
+        addToMappings( mappings );
+        return mappings;
+    }
+
+    private void addToMappings( Map<String, V> mappings ) {
+        if ( key != null )
+            mappings.put( key, value );
+
+        for ( AbbreviationMap<V> each : children.values() )
+            each.addToMappings( mappings );
+    }
+
+    private static char[] charsOf( String aKey ) {
+        char[] chars = new char[ aKey.length() ];
+        aKey.getChars( 0, aKey.length(), chars, 0 );
+        return chars;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Classes.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public final class Classes {
+    private static final Map<Class<?>, Class<?>> WRAPPERS = new HashMap<Class<?>, Class<?>>( 13 );
+
+    static {
+        WRAPPERS.put( boolean.class, Boolean.class );
+        WRAPPERS.put( byte.class, Byte.class );
+        WRAPPERS.put( char.class, Character.class );
+        WRAPPERS.put( double.class, Double.class );
+        WRAPPERS.put( float.class, Float.class );
+        WRAPPERS.put( int.class, Integer.class );
+        WRAPPERS.put( long.class, Long.class );
+        WRAPPERS.put( short.class, Short.class );
+        WRAPPERS.put( void.class, Void.class );
+    }
+
+    private Classes() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Gives the "short version" of the given class name.  Somewhat naive to inner classes.
+     *
+     * @param className class name to chew on
+     * @return the short name of the class
+     */
+    public static String shortNameOf( String className ) {
+        return className.substring( className.lastIndexOf( '.' ) + 1 );
+    }
+
+    /**
+     * Gives the primitive wrapper class for the given class. If the given class is not
+     * {@linkplain Class#isPrimitive() primitive}, returns the class itself.
+     *
+     * @param <T> generic class type
+     * @param clazz the class to check
+     * @return primitive wrapper type if {@code clazz} is primitive, otherwise {@code clazz}
+     */
+    @SuppressWarnings( "unchecked" )
+    public static <T> Class<T> wrapperOf( Class<T> clazz ) {
+        return clazz.isPrimitive() ? (Class<T>) WRAPPERS.get( clazz ) : clazz;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Columns.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.text.BreakIterator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import static java.text.BreakIterator.*;
+
+import static jdk.internal.joptsimple.internal.Strings.*;
+
+/**
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class Columns {
+    private static final int INDENT_WIDTH = 2;
+
+    private final int optionWidth;
+    private final int descriptionWidth;
+
+    Columns( int optionWidth, int descriptionWidth ) {
+        this.optionWidth = optionWidth;
+        this.descriptionWidth = descriptionWidth;
+    }
+
+    List<Row> fit( Row row ) {
+        List<String> options = piecesOf( row.option, optionWidth );
+        List<String> descriptions = piecesOf( row.description, descriptionWidth );
+
+        List<Row> rows = new ArrayList<Row>();
+        for ( int i = 0; i < Math.max( options.size(), descriptions.size() ); ++i )
+            rows.add( new Row( itemOrEmpty( options, i ), itemOrEmpty( descriptions, i ) ) );
+
+        return rows;
+    }
+
+    private static String itemOrEmpty( List<String> items, int index ) {
+        return index >= items.size() ? "" : items.get( index );
+    }
+
+    private List<String> piecesOf( String raw, int width ) {
+        List<String> pieces = new ArrayList<String>();
+
+        for ( String each : raw.trim().split( LINE_SEPARATOR ) )
+            pieces.addAll( piecesOfEmbeddedLine( each, width ) );
+
+        return pieces;
+    }
+
+    private List<String> piecesOfEmbeddedLine( String line, int width ) {
+        List<String> pieces = new ArrayList<String>();
+
+        BreakIterator words = BreakIterator.getLineInstance( Locale.US );
+        words.setText( line );
+
+        StringBuilder nextPiece = new StringBuilder();
+
+        int start = words.first();
+        for ( int end = words.next(); end != DONE; start = end, end = words.next() )
+            nextPiece = processNextWord( line, nextPiece, start, end, width, pieces );
+
+        if ( nextPiece.length() > 0 )
+            pieces.add( nextPiece.toString() );
+
+        return pieces;
+    }
+
+    private StringBuilder processNextWord( String source, StringBuilder nextPiece, int start, int end, int width,
+                                           List<String> pieces ) {
+        StringBuilder augmented = nextPiece;
+
+        String word = source.substring( start, end );
+        if ( augmented.length() + word.length() > width ) {
+            pieces.add( augmented.toString().replaceAll( "\\s+$", "" ) );
+            augmented = new StringBuilder( repeat( ' ', INDENT_WIDTH ) ).append( word );
+        }
+        else
+            augmented.append( word );
+
+        return augmented;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ConstructorInvokingValueConverter.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.lang.reflect.Constructor;
+
+import jdk.internal.joptsimple.ValueConverter;
+
+import static jdk.internal.joptsimple.internal.Reflection.*;
+
+/**
+ * @param <V> constraint on the type of values being converted to
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class ConstructorInvokingValueConverter<V> implements ValueConverter<V> {
+    private final Constructor<V> ctor;
+
+    ConstructorInvokingValueConverter( Constructor<V> ctor ) {
+        this.ctor = ctor;
+    }
+
+    public V convert( String value ) {
+        return instantiate( ctor, value );
+    }
+
+    public Class<V> valueType() {
+        return ctor.getDeclaringClass();
+    }
+
+    public String valuePattern() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/MethodInvokingValueConverter.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.lang.reflect.Method;
+
+import jdk.internal.joptsimple.ValueConverter;
+
+import static jdk.internal.joptsimple.internal.Reflection.*;
+
+/**
+ * @param <V> constraint on the type of values being converted to
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class MethodInvokingValueConverter<V> implements ValueConverter<V> {
+    private final Method method;
+    private final Class<V> clazz;
+
+    MethodInvokingValueConverter( Method method, Class<V> clazz ) {
+        this.method = method;
+        this.clazz = clazz;
+    }
+
+    public V convert( String value ) {
+        return clazz.cast( invoke( method, value ) );
+    }
+
+    public Class<V> valueType() {
+        return clazz;
+    }
+
+    public String valuePattern() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Objects.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+/**
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public final class Objects {
+    private Objects() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Rejects {@code null} references.
+     *
+     * @param target reference to check
+     * @throws NullPointerException if {@code target} is {@code null}
+     */
+    public static void ensureNotNull( Object target ) {
+        if ( target == null )
+            throw new NullPointerException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Reflection.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import static java.lang.reflect.Modifier.*;
+
+import jdk.internal.joptsimple.ValueConverter;
+
+import static jdk.internal.joptsimple.internal.Classes.*;
+
+/**
+ * Helper methods for reflection.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public final class Reflection {
+    private Reflection() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Finds an appropriate value converter for the given class.
+     *
+     * @param <V> a constraint on the class object to introspect
+     * @param clazz class to introspect on
+     * @return a converter method or constructor
+     */
+    public static <V> ValueConverter<V> findConverter( Class<V> clazz ) {
+        Class<V> maybeWrapper = wrapperOf( clazz );
+
+        ValueConverter<V> valueOf = valueOfConverter( maybeWrapper );
+        if ( valueOf != null )
+            return valueOf;
+
+        ValueConverter<V> constructor = constructorConverter( maybeWrapper );
+        if ( constructor != null )
+            return constructor;
+
+        throw new IllegalArgumentException( clazz + " is not a value type" );
+    }
+
+    private static <V> ValueConverter<V> valueOfConverter( Class<V> clazz ) {
+        try {
+            Method valueOf = clazz.getDeclaredMethod( "valueOf", String.class );
+            if ( meetsConverterRequirements( valueOf, clazz ) )
+                return new MethodInvokingValueConverter<V>( valueOf, clazz );
+
+            return null;
+        }
+        catch ( NoSuchMethodException ignored ) {
+            return null;
+        }
+    }
+
+    private static <V> ValueConverter<V> constructorConverter( Class<V> clazz ) {
+        try {
+            return new ConstructorInvokingValueConverter<V>( clazz.getConstructor( String.class ) );
+        }
+        catch ( NoSuchMethodException ignored ) {
+            return null;
+        }
+    }
+
+    /**
+     * Invokes the given constructor with the given arguments.
+     *
+     * @param <T> constraint on the type of the objects yielded by the constructor
+     * @param constructor constructor to invoke
+     * @param args arguments to hand to the constructor
+     * @return the result of invoking the constructor
+     * @throws ReflectionException in lieu of the gaggle of reflection-related exceptions
+     */
+    public static <T> T instantiate( Constructor<T> constructor, Object... args ) {
+        try {
+            return constructor.newInstance( args );
+        }
+        catch ( Exception ex ) {
+            throw reflectionException( ex );
+        }
+    }
+
+    /**
+     * Invokes the given static method with the given arguments.
+     *
+     * @param method method to invoke
+     * @param args arguments to hand to the method
+     * @return the result of invoking the method
+     * @throws ReflectionException in lieu of the gaggle of reflection-related exceptions
+     */
+    public static Object invoke( Method method, Object... args ) {
+        try {
+            return method.invoke( null, args );
+        }
+        catch ( Exception ex ) {
+            throw reflectionException( ex );
+        }
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public static <V> V convertWith( ValueConverter<V> converter, String raw ) {
+        return converter == null ? (V) raw : converter.convert( raw );
+    }
+
+    private static boolean meetsConverterRequirements( Method method, Class<?> expectedReturnType ) {
+        int modifiers = method.getModifiers();
+        return isPublic( modifiers ) && isStatic( modifiers ) && expectedReturnType.equals( method.getReturnType() );
+    }
+
+    private static RuntimeException reflectionException( Exception ex ) {
+        if ( ex instanceof IllegalArgumentException )
+            return new ReflectionException( ex );
+        if ( ex instanceof InvocationTargetException )
+            return new ReflectionException( ex.getCause() );
+        if ( ex instanceof RuntimeException )
+            return (RuntimeException) ex;
+
+        return new ReflectionException( ex );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/ReflectionException.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+/**
+ * This unchecked exception wraps reflection-oriented exceptions.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public class ReflectionException extends RuntimeException {
+    private static final long serialVersionUID = -2L;
+
+    ReflectionException( Throwable cause ) {
+        super( cause );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Row.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+/**
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+class Row {
+    final String option;
+    final String description;
+
+    Row( String option, String description ) {
+        this.option = option;
+        this.description = description;
+    }
+
+    @Override
+    public boolean equals( Object that ) {
+        if ( that == this )
+            return true;
+        if ( that == null || !getClass().equals( that.getClass() ) )
+            return false;
+
+        Row other = (Row) that;
+        return option.equals( other.option ) && description.equals( other.description );
+    }
+
+    @Override
+    public int hashCode() {
+        return option.hashCode() ^ description.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Rows.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import static java.lang.Math.*;
+
+import static jdk.internal.joptsimple.internal.Strings.*;
+
+/**
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public class Rows {
+    private final int overallWidth;
+    private final int columnSeparatorWidth;
+    private final Set<Row> rows = new LinkedHashSet<Row>();
+    private int widthOfWidestOption;
+    private int widthOfWidestDescription;
+
+    public Rows( int overallWidth, int columnSeparatorWidth ) {
+        this.overallWidth = overallWidth;
+        this.columnSeparatorWidth = columnSeparatorWidth;
+    }
+
+    public void add( String option, String description ) {
+        add( new Row( option, description ) );
+    }
+
+    private void add( Row row ) {
+        rows.add( row );
+        widthOfWidestOption = max( widthOfWidestOption, row.option.length() );
+        widthOfWidestDescription = max( widthOfWidestDescription, row.description.length() );
+    }
+
+    private void reset() {
+        rows.clear();
+        widthOfWidestOption = 0;
+        widthOfWidestDescription = 0;
+    }
+
+    public void fitToWidth() {
+        Columns columns = new Columns( optionWidth(), descriptionWidth() );
+
+        Set<Row> fitted = new LinkedHashSet<Row>();
+        for ( Row each : rows )
+            fitted.addAll( columns.fit( each ) );
+
+        reset();
+
+        for ( Row each : fitted )
+            add( each );
+    }
+
+    public String render() {
+        StringBuilder buffer = new StringBuilder();
+
+        for ( Row each : rows ) {
+            pad( buffer, each.option, optionWidth() ).append( repeat( ' ', columnSeparatorWidth ) );
+            pad( buffer, each.description, descriptionWidth() ).append( LINE_SEPARATOR );
+        }
+
+        return buffer.toString();
+    }
+
+    private int optionWidth() {
+        return min( ( overallWidth - columnSeparatorWidth ) / 2, widthOfWidestOption );
+    }
+
+    private int descriptionWidth() {
+        return min( ( overallWidth - columnSeparatorWidth ) / 2, widthOfWidestDescription );
+    }
+
+    private StringBuilder pad( StringBuilder buffer, String s, int length ) {
+        buffer.append( s ).append( repeat( ' ', length - s.length() ) );
+        return buffer;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/internal/Strings.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.internal;
+
+import java.util.Iterator;
+import java.util.List;
+
+import static java.lang.System.*;
+import static java.util.Arrays.*;
+
+/**
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public final class Strings {
+    public static final String EMPTY = "";
+    public static final String SINGLE_QUOTE = "'";
+    public static final String LINE_SEPARATOR = getProperty( "line.separator" );
+
+    private Strings() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Gives a string consisting of the given character repeated the given number of times.
+     *
+     * @param ch the character to repeat
+     * @param count how many times to repeat the character
+     * @return the resultant string
+     */
+    public static String repeat( char ch, int count ) {
+        StringBuilder buffer = new StringBuilder();
+
+        for ( int i = 0; i < count; ++i )
+            buffer.append( ch );
+
+        return buffer.toString();
+    }
+
+    /**
+     * Tells whether the given string is either {@code} or consists solely of whitespace characters.
+     *
+     * @param target string to check
+     * @return {@code true} if the target string is null or empty
+     */
+    public static boolean isNullOrEmpty( String target ) {
+        return target == null || EMPTY.equals( target );
+    }
+
+
+    /**
+     * Gives a string consisting of a given string prepended and appended with surrounding characters.
+     *
+     * @param target a string
+     * @param begin character to prepend
+     * @param end character to append
+     * @return the surrounded string
+     */
+    public static String surround( String target, char begin, char end ) {
+        return begin + target + end;
+    }
+
+    /**
+     * Gives a string consisting of the elements of a given array of strings, each separated by a given separator
+     * string.
+     *
+     * @param pieces the strings to join
+     * @param separator the separator
+     * @return the joined string
+     */
+    public static String join( String[] pieces, String separator ) {
+        return join( asList( pieces ), separator );
+    }
+
+    /**
+     * Gives a string consisting of the string representations of the elements of a given array of objects,
+     * each separated by a given separator string.
+     *
+     * @param pieces the elements whose string representations are to be joined
+     * @param separator the separator
+     * @return the joined string
+     */
+    public static String join( List<String> pieces, String separator ) {
+        StringBuilder buffer = new StringBuilder();
+
+        for ( Iterator<String> iter = pieces.iterator(); iter.hasNext(); ) {
+            buffer.append( iter.next() );
+
+            if ( iter.hasNext() )
+                buffer.append( separator );
+        }
+
+        return buffer.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/DateConverter.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.util;
+
+import java.text.DateFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import jdk.internal.joptsimple.ValueConversionException;
+import jdk.internal.joptsimple.ValueConverter;
+
+/**
+ * Converts values to {@link Date}s using a {@link DateFormat} object.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public class DateConverter implements ValueConverter<Date> {
+    private final DateFormat formatter;
+
+    /**
+     * Creates a converter that uses the given date formatter/parser.
+     *
+     * @param formatter the formatter/parser to use
+     * @throws NullPointerException if {@code formatter} is {@code null}
+     */
+    public DateConverter( DateFormat formatter ) {
+        if ( formatter == null )
+            throw new NullPointerException( "illegal null formatter" );
+
+        this.formatter = formatter;
+    }
+
+    /**
+     * Creates a converter that uses a {@link SimpleDateFormat} with the given date/time pattern.  The date formatter
+     * created is not {@link SimpleDateFormat#setLenient(boolean) lenient}.
+     *
+     * @param pattern expected date/time pattern
+     * @return the new converter
+     * @throws NullPointerException if {@code pattern} is {@code null}
+     * @throws IllegalArgumentException if {@code pattern} is invalid
+     */
+    public static DateConverter datePattern( String pattern ) {
+        SimpleDateFormat formatter = new SimpleDateFormat( pattern );
+        formatter.setLenient( false );
+
+        return new DateConverter( formatter );
+    }
+
+    public Date convert( String value ) {
+        ParsePosition position = new ParsePosition( 0 );
+
+        Date date = formatter.parse( value, position );
+        if ( position.getIndex() != value.length() )
+            throw new ValueConversionException( message( value ) );
+
+        return date;
+    }
+
+    public Class<Date> valueType() {
+        return Date.class;
+    }
+
+    public String valuePattern() {
+        return formatter instanceof SimpleDateFormat
+            ? ( (SimpleDateFormat) formatter ).toPattern()
+            : "";
+    }
+
+    private String message( String value ) {
+        String message = "Value [" + value + "] does not match date/time pattern";
+        if ( formatter instanceof SimpleDateFormat )
+            message += " [" + ( (SimpleDateFormat) formatter ).toPattern() + ']';
+
+        return message;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/InetAddressConverter.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.util;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import jdk.internal.joptsimple.ValueConversionException;
+import jdk.internal.joptsimple.ValueConverter;
+
+/**
+ * Converts values to {@link java.net.InetAddress} using {@link InetAddress#getByName(String) getByName}.
+ *
+ * @author <a href="mailto:r@ymund.de">Raymund F\u00FCl\u00F6p</a>
+ */
+public class InetAddressConverter implements ValueConverter<InetAddress> {
+    public InetAddress convert( String value ) {
+        try {
+            return InetAddress.getByName( value );
+        } catch ( UnknownHostException e ) {
+            throw new ValueConversionException( "Cannot convert value [" + value + " into an InetAddress", e );
+        }
+    }
+
+    public Class<InetAddress> valueType() {
+        return InetAddress.class;
+    }
+
+    public String valuePattern() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/KeyValuePair.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009, 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.util;
+
+import static jdk.internal.joptsimple.internal.Strings.*;
+
+/**
+ * <p>A simple string key/string value pair.</p>
+ *
+ * <p>This is useful as an argument type for options whose values take on the form <kbd>key=value</kbd>, such as JVM
+ * command line system properties.</p>
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public final class KeyValuePair {
+    public final String key;
+    public final String value;
+
+    private KeyValuePair( String key, String value ) {
+        this.key = key;
+        this.value = value;
+    }
+
+    /**
+     * Parses a string assumed to be of the form <kbd>key=value</kbd> into its parts.
+     *
+     * @param asString key-value string
+     * @return a key-value pair
+     * @throws NullPointerException if {@code stringRepresentation} is {@code null}
+     */
+    public static KeyValuePair valueOf( String asString ) {
+        int equalsIndex = asString.indexOf( '=' );
+        if ( equalsIndex == -1 )
+            return new KeyValuePair( asString, EMPTY );
+
+        String aKey = asString.substring( 0, equalsIndex );
+        String aValue = equalsIndex == asString.length() - 1 ? EMPTY : asString.substring( equalsIndex + 1 );
+
+        return new KeyValuePair( aKey, aValue );
+    }
+
+    @Override
+    public boolean equals( Object that ) {
+        if ( !( that instanceof KeyValuePair ) )
+            return false;
+
+        KeyValuePair other = (KeyValuePair) that;
+        return key.equals( other.key ) && value.equals( other.value );
+    }
+
+    @Override
+    public int hashCode() {
+        return key.hashCode() ^ value.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return key + '=' + value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/util/RegexMatcher.java	Tue Jan 26 09:18:51 2016 +0000
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2004-2014 Paul R. Holser, Jr.
+ *
+ * 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.
+ */
+
+package jdk.internal.joptsimple.util;
+
+import java.util.regex.Pattern;
+
+import static java.util.regex.Pattern.*;
+
+import jdk.internal.joptsimple.ValueConversionException;
+import jdk.internal.joptsimple.ValueConverter;
+
+/**
+ * Ensures that values entirely match a regular expression.
+ *
+ * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
+ */
+public class RegexMatcher implements ValueConverter<String> {
+    private final Pattern pattern;
+
+    /**
+     * Creates a matcher that uses the given regular expression, modified by the given flags.
+     *
+     * @param pattern the regular expression pattern
+     * @param flags modifying regex flags
+     * @throws IllegalArgumentException if bit values other than those corresponding to the defined match flags are
+     * set in {@code flags}
+     * @throws java.util.regex.PatternSyntaxException if the expression's syntax is invalid
+     */
+    public RegexMatcher( String pattern, int flags ) {
+        this.pattern = compile( pattern, flags );
+    }
+
+    /**
+     * Gives a matcher that uses the given regular expression.
+     *
+     * @param pattern the regular expression pattern
+     * @return the new converter
+     * @throws java.util.regex.PatternSyntaxException if the expression's syntax is invalid
+     */
+    public static ValueConverter<String> regex( String pattern ) {
+        return new RegexMatcher( pattern, 0 );
+    }
+
+    public String convert( String value ) {
+        if ( !pattern.matcher( value ).matches() ) {
+            throw new ValueConversionException(
+                "Value [" + value + "] did not match regex [" + pattern.pattern() + ']' );
+        }
+
+        return value;
+    }
+
+    public Class<String> valueType() {
+        return String.class;
+    }
+
+    public String valuePattern() {
+        return pattern.pattern();
+    }
+}