Merge
authorlana
Thu, 28 Jan 2016 15:43:15 -0800
changeset 35390 bd8b3cb897da
parent 35376 37a7a87f8f74 (current diff)
parent 35389 97c366a8338e (diff)
child 35391 30e7774e9190
child 35633 c101ffa2470e
Merge
jdk/test/java/net/SocketPermission/policy
--- a/jdk/make/launcher/Launcher-jdk.javadoc.gmk	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/make/launcher/Launcher-jdk.javadoc.gmk	Thu Jan 28 15:43:15 2016 -0800
@@ -26,7 +26,7 @@
 include LauncherCommon.gmk
 
 $(eval $(call SetupBuildLauncher, javadoc, \
-    MAIN_CLASS := com.sun.tools.javadoc.Main, \
+    MAIN_CLASS := jdk.javadoc.internal.tool.Main, \
     CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
 ))
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, 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
@@ -339,7 +339,6 @@
         // assert shift > 0 && shift <=5 : "Illegal shift value";
         int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
         int chars = Math.max(((mag + (shift - 1)) / shift), 1);
-
         if (COMPACT_STRINGS) {
             byte[] buf = new byte[chars];
             formatUnsignedInt(val, shift, buf, 0, chars);
@@ -477,8 +476,13 @@
      * values, to cover the Integer.MIN_VALUE case. Converting otherwise
      * (negative to positive) will expose -Integer.MIN_VALUE that overflows
      * integer.
+     *
+     * @param i     value to convert
+     * @param index next index, after the least significant digit
+     * @param buf   target buffer, Latin1-encoded
+     * @return index of the most significant digit or minus sign, if present
      */
-    static void getChars(int i, int index, byte[] buf) {
+    static int getChars(int i, int index, byte[] buf) {
         int q, r;
         int charPos = index;
 
@@ -509,9 +513,19 @@
         if (negative) {
             buf[--charPos] = (byte)'-';
         }
+        return charPos;
     }
 
-    static void getCharsUTF16(int i, int index, byte[] buf) {
+    /**
+     * This is a variant of {@link #getChars(int, int, byte[])}, but for
+     * UTF-16 coder.
+     *
+     * @param i     value to convert
+     * @param index next index, after the least significant digit
+     * @param buf   target buffer, UTF16-coded.
+     * @return index of the most significant digit or minus sign, if present
+     */
+    static int getCharsUTF16(int i, int index, byte[] buf) {
         int q, r;
         int charPos = index;
 
@@ -542,6 +556,7 @@
         if (negative) {
             StringUTF16.putChar(buf, --charPos, '-');
         }
+        return charPos;
     }
 
     // Left here for compatibility reasons, see JDK-8143900.
--- a/jdk/src/java.base/share/classes/java/lang/Long.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, 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
@@ -379,7 +379,6 @@
         // assert shift > 0 && shift <=5 : "Illegal shift value";
         int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
         int chars = Math.max(((mag + (shift - 1)) / shift), 1);
-
         if (COMPACT_STRINGS) {
             byte[] buf = new byte[chars];
             formatUnsignedLong0(val, shift, buf, 0, chars);
@@ -489,8 +488,13 @@
      * values, to cover the Long.MIN_VALUE case. Converting otherwise
      * (negative to positive) will expose -Long.MIN_VALUE that overflows
      * long.
+     *
+     * @param i     value to convert
+     * @param index next index, after the least significant digit
+     * @param buf   target buffer, Latin1-encoded
+     * @return index of the most significant digit or minus sign, if present
      */
-    static void getChars(long i, int index, byte[] buf) {
+    static int getChars(long i, int index, byte[] buf) {
         long q;
         int r;
         int charPos = index;
@@ -533,9 +537,19 @@
         if (negative) {
             buf[--charPos] = (byte)'-';
         }
+        return charPos;
     }
 
-    static void getCharsUTF16(long i, int index, byte[] buf) {
+    /**
+     * This is a variant of {@link #getChars(long, int, byte[])}, but for
+     * UTF-16 coder.
+     *
+     * @param i     value to convert
+     * @param index next index, after the least significant digit
+     * @param buf   target buffer, UTF16-coded.
+     * @return index of the most significant digit or minus sign, if present
+     */
+    static int getCharsUTF16(long i, int index, byte[] buf) {
         long q;
         int r;
         int charPos = index;
@@ -578,6 +592,7 @@
         if (negative) {
             StringUTF16.putChar(buf, --charPos, '-');
         }
+        return charPos;
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StringConcatHelper.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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 java.lang;
+
+/**
+ * Helper for string concatenation. These methods are mostly looked up with private lookups
+ * from {@link java.lang.invoke.StringConcatFactory}, and used in {@link java.lang.invoke.MethodHandle}
+ * combinators there.
+ */
+final class StringConcatHelper {
+
+    private StringConcatHelper() {
+        // no instantiation
+    }
+
+    /**
+     * Check for overflow, throw the exception on overflow.
+     * @param len String length
+     * @return length
+     */
+    private static int checkOverflow(int len) {
+        if (len < 0) {
+            throw new OutOfMemoryError("Overflow: String length out of range");
+        }
+        return len;
+    }
+
+    /**
+     * Mix value length into current length
+     * @param current current length
+     * @param value   value to mix in
+     * @return new length
+     */
+    static int mixLen(int current, boolean value) {
+        return checkOverflow(current + (value ? 4 : 5));
+    }
+
+    /**
+     * Mix value length into current length
+     * @param current current length
+     * @param value   value to mix in
+     * @return new length
+     */
+    static int mixLen(int current, byte value) {
+        return mixLen(current, (int)value);
+    }
+
+    /**
+     * Mix value length into current length
+     * @param current current length
+     * @param value   value to mix in
+     * @return new length
+     */
+    static int mixLen(int current, char value) {
+        return checkOverflow(current + 1);
+    }
+
+    /**
+     * Mix value length into current length
+     * @param current current length
+     * @param value   value to mix in
+     * @return new length
+     */
+    static int mixLen(int current, short value) {
+        return mixLen(current, (int)value);
+    }
+
+    /**
+     * Mix value length into current length
+     * @param current current length
+     * @param value   value to mix in
+     * @return new length
+     */
+    static int mixLen(int current, int value) {
+        return checkOverflow(current + Integer.stringSize(value));
+    }
+
+    /**
+     * Mix value length into current length
+     * @param current current length
+     * @param value   value to mix in
+     * @return new length
+     */
+    static int mixLen(int current, long value) {
+        return checkOverflow(current + Long.stringSize(value));
+    }
+
+    /**
+     * Mix value length into current length
+     * @param current current length
+     * @param value   value to mix in
+     * @return new length
+     */
+    static int mixLen(int current, String value) {
+        return checkOverflow(current + value.length());
+    }
+
+    /**
+     * Mix coder into current coder
+     * @param current current coder
+     * @param value   value to mix in
+     * @return new coder
+     */
+    static byte mixCoder(byte current, char value) {
+        return (byte)(current | (StringLatin1.canEncode(value) ? 0 : 1));
+    }
+
+    /**
+     * Mix coder into current coder
+     * @param current current coder
+     * @param value   value to mix in
+     * @return new coder
+     */
+    static byte mixCoder(byte current, String value) {
+        return (byte)(current | value.coder());
+    }
+
+    /**
+     * Mix coder into current coder
+     * @param current current coder
+     * @param value   value to mix in
+     * @return new coder
+     */
+    static byte mixCoder(byte current, boolean value) {
+        // Booleans are represented with Latin1
+        return current;
+    }
+
+    /**
+     * Mix coder into current coder
+     * @param current current coder
+     * @param value   value to mix in
+     * @return new coder
+     */
+    static byte mixCoder(byte current, byte value) {
+        // Bytes are represented with Latin1
+        return current;
+    }
+
+    /**
+     * Mix coder into current coder
+     * @param current current coder
+     * @param value   value to mix in
+     * @return new coder
+     */
+    static byte mixCoder(byte current, short value) {
+        // Shorts are represented with Latin1
+        return current;
+    }
+
+    /**
+     * Mix coder into current coder
+     * @param current current coder
+     * @param value   value to mix in
+     * @return new coder
+     */
+    static byte mixCoder(byte current, int value) {
+        // Ints are represented with Latin1
+        return current;
+    }
+
+    /**
+     * Mix coder into current coder
+     * @param current current coder
+     * @param value   value to mix in
+     * @return new coder
+     */
+    static byte mixCoder(byte current, long value) {
+        // Longs are represented with Latin1
+        return current;
+    }
+
+    /**
+     * Prepends the stringly representation of boolean value into buffer,
+     * given the coder and final index. Index is measured in chars, not in bytes!
+     *
+     * @param index final char index in the buffer
+     * @param buf   buffer to append to
+     * @param coder coder to add with
+     * @param value boolean value to encode
+     * @return new index
+     */
+    static int prepend(int index, byte[] buf, byte coder, boolean value) {
+        if (coder == String.LATIN1) {
+            if (value) {
+                buf[--index] = 'e';
+                buf[--index] = 'u';
+                buf[--index] = 'r';
+                buf[--index] = 't';
+            } else {
+                buf[--index] = 'e';
+                buf[--index] = 's';
+                buf[--index] = 'l';
+                buf[--index] = 'a';
+                buf[--index] = 'f';
+            }
+        } else {
+            if (value) {
+                StringUTF16.putChar(buf, --index, 'e');
+                StringUTF16.putChar(buf, --index, 'u');
+                StringUTF16.putChar(buf, --index, 'r');
+                StringUTF16.putChar(buf, --index, 't');
+            } else {
+                StringUTF16.putChar(buf, --index, 'e');
+                StringUTF16.putChar(buf, --index, 's');
+                StringUTF16.putChar(buf, --index, 'l');
+                StringUTF16.putChar(buf, --index, 'a');
+                StringUTF16.putChar(buf, --index, 'f');
+            }
+        }
+        return index;
+    }
+
+    /**
+     * Prepends the stringly representation of byte value into buffer,
+     * given the coder and final index. Index is measured in chars, not in bytes!
+     *
+     * @param index final char index in the buffer
+     * @param buf   buffer to append to
+     * @param coder coder to add with
+     * @param value byte value to encode
+     * @return new index
+     */
+    static int prepend(int index, byte[] buf, byte coder, byte value) {
+        return prepend(index, buf, coder, (int)value);
+    }
+
+    /**
+     * Prepends the stringly representation of char value into buffer,
+     * given the coder and final index. Index is measured in chars, not in bytes!
+     *
+     * @param index final char index in the buffer
+     * @param buf   buffer to append to
+     * @param coder coder to add with
+     * @param value char value to encode
+     * @return new index
+     */
+    static int prepend(int index, byte[] buf, byte coder, char value) {
+        if (coder == String.LATIN1) {
+            buf[--index] = (byte) (value & 0xFF);
+        } else {
+            StringUTF16.putChar(buf, --index, value);
+        }
+        return index;
+    }
+
+    /**
+     * Prepends the stringly representation of short value into buffer,
+     * given the coder and final index. Index is measured in chars, not in bytes!
+     *
+     * @param index final char index in the buffer
+     * @param buf   buffer to append to
+     * @param coder coder to add with
+     * @param value short value to encode
+     * @return new index
+     */
+    static int prepend(int index, byte[] buf, byte coder, short value) {
+        return prepend(index, buf, coder, (int)value);
+    }
+
+    /**
+     * Prepends the stringly representation of integer value into buffer,
+     * given the coder and final index. Index is measured in chars, not in bytes!
+     *
+     * @param index final char index in the buffer
+     * @param buf   buffer to append to
+     * @param coder coder to add with
+     * @param value integer value to encode
+     * @return new index
+     */
+    static int prepend(int index, byte[] buf, byte coder, int value) {
+        if (coder == String.LATIN1) {
+            return Integer.getChars(value, index, buf);
+        } else {
+            return Integer.getCharsUTF16(value, index, buf);
+        }
+    }
+
+    /**
+     * Prepends the stringly representation of long value into buffer,
+     * given the coder and final index. Index is measured in chars, not in bytes!
+     *
+     * @param index final char index in the buffer
+     * @param buf   buffer to append to
+     * @param coder coder to add with
+     * @param value long value to encode
+     * @return new index
+     */
+    static int prepend(int index, byte[] buf, byte coder, long value) {
+        if (coder == String.LATIN1) {
+            return Long.getChars(value, index, buf);
+        } else {
+            return Long.getCharsUTF16(value, index, buf);
+        }
+    }
+
+    /**
+     * Prepends the stringly representation of String value into buffer,
+     * given the coder and final index. Index is measured in chars, not in bytes!
+     *
+     * @param index final char index in the buffer
+     * @param buf   buffer to append to
+     * @param coder coder to add with
+     * @param value String value to encode
+     * @return new index
+     */
+    static int prepend(int index, byte[] buf, byte coder, String value) {
+        index -= value.length();
+        value.getBytes(buf, index, coder);
+        return index;
+    }
+
+    /**
+     * Instantiates the String with given buffer and coder
+     * @param buf     buffer to use
+     * @param coder   coder to use
+     * @return String resulting string
+     */
+    static String newString(byte[] buf, byte coder) {
+        // Use the private, non-copying constructor (unsafe!)
+        return new String(buf, coder);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatException.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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 java.lang.invoke;
+
+/**
+ * StringConcatException is thrown by {@link StringConcatFactory} when linkage
+ * invariants are violated.
+ */
+public class StringConcatException extends Exception {
+    private static final long serialVersionUID = 292L + 9L;
+
+    /**
+     * Constructs an exception with a message
+     * @param msg exception message
+     */
+    public StringConcatException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Constructs an exception with a message and a linked throwable
+     * @param msg   exception message
+     * @param cause throwable cause
+     */
+    public StringConcatException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,1790 @@
+/*
+ * Copyright (c) 2015, 2016, 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 java.lang.invoke;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.vm.annotation.ForceInline;
+import sun.misc.Unsafe;
+
+import java.lang.invoke.MethodHandles.Lookup;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+/**
+ * <p>Methods to facilitate the creation of String concatenation methods, that
+ * can be used to efficiently concatenate a known number of arguments of known
+ * types, possibly after type adaptation and partial evaluation of arguments.
+ * These methods are typically used as <em>bootstrap methods</em> for {@code
+ * invokedynamic} call sites, to support the <em>string concatenation</em>
+ * feature of the Java Programming Language.
+ *
+ * <p>Indirect access to the behavior specified by the provided {@code
+ * MethodHandle} proceeds in order through two phases:
+ *
+ * <ol>
+ *     <li><em>Linkage</em> occurs when the methods in this class are invoked.
+ * They take as arguments a method type describing the concatenated arguments
+ * count and types, and optionally the String <em>recipe</em>, plus the
+ * constants that participate in the String concatenation. The details on
+ * accepted recipe shapes are described further below. Linkage may involve
+ * dynamically loading a new class that implements the expected concatenation
+ * behavior. The {@code CallSite} holds the {@code MethodHandle} pointing to the
+ * exact concatenation method. The concatenation methods may be shared among
+ * different {@code CallSite}s, e.g. if linkage methods produce them as pure
+ * functions.</li>
+ *
+ * <li><em>Invocation</em> occurs when a generated concatenation method is
+ * invoked with the exact dynamic arguments. This may occur many times for a
+ * single concatenation method. The method referenced by the behavior {@code
+ * MethodHandle} is invoked with the static arguments and any additional dynamic
+ * arguments provided on invocation, as if by {@link MethodHandle#invoke(Object...)}.</li>
+ * </ol>
+ *
+ * <p> This class provides two forms of linkage methods: a simple version
+ * ({@link #makeConcat(java.lang.invoke.MethodHandles.Lookup, String,
+ * MethodType)}) using only the dynamic arguments, and an advanced version
+ * ({@link #makeConcatWithConstants(java.lang.invoke.MethodHandles.Lookup,
+ * String, MethodType, String, Object...)} using the advanced forms of capturing
+ * the constant arguments. The advanced strategy can produce marginally better
+ * invocation bytecode, at the expense of exploding the number of shapes of
+ * string concatenation methods present at runtime, because those shapes would
+ * include constant static arguments as well.
+ *
+ * @author Aleksey Shipilev
+ * @author Remi Forax
+ * @author Peter Levart
+ *
+ * @apiNote
+ * <p>There is a JVM limit (classfile structural constraint): no method
+ * can call with more than 255 slots. This limits the number of static and
+ * dynamic arguments one can pass to bootstrap method. Since there are potential
+ * concatenation strategies that use {@code MethodHandle} combinators, we need
+ * to reserve a few empty slots on the parameter lists to to capture the
+ * temporal results. This is why bootstrap methods in this factory do not accept
+ * more than 200 argument slots. Users requiring more than 200 argument slots in
+ * concatenation are expected to split the large concatenation in smaller
+ * expressions.
+ */
+public final class StringConcatFactory {
+
+    /**
+     * Tag used to demarcate an ordinary argument.
+     */
+    private static final char TAG_ARG = '\u0001';
+
+    /**
+     * Tag used to demarcate a constant.
+     */
+    private static final char TAG_CONST = '\u0002';
+
+    /**
+     * Maximum number of argument slots in String Concat call.
+     *
+     * While the maximum number of argument slots that indy call can handle is 253,
+     * we do not use all those slots, to let the strategies with MethodHandle
+     * combinators to use some arguments.
+     */
+    private static final int MAX_INDY_CONCAT_ARG_SLOTS = 200;
+
+    /**
+     * Concatenation strategy to use. See {@link Strategy} for possible options.
+     * This option is controllable with -Djava.lang.invoke.stringConcat JDK option.
+     */
+    private static final Strategy STRATEGY;
+
+    /**
+     * Default strategy to use for concatenation.
+     */
+    private static final Strategy DEFAULT_STRATEGY = Strategy.BC_SB;
+
+    private enum Strategy {
+        /**
+         * Bytecode generator, calling into {@link java.lang.StringBuilder}.
+         */
+        BC_SB,
+
+        /**
+         * Bytecode generator, calling into {@link java.lang.StringBuilder};
+         * but trying to estimate the required storage.
+         */
+        BC_SB_SIZED,
+
+        /**
+         * Bytecode generator, calling into {@link java.lang.StringBuilder};
+         * but computing the required storage exactly.
+         */
+        BC_SB_SIZED_EXACT,
+
+        /**
+         * MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
+         * This strategy also tries to estimate the required storage.
+         */
+        MH_SB_SIZED,
+
+        /**
+         * MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
+         * This strategy also estimate the required storage exactly.
+         */
+        MH_SB_SIZED_EXACT,
+
+        /**
+         * MethodHandle-based generator, that constructs its own byte[] array from
+         * the arguments. It computes the required storage exactly.
+         */
+        MH_INLINE_SIZED_EXACT
+    }
+
+    /**
+     * Enables debugging: this may print debugging messages, perform additional (non-neutral for performance)
+     * checks, etc.
+     */
+    private static final boolean DEBUG;
+
+    /**
+     * Enables caching of strategy stubs. This may improve the linkage time by reusing the generated
+     * code, at the expense of contaminating the profiles.
+     */
+    private static final boolean CACHE_ENABLE;
+
+    private static final ConcurrentMap<Key, MethodHandle> CACHE;
+
+    static {
+        // Poke the privileged block once, taking everything we need:
+        final Object[] values = new Object[3];
+        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
+            values[0] = System.getProperty("java.lang.invoke.stringConcat");
+            values[1] = Boolean.getBoolean("java.lang.invoke.stringConcat.cache");
+            values[2] = Boolean.getBoolean("java.lang.invoke.stringConcat.debug");
+            return null;
+        });
+
+        final String strategy = (String)  values[0];
+        CACHE_ENABLE          = (Boolean) values[1];
+        DEBUG                 = (Boolean) values[2];
+
+        STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy);
+        CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null;
+    }
+
+    private static final class Key {
+        final MethodType mt;
+        final Recipe recipe;
+
+        public Key(MethodType mt, Recipe recipe) {
+            this.mt = mt;
+            this.recipe = recipe;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Key key = (Key) o;
+
+            if (!mt.equals(key.mt)) return false;
+            if (!recipe.equals(key.recipe)) return false;
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = mt.hashCode();
+            result = 31 * result + recipe.hashCode();
+            return result;
+        }
+    }
+
+    /**
+     * Parses the recipe string, and produces the traversable collection of
+     * {@link java.lang.invoke.StringConcatFactory.RecipeElement}-s for generator
+     * strategies. Notably, this class parses out the constants from the recipe
+     * and from other static arguments.
+     */
+    private static final class Recipe {
+        private final List<RecipeElement> elements;
+        private final List<RecipeElement> elementsRev;
+
+        public Recipe(String src, Object[] constants) {
+            List<RecipeElement> el = new ArrayList<>();
+
+            int constC = 0;
+            int argC = 0;
+
+            StringBuilder acc = new StringBuilder();
+
+            for (int i = 0; i < src.length(); i++) {
+                char c = src.charAt(i);
+
+                if (c == TAG_CONST || c == TAG_ARG) {
+                    // Detected a special tag, flush all accumulated characters
+                    // as a constant first:
+                    if (acc.length() > 0) {
+                        el.add(new RecipeElement(acc.toString()));
+                        acc.setLength(0);
+                    }
+                    if (c == TAG_CONST) {
+                        Object cnst = constants[constC++];
+                        el.add(new RecipeElement(cnst));
+                    }
+                    if (c == TAG_ARG) {
+                        el.add(new RecipeElement(argC++));
+                    }
+                } else {
+                    // Not a special characters, this is a constant embedded into
+                    // the recipe itself.
+                    acc.append(c);
+                }
+            }
+
+            // Flush the remaining characters as constant:
+            if (acc.length() > 0) {
+                el.add(new RecipeElement(acc.toString()));
+            }
+
+            elements = new ArrayList<>(el);
+            Collections.reverse(el);
+            elementsRev = el;
+        }
+
+        public Collection<RecipeElement> getElements() {
+            return elements;
+        }
+
+        public Collection<RecipeElement> getElementsReversed() {
+            return elementsRev;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Recipe recipe = (Recipe) o;
+            return elements.equals(recipe.elements);
+        }
+
+        @Override
+        public int hashCode() {
+            return elements.hashCode();
+        }
+    }
+
+    private static final class RecipeElement {
+        private final Object value;
+        private final int argPos;
+        private final Tag tag;
+
+        public RecipeElement(Object cnst) {
+            this.value = Objects.requireNonNull(cnst);
+            this.argPos = -1;
+            this.tag = Tag.CONST;
+        }
+
+        public RecipeElement(int arg) {
+            this.value = null;
+            this.argPos = arg;
+            this.tag = Tag.ARG;
+        }
+
+        public Object getValue() {
+            assert (tag == Tag.CONST);
+            return value;
+        }
+
+        public int getArgPos() {
+            assert (tag == Tag.ARG);
+            return argPos;
+        }
+
+        public Tag getTag() {
+            return tag;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            RecipeElement that = (RecipeElement) o;
+
+            if (tag != that.tag) return false;
+            if (tag == Tag.CONST && (!value.equals(that.value))) return false;
+            if (tag == Tag.ARG && (argPos != that.argPos)) return false;
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return tag.hashCode();
+        }
+    }
+
+    private enum Tag {
+        CONST, ARG
+    }
+
+    /**
+     * Facilitates the creation of optimized String concatenation methods, that
+     * can be used to efficiently concatenate a known number of arguments of
+     * known types, possibly after type adaptation and partial evaluation of
+     * arguments. Typically used as a <em>bootstrap method</em> for {@code
+     * invokedynamic} call sites, to support the <em>string concatenation</em>
+     * feature of the Java Programming Language.
+     *
+     * <p>When the target of the {@code CallSite} returned from this method is
+     * invoked, it returns the result of String concatenation, taking all
+     * function arguments passed to the linkage method as inputs for
+     * concatenation. The target signature is given by {@code concatType}.
+     * The arguments are concatenated as per requirements stated in JLS 15.18.1
+     * "String Concatenation Operator +". Notably, the inputs are converted as
+     * per JLS 5.1.11 "String Conversion", and combined from left to right.
+     *
+     * <p>Assume the linkage arguments are as follows:
+     *
+     * <ul>
+     *     <li>{@code concatType}, describing the {@code CallSite} signature</li>
+     * </ul>
+     *
+     * <p>Then the following linkage invariants must hold:
+     *
+     * <ul>
+     *     <li>The parameter count in {@code concatType} is less than or equal to 200</li>
+     *
+     *     <li>The return type in {@code concatType} is assignable from {@link java.lang.String}</li>
+     * </ul>
+     *
+     * @param lookup   Represents a lookup context with the accessibility
+     *                 privileges of the caller.  When used with {@code
+     *                 invokedynamic}, this is stacked automatically by the VM.
+     * @param name     The name of the method to implement. This name is
+     *                 arbitrary, and has no meaning for this linkage method.
+     *                 When used with {@code invokedynamic}, this is provided by
+     *                 the {@code NameAndType} of the {@code InvokeDynamic}
+     *                 structure and is stacked automatically by the VM.
+     * @param concatType The expected signature of the {@code CallSite}.  The
+     *                   parameter types represent the types of concatenation
+     *                   arguments; the return type is always assignable from {@link
+     *                   java.lang.String}.  When used with {@code invokedynamic},
+     *                   this is provided by the {@code NameAndType} of the {@code
+     *                   InvokeDynamic} structure and is stacked automatically by
+     *                   the VM.
+     * @return a CallSite whose target can be used to perform String
+     * concatenation, with dynamic concatenation arguments described by the given
+     * {@code concatType}.
+     * @throws StringConcatException If any of the linkage invariants described
+     *                               here are violated.
+     * @throws NullPointerException If any of the incoming arguments is null.
+     *                              This will never happen when a bootstrap method
+     *                              is called with invokedynamic.
+     *
+     * @jls  5.1.11 String Conversion
+     * @jls 15.18.1 String Concatenation Operator +
+     */
+    public static CallSite makeConcat(MethodHandles.Lookup lookup,
+                                      String name,
+                                      MethodType concatType) throws StringConcatException {
+        if (DEBUG) {
+            System.out.println("StringConcatFactory " + STRATEGY + " is here for " + concatType);
+        }
+
+        return doStringConcat(lookup, name, concatType, true, null);
+    }
+
+    /**
+     * Facilitates the creation of optimized String concatenation methods, that
+     * can be used to efficiently concatenate a known number of arguments of
+     * known types, possibly after type adaptation and partial evaluation of
+     * arguments. Typically used as a <em>bootstrap method</em> for {@code
+     * invokedynamic} call sites, to support the <em>string concatenation</em>
+     * feature of the Java Programming Language.
+     *
+     * <p>When the target of the {@code CallSite} returned from this method is
+     * invoked, it returns the result of String concatenation, taking all
+     * function arguments and constants passed to the linkage method as inputs for
+     * concatenation. The target signature is given by {@code concatType}, and
+     * does not include constants. The arguments are concatenated as per requirements
+     * stated in JLS 15.18.1 "String Concatenation Operator +". Notably, the inputs
+     * are converted as per JLS 5.1.11 "String Conversion", and combined from left
+     * to right.
+     *
+     * <p>The concatenation <em>recipe</em> is a String description for the way to
+     * construct a concatenated String from the arguments and constants. The
+     * recipe is processed from left to right, and each character represents an
+     * input to concatenation. Recipe characters mean:
+     *
+     * <ul>
+     *
+     *   <li><em>\1 (Unicode point 0001)</em>: an ordinary argument. This
+     *   input is passed through dynamic argument, and is provided during the
+     *   concatenation method invocation. This input can be null.</li>
+     *
+     *   <li><em>\2 (Unicode point 0002):</em> a constant. This input passed
+     *   through static bootstrap argument. This constant can be any value
+     *   representable in constant pool. If necessary, the factory would call
+     *   {@code toString} to perform a one-time String conversion.</li>
+     *
+     *   <li><em>Any other char value:</em> a single character constant.</li>
+     * </ul>
+     *
+     * <p>Assume the linkage arguments are as follows:
+     *
+     * <ul>
+     *   <li>{@code concatType}, describing the {@code CallSite} signature</li>
+     *   <li>{@code recipe}, describing the String recipe</li>
+     *   <li>{@code constants}, the vararg array of constants</li>
+     * </ul>
+     *
+     * <p>Then the following linkage invariants must hold:
+     *
+     * <ul>
+     *   <li>The parameter count in {@code concatType} is less than or equal to
+     *   200</li>
+     *
+     *   <li>The parameter count in {@code concatType} equals to number of \1 tags
+     *   in {@code recipe}</li>
+     *
+     *   <li>The return type in {@code concatType} is assignable
+     *   from {@link java.lang.String}, and matches the return type of the
+     *   returned {@link MethodHandle}</li>
+     *
+     *   <li>The number of elements in {@code constants} equals to number of \2
+     *   tags in {@code recipe}</li>
+     * </ul>
+     *
+     * @param lookup    Represents a lookup context with the accessibility
+     *                  privileges of the caller. When used with {@code
+     *                  invokedynamic}, this is stacked automatically by the
+     *                  VM.
+     * @param name      The name of the method to implement. This name is
+     *                  arbitrary, and has no meaning for this linkage method.
+     *                  When used with {@code invokedynamic}, this is provided
+     *                  by the {@code NameAndType} of the {@code InvokeDynamic}
+     *                  structure and is stacked automatically by the VM.
+     * @param concatType The expected signature of the {@code CallSite}.  The
+     *                  parameter types represent the types of dynamic concatenation
+     *                  arguments; the return type is always assignable from {@link
+     *                  java.lang.String}.  When used with {@code
+     *                  invokedynamic}, this is provided by the {@code
+     *                  NameAndType} of the {@code InvokeDynamic} structure and
+     *                  is stacked automatically by the VM.
+     * @param recipe    Concatenation recipe, described above.
+     * @param constants A vararg parameter representing the constants passed to
+     *                  the linkage method.
+     * @return a CallSite whose target can be used to perform String
+     * concatenation, with dynamic concatenation arguments described by the given
+     * {@code concatType}.
+     * @throws StringConcatException If any of the linkage invariants described
+     *                               here are violated.
+     * @throws NullPointerException If any of the incoming arguments is null, or
+     *                              any constant in {@code recipe} is null.
+     *                              This will never happen when a bootstrap method
+     *                              is called with invokedynamic.
+     * @apiNote Code generators have three distinct ways to process a constant
+     * string operand S in a string concatenation expression.  First, S can be
+     * materialized as a reference (using ldc) and passed as an ordinary argument
+     * (recipe '\1'). Or, S can be stored in the constant pool and passed as a
+     * constant (recipe '\2') . Finally, if S contains neither of the recipe
+     * tag characters ('\1', '\2') then S can be interpolated into the recipe
+     * itself, causing its characters to be inserted into the result.
+     *
+     * @jls  5.1.11 String Conversion
+     * @jls 15.18.1 String Concatenation Operator +
+     */
+    public static CallSite makeConcatWithConstants(MethodHandles.Lookup lookup,
+                                                   String name,
+                                                   MethodType concatType,
+                                                   String recipe,
+                                                   Object... constants) throws StringConcatException {
+        if (DEBUG) {
+            System.out.println("StringConcatFactory " + STRATEGY + " is here for " + concatType + ", {" + recipe + "}, " + Arrays.toString(constants));
+        }
+
+        return doStringConcat(lookup, name, concatType, false, recipe, constants);
+    }
+
+    private static CallSite doStringConcat(MethodHandles.Lookup lookup,
+                                           String name,
+                                           MethodType concatType,
+                                           boolean generateRecipe,
+                                           String recipe,
+                                           Object... constants) throws StringConcatException {
+        Objects.requireNonNull(lookup, "Lookup is null");
+        Objects.requireNonNull(name, "Name is null");
+        Objects.requireNonNull(concatType, "Concat type is null");
+        Objects.requireNonNull(constants, "Constants are null");
+
+        for (Object o : constants) {
+            Objects.requireNonNull(o, "Cannot accept null constants");
+        }
+
+        int cCount = 0;
+        int oCount = 0;
+        if (generateRecipe) {
+            // Mock the recipe to reuse the concat generator code
+            char[] value = new char[concatType.parameterCount()];
+            Arrays.fill(value, TAG_ARG);
+            recipe = new String(value);
+            oCount = concatType.parameterCount();
+        } else {
+            Objects.requireNonNull(recipe, "Recipe is null");
+
+            for (int i = 0; i < recipe.length(); i++) {
+                char c = recipe.charAt(i);
+                if (c == TAG_CONST) cCount++;
+                if (c == TAG_ARG)   oCount++;
+            }
+        }
+
+        if (oCount != concatType.parameterCount()) {
+            throw new StringConcatException(
+                    "Mismatched number of concat arguments: recipe wants " +
+                            oCount +
+                            " arguments, but signature provides " +
+                            concatType.parameterCount());
+        }
+
+        if (cCount != constants.length) {
+            throw new StringConcatException(
+                    "Mismatched number of concat constants: recipe wants " +
+                            cCount +
+                            " constants, but only " +
+                            constants.length +
+                            " are passed");
+        }
+
+        if (!concatType.returnType().isAssignableFrom(String.class)) {
+            throw new StringConcatException(
+                    "The return type should be compatible with String, but it is " +
+                            concatType.returnType());
+        }
+
+        if (concatType.parameterCount() > MAX_INDY_CONCAT_ARG_SLOTS) {
+            throw new StringConcatException("Too many concat argument slots: " +
+                    concatType.parameterCount() +
+                    ", can only accept " +
+                    MAX_INDY_CONCAT_ARG_SLOTS);
+        }
+
+        MethodType mt = adaptType(concatType);
+
+        Recipe rec = new Recipe(recipe, constants);
+
+        MethodHandle mh;
+        if (CACHE_ENABLE) {
+            Key key = new Key(mt, rec);
+            mh = CACHE.get(key);
+            if (mh == null) {
+                mh = generate(lookup, mt, rec);
+                CACHE.put(key, mh);
+            }
+        } else {
+            mh = generate(lookup, mt, rec);
+        }
+        return new ConstantCallSite(mh.asType(concatType));
+    }
+
+    /**
+     * Adapt method type to an API we are going to use.
+     *
+     * This strips the concrete classes from the signatures, thus preventing
+     * class leakage when we cache the concatenation stubs.
+     *
+     * @param args actual argument types
+     * @return argument types the strategy is going to use
+     */
+    private static MethodType adaptType(MethodType args) {
+        Class<?>[] ptypes = args.parameterArray();
+        boolean changed = false;
+        for (int i = 0; i < ptypes.length; i++) {
+            Class<?> ptype = ptypes[i];
+            if (!ptype.isPrimitive() &&
+                    ptype != String.class &&
+                    ptype != Object.class) { // truncate to Object
+                ptypes[i] = Object.class;
+                changed = true;
+            }
+            // else other primitives or String or Object (unchanged)
+        }
+        return changed
+                ? MethodType.methodType(args.returnType(), ptypes)
+                : args;
+    }
+
+    private static MethodHandle generate(Lookup lookup, MethodType mt, Recipe recipe) throws StringConcatException {
+        try {
+            switch (STRATEGY) {
+                case BC_SB:
+                    return BytecodeStringBuilderStrategy.generate(lookup, mt, recipe, Mode.DEFAULT);
+                case BC_SB_SIZED:
+                    return BytecodeStringBuilderStrategy.generate(lookup, mt, recipe, Mode.SIZED);
+                case BC_SB_SIZED_EXACT:
+                    return BytecodeStringBuilderStrategy.generate(lookup, mt, recipe, Mode.SIZED_EXACT);
+                case MH_SB_SIZED:
+                    return MethodHandleStringBuilderStrategy.generate(mt, recipe, Mode.SIZED);
+                case MH_SB_SIZED_EXACT:
+                    return MethodHandleStringBuilderStrategy.generate(mt, recipe, Mode.SIZED_EXACT);
+                case MH_INLINE_SIZED_EXACT:
+                    return MethodHandleInlineCopyStrategy.generate(mt, recipe);
+                default:
+                    throw new StringConcatException("Concatenation strategy " + STRATEGY + " is not implemented");
+            }
+        } catch (Throwable t) {
+            throw new StringConcatException("Generator failed", t);
+        }
+    }
+
+    private enum Mode {
+        DEFAULT(false, false),
+        SIZED(true, false),
+        SIZED_EXACT(true, true);
+
+        private final boolean sized;
+        private final boolean exact;
+
+        Mode(boolean sized, boolean exact) {
+            this.sized = sized;
+            this.exact = exact;
+        }
+
+        boolean isSized() {
+            return sized;
+        }
+
+        boolean isExact() {
+            return exact;
+        }
+    }
+
+    /**
+     * Bytecode StringBuilder strategy.
+     *
+     * <p>This strategy operates in three modes, gated by {@link Mode}.
+     *
+     * <p><b>{@link Strategy#BC_SB}: "bytecode StringBuilder".</b>
+     *
+     * <p>This strategy spins up the bytecode that has the same StringBuilder
+     * chain javac would otherwise emit. This strategy uses only the public API,
+     * and comes as the baseline for the current JDK behavior. On other words,
+     * this strategy moves the javac generated bytecode to runtime. The
+     * generated bytecode is loaded via Unsafe.defineAnonymousClass, but with
+     * the caller class coming from the BSM -- in other words, the protection
+     * guarantees are inherited from the method where invokedynamic was
+     * originally called. This means, among other things, that the bytecode is
+     * verified for all non-JDK uses.
+     *
+     * <p><b>{@link Strategy#BC_SB_SIZED}: "bytecode StringBuilder, but
+     * sized".</b>
+     *
+     * <p>This strategy acts similarly to {@link Strategy#BC_SB}, but it also
+     * tries to guess the capacity required for StringBuilder to accept all
+     * arguments without resizing. This strategy only makes an educated guess:
+     * it only guesses the space required for known types (e.g. primitives and
+     * Strings), but does not otherwise convert arguments. Therefore, the
+     * capacity estimate may be wrong, and StringBuilder may have to
+     * transparently resize or trim when doing the actual concatenation. While
+     * this does not constitute a correctness issue (in the end, that what BC_SB
+     * has to do anyway), this does pose a potential performance problem.
+     *
+     * <p><b>{@link Strategy#BC_SB_SIZED_EXACT}: "bytecode StringBuilder, but
+     * sized exactly".</b>
+     *
+     * <p>This strategy improves on @link Strategy#BC_SB_SIZED}, by first
+     * converting all arguments to String in order to get the exact capacity
+     * StringBuilder should have. The conversion is done via the public
+     * String.valueOf and/or Object.toString methods, and does not touch any
+     * private String API.
+     */
+    private static final class BytecodeStringBuilderStrategy {
+        static final Unsafe UNSAFE = Unsafe.getUnsafe();
+        static final int CLASSFILE_VERSION = 52;
+        static final String NAME_FACTORY = "concat";
+        static final String CLASS_NAME = "java/lang/String$Concat";
+
+        private BytecodeStringBuilderStrategy() {
+            // no instantiation
+        }
+
+        private static MethodHandle generate(MethodHandles.Lookup lookup, MethodType args, Recipe recipe, Mode mode) throws Exception {
+            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+
+            cw.visit(CLASSFILE_VERSION,
+                    ACC_SUPER + ACC_PUBLIC + ACC_FINAL + ACC_SYNTHETIC,
+                    CLASS_NAME,
+                    null,
+                    "java/lang/Object",
+                    null
+            );
+
+            MethodVisitor mv = cw.visitMethod(
+                    ACC_PUBLIC + ACC_STATIC + ACC_FINAL,
+                    NAME_FACTORY,
+                    args.toMethodDescriptorString(),
+                    null,
+                    null);
+
+            mv.visitAnnotation("Ljdk/internal/vm/annotation/ForceInline;", true);
+            mv.visitCode();
+
+            Class<?>[] arr = args.parameterArray();
+            boolean[] guaranteedNonNull = new boolean[arr.length];
+
+            if (mode.isExact()) {
+                /*
+                    In exact mode, we need to convert all arguments to their String representations,
+                    as this allows to compute their String sizes exactly. We cannot use private
+                    methods for primitives in here, therefore we need to convert those as well.
+
+                    We also record what arguments are guaranteed to be non-null as the result
+                    of the conversion. String.valueOf does the null checks for us. The only
+                    corner case to take care of is String.valueOf(Object) returning null itself.
+
+                    Also, if any conversion happened, then the slot indices in the incoming
+                    arguments are not equal to the final local maps. The only case this may break
+                    is when converting 2-slot long/double argument to 1-slot String. Therefore,
+                    we get away with tracking modified offset, since no conversion can overwrite
+                    the upcoming the argument.
+                 */
+
+                int off = 0;
+                int modOff = 0;
+                for (int c = 0; c < arr.length; c++) {
+                    Class<?> cl = arr[c];
+                    if (cl == String.class) {
+                        if (off != modOff) {
+                            mv.visitIntInsn(getLoadOpcode(cl), off);
+                            mv.visitIntInsn(ASTORE, modOff);
+                        }
+                    } else {
+                        mv.visitIntInsn(getLoadOpcode(cl), off);
+                        mv.visitMethodInsn(
+                                INVOKESTATIC,
+                                "java/lang/String",
+                                "valueOf",
+                                getStringValueOfDesc(cl),
+                                false
+                        );
+                        mv.visitIntInsn(ASTORE, modOff);
+                        arr[c] = String.class;
+                        guaranteedNonNull[c] = cl.isPrimitive();
+                    }
+                    off += getParameterSize(cl);
+                    modOff += getParameterSize(String.class);
+                }
+            }
+
+            if (mode.isSized()) {
+                /*
+                    When operating in sized mode (this includes exact mode), it makes sense to make
+                    StringBuilder append chains look familiar to OptimizeStringConcat. For that, we
+                    need to do null-checks early, not make the append chain shape simpler.
+                 */
+
+                int off = 0;
+                for (RecipeElement el : recipe.getElements()) {
+                    switch (el.getTag()) {
+                        case CONST: {
+                            // Guaranteed non-null, no null check required.
+                            break;
+                        }
+                        case ARG: {
+                            // Null-checks are needed only for String arguments, and when a previous stage
+                            // did not do implicit null-checks. If a String is null, we eagerly replace it
+                            // with "null" constant. Note, we omit Objects here, because we don't call
+                            // .length() on them down below.
+                            int ac = el.getArgPos();
+                            Class<?> cl = arr[ac];
+                            if (cl == String.class && !guaranteedNonNull[ac]) {
+                                Label l0 = new Label();
+                                mv.visitIntInsn(ALOAD, off);
+                                mv.visitJumpInsn(IFNONNULL, l0);
+                                mv.visitLdcInsn("null");
+                                mv.visitIntInsn(ASTORE, off);
+                                mv.visitLabel(l0);
+                            }
+                            off += getParameterSize(cl);
+                            break;
+                        }
+                        default:
+                            throw new StringConcatException("Unhandled tag: " + el.getTag());
+                    }
+                }
+            }
+
+            // Prepare StringBuilder instance
+            mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
+            mv.visitInsn(DUP);
+
+            if (mode.isSized()) {
+                /*
+                    Sized mode requires us to walk through the arguments, and estimate the final length.
+                    In exact mode, this will operate on Strings only. This code would accumulate the
+                    final length on stack.
+                 */
+                int len = 0;
+                int off = 0;
+
+                mv.visitInsn(ICONST_0);
+
+                for (RecipeElement el : recipe.getElements()) {
+                    switch (el.getTag()) {
+                        case CONST: {
+                            Object cnst = el.getValue();
+                            len += cnst.toString().length();
+                            break;
+                        }
+                        case ARG: {
+                            /*
+                                If an argument is String, then we can call .length() on it. Sized/Exact modes have
+                                converted arguments for us. If an argument is primitive, we can provide a guess
+                                for its String representation size.
+                            */
+                            Class<?> cl = arr[el.getArgPos()];
+                            if (cl == String.class) {
+                                mv.visitIntInsn(ALOAD, off);
+                                mv.visitMethodInsn(
+                                        INVOKEVIRTUAL,
+                                        "java/lang/String",
+                                        "length",
+                                        "()I",
+                                        false
+                                );
+                                mv.visitInsn(IADD);
+                            } else if (cl.isPrimitive()) {
+                                len += estimateSize(cl);
+                            }
+                            off += getParameterSize(cl);
+                            break;
+                        }
+                        default:
+                            throw new StringConcatException("Unhandled tag: " + el.getTag());
+                    }
+                }
+
+                // Constants have non-zero length, mix in
+                if (len > 0) {
+                    iconst(mv, len);
+                    mv.visitInsn(IADD);
+                }
+
+                mv.visitMethodInsn(
+                        INVOKESPECIAL,
+                        "java/lang/StringBuilder",
+                        "<init>",
+                        "(I)V",
+                        false
+                );
+            } else {
+                mv.visitMethodInsn(
+                        INVOKESPECIAL,
+                        "java/lang/StringBuilder",
+                        "<init>",
+                        "()V",
+                        false
+                );
+            }
+
+            // At this point, we have a blank StringBuilder on stack, fill it in with .append calls.
+            {
+                int off = 0;
+                for (RecipeElement el : recipe.getElements()) {
+                    String desc;
+                    switch (el.getTag()) {
+                        case CONST: {
+                            Object cnst = el.getValue();
+                            mv.visitLdcInsn(cnst);
+                            desc = getSBAppendDesc(cnst.getClass());
+                            break;
+                        }
+                        case ARG: {
+                            Class<?> cl = arr[el.getArgPos()];
+                            mv.visitVarInsn(getLoadOpcode(cl), off);
+                            off += getParameterSize(cl);
+                            desc = getSBAppendDesc(cl);
+                            break;
+                        }
+                        default:
+                            throw new StringConcatException("Unhandled tag: " + el.getTag());
+                    }
+                    mv.visitMethodInsn(
+                            INVOKEVIRTUAL,
+                            "java/lang/StringBuilder",
+                            "append",
+                            desc,
+                            false
+                    );
+                }
+            }
+
+            if (DEBUG && mode.isExact()) {
+                /*
+                    Exactness checks compare the final StringBuilder.capacity() with a resulting
+                    String.length(). If these values disagree, that means StringBuilder had to perform
+                    storage trimming, which defeats the purpose of exact strategies.
+                 */
+
+                mv.visitInsn(DUP);
+
+                mv.visitMethodInsn(
+                        INVOKEVIRTUAL,
+                        "java/lang/StringBuilder",
+                        "capacity",
+                        "()I",
+                        false
+                );
+
+                mv.visitIntInsn(ISTORE, 0);
+
+                mv.visitMethodInsn(
+                        INVOKEVIRTUAL,
+                        "java/lang/StringBuilder",
+                        "toString",
+                        "()Ljava/lang/String;",
+                        false
+                );
+
+                mv.visitInsn(DUP);
+
+                mv.visitMethodInsn(
+                        INVOKEVIRTUAL,
+                        "java/lang/String",
+                        "length",
+                        "()I",
+                        false
+                );
+
+                mv.visitIntInsn(ILOAD, 0);
+
+                Label l0 = new Label();
+                mv.visitJumpInsn(IF_ICMPEQ, l0);
+
+                mv.visitTypeInsn(NEW, "java/lang/AssertionError");
+                mv.visitInsn(DUP);
+                mv.visitLdcInsn("Failed exactness check");
+                mv.visitMethodInsn(INVOKESPECIAL,
+                        "java/lang/AssertionError",
+                        "<init>",
+                        "(Ljava/lang/Object;)V",
+                        false);
+                mv.visitInsn(ATHROW);
+
+                mv.visitLabel(l0);
+            } else {
+                mv.visitMethodInsn(
+                        INVOKEVIRTUAL,
+                        "java/lang/StringBuilder",
+                        "toString",
+                        "()Ljava/lang/String;",
+                        false
+                );
+            }
+
+            mv.visitInsn(ARETURN);
+
+            mv.visitMaxs(-1, -1);
+            mv.visitEnd();
+            cw.visitEnd();
+
+            Class<?> targetClass = lookup.lookupClass();
+            final byte[] classBytes = cw.toByteArray();
+            final Class<?> innerClass = UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
+
+            try {
+                UNSAFE.ensureClassInitialized(innerClass);
+                return lookup.findStatic(innerClass, NAME_FACTORY, args);
+            } catch (ReflectiveOperationException e) {
+                throw new StringConcatException("Exception finding constructor", e);
+            }
+        }
+
+        private static String getSBAppendDesc(Class<?> cl) {
+            if (cl.isPrimitive()) {
+                if (cl == Integer.TYPE || cl == Byte.TYPE || cl == Short.TYPE) {
+                    return "(I)Ljava/lang/StringBuilder;";
+                } else if (cl == Boolean.TYPE) {
+                    return "(Z)Ljava/lang/StringBuilder;";
+                } else if (cl == Character.TYPE) {
+                    return "(C)Ljava/lang/StringBuilder;";
+                } else if (cl == Double.TYPE) {
+                    return "(D)Ljava/lang/StringBuilder;";
+                } else if (cl == Float.TYPE) {
+                    return "(F)Ljava/lang/StringBuilder;";
+                } else if (cl == Long.TYPE) {
+                    return "(J)Ljava/lang/StringBuilder;";
+                } else {
+                    throw new IllegalStateException("Unhandled primitive StringBuilder.append: " + cl);
+                }
+            } else if (cl == String.class) {
+                return "(Ljava/lang/String;)Ljava/lang/StringBuilder;";
+            } else {
+                return "(Ljava/lang/Object;)Ljava/lang/StringBuilder;";
+            }
+        }
+
+        private static String getStringValueOfDesc(Class<?> cl) {
+            if (cl.isPrimitive()) {
+                if (cl == Integer.TYPE || cl == Byte.TYPE || cl == Short.TYPE) {
+                    return "(I)Ljava/lang/String;";
+                } else if (cl == Boolean.TYPE) {
+                    return "(Z)Ljava/lang/String;";
+                } else if (cl == Character.TYPE) {
+                    return "(C)Ljava/lang/String;";
+                } else if (cl == Double.TYPE) {
+                    return "(D)Ljava/lang/String;";
+                } else if (cl == Float.TYPE) {
+                    return "(F)Ljava/lang/String;";
+                } else if (cl == Long.TYPE) {
+                    return "(J)Ljava/lang/String;";
+                } else {
+                    throw new IllegalStateException("Unhandled String.valueOf: " + cl);
+                }
+            } else if (cl == String.class) {
+                return "(Ljava/lang/String;)Ljava/lang/String;";
+            } else {
+                return "(Ljava/lang/Object;)Ljava/lang/String;";
+            }
+        }
+
+        /**
+         * The following method is copied from
+         * org.objectweb.asm.commons.InstructionAdapter. Part of ASM: a very small
+         * and fast Java bytecode manipulation framework.
+         * Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved.
+         */
+        private static void iconst(MethodVisitor mv, final int cst) {
+            if (cst >= -1 && cst <= 5) {
+                mv.visitInsn(Opcodes.ICONST_0 + cst);
+            } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
+                mv.visitIntInsn(Opcodes.BIPUSH, cst);
+            } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
+                mv.visitIntInsn(Opcodes.SIPUSH, cst);
+            } else {
+                mv.visitLdcInsn(cst);
+            }
+        }
+
+        private static int getLoadOpcode(Class<?> c) {
+            if (c == Void.TYPE) {
+                throw new InternalError("Unexpected void type of load opcode");
+            }
+            return ILOAD + getOpcodeOffset(c);
+        }
+
+        private static int getOpcodeOffset(Class<?> c) {
+            if (c.isPrimitive()) {
+                if (c == Long.TYPE) {
+                    return 1;
+                } else if (c == Float.TYPE) {
+                    return 2;
+                } else if (c == Double.TYPE) {
+                    return 3;
+                }
+                return 0;
+            } else {
+                return 4;
+            }
+        }
+
+        private static int getParameterSize(Class<?> c) {
+            if (c == Void.TYPE) {
+                return 0;
+            } else if (c == Long.TYPE || c == Double.TYPE) {
+                return 2;
+            }
+            return 1;
+        }
+    }
+
+    /**
+     * MethodHandle StringBuilder strategy.
+     *
+     * <p>This strategy operates in two modes, gated by {@link Mode}.
+     *
+     * <p><b>{@link Strategy#MH_SB_SIZED}: "MethodHandles StringBuilder,
+     * sized".</b>
+     *
+     * <p>This strategy avoids spinning up the bytecode by building the
+     * computation on MethodHandle combinators. The computation is built with
+     * public MethodHandle APIs, resolved from a public Lookup sequence, and
+     * ends up calling the public StringBuilder API. Therefore, this strategy
+     * does not use any private API at all, even the Unsafe.defineAnonymousClass,
+     * since everything is handled under cover by java.lang.invoke APIs.
+     *
+     * <p><b>{@link Strategy#MH_SB_SIZED_EXACT}: "MethodHandles StringBuilder,
+     * sized exactly".</b>
+     *
+     * <p>This strategy improves on @link Strategy#MH_SB_SIZED}, by first
+     * converting all arguments to String in order to get the exact capacity
+     * StringBuilder should have. The conversion is done via the public
+     * String.valueOf and/or Object.toString methods, and does not touch any
+     * private String API.
+     */
+    private static final class MethodHandleStringBuilderStrategy {
+
+        private MethodHandleStringBuilderStrategy() {
+            // no instantiation
+        }
+
+        private static MethodHandle generate(MethodType mt, Recipe recipe, Mode mode) throws Exception {
+            int pc = mt.parameterCount();
+
+            Class<?>[] ptypes = mt.parameterArray();
+            MethodHandle[] filters = new MethodHandle[ptypes.length];
+            for (int i = 0; i < ptypes.length; i++) {
+                MethodHandle filter;
+                switch (mode) {
+                    case SIZED:
+                        // In sized mode, we convert all references and floats/doubles
+                        // to String: there is no specialization for different
+                        // classes in StringBuilder API, and it will convert to
+                        // String internally anyhow.
+                        filter = Stringifiers.forMost(ptypes[i]);
+                        break;
+                    case SIZED_EXACT:
+                        // In exact mode, we convert everything to String:
+                        // this helps to compute the storage exactly.
+                        filter = Stringifiers.forAny(ptypes[i]);
+                        break;
+                    default:
+                        throw new StringConcatException("Not supported");
+                }
+                if (filter != null) {
+                    filters[i] = filter;
+                    ptypes[i] = filter.type().returnType();
+                }
+            }
+
+            List<Class<?>> ptypesList = Arrays.asList(ptypes);
+            MethodHandle[] lengthers = new MethodHandle[pc];
+
+            // Figure out lengths: constants' lengths can be deduced on the spot.
+            // All reference arguments were filtered to String in the combinators below, so we can
+            // call the usual String.length(). Primitive values string sizes can be estimated.
+            int initial = 0;
+            for (RecipeElement el : recipe.getElements()) {
+                switch (el.getTag()) {
+                    case CONST: {
+                        Object cnst = el.getValue();
+                        initial += cnst.toString().length();
+                        break;
+                    }
+                    case ARG: {
+                        final int i = el.getArgPos();
+                        Class<?> type = ptypesList.get(i);
+                        if (type.isPrimitive()) {
+                            MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
+                            est = MethodHandles.dropArguments(est, 0, type);
+                            lengthers[i] = est;
+                        } else {
+                            lengthers[i] = STRING_LENGTH;
+                        }
+                        break;
+                    }
+                    default:
+                        throw new StringConcatException("Unhandled tag: " + el.getTag());
+                }
+            }
+
+            // Create (StringBuilder, <args>) shape for appending:
+            MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, ptypesList);
+
+            // Compose append calls. This is done in reverse because the application order is
+            // reverse as well.
+            for (RecipeElement el : recipe.getElementsReversed()) {
+                MethodHandle appender;
+                switch (el.getTag()) {
+                    case CONST: {
+                        Object constant = el.getValue();
+                        MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
+                        appender = MethodHandles.insertArguments(mh, 1, constant);
+                        break;
+                    }
+                    case ARG: {
+                        int ac = el.getArgPos();
+                        appender = appender(ptypesList.get(ac));
+
+                        // Insert dummy arguments to match the prefix in the signature.
+                        // The actual appender argument will be the ac-ith argument.
+                        if (ac != 0) {
+                            appender = MethodHandles.dropArguments(appender, 1, ptypesList.subList(0, ac));
+                        }
+                        break;
+                    }
+                    default:
+                        throw new StringConcatException("Unhandled tag: " + el.getTag());
+                }
+                builder = MethodHandles.foldArguments(builder, appender);
+            }
+
+            // Build the sub-tree that adds the sizes and produces a StringBuilder:
+
+            // a) Start with the reducer that accepts all arguments, plus one
+            //    slot for the initial value. Inject the initial value right away.
+            //    This produces (<ints>)int shape:
+            MethodHandle sum = getReducerFor(pc + 1);
+            MethodHandle adder = MethodHandles.insertArguments(sum, 0, initial);
+
+            // b) Apply lengthers to transform arguments to lengths, producing (<args>)int
+            adder = MethodHandles.filterArguments(adder, 0, lengthers);
+
+            // c) Instantiate StringBuilder (<args>)int -> (<args>)StringBuilder
+            MethodHandle newBuilder = MethodHandles.filterReturnValue(adder, NEW_STRING_BUILDER);
+
+            // d) Fold in StringBuilder constructor, this produces (<args>)StringBuilder
+            MethodHandle mh = MethodHandles.foldArguments(builder, newBuilder);
+
+            // Convert non-primitive arguments to Strings
+            mh = MethodHandles.filterArguments(mh, 0, filters);
+
+            // Convert (<args>)StringBuilder to (<args>)String
+            if (DEBUG && mode.isExact()) {
+                mh = MethodHandles.filterReturnValue(mh, BUILDER_TO_STRING_CHECKED);
+            } else {
+                mh = MethodHandles.filterReturnValue(mh, BUILDER_TO_STRING);
+            }
+
+            return mh;
+        }
+
+        private static MethodHandle getReducerFor(int cnt) {
+            return SUMMERS.computeIfAbsent(cnt, SUMMER);
+        }
+
+        private static MethodHandle appender(Class<?> appendType) {
+            MethodHandle appender = lookupVirtual(MethodHandles.publicLookup(), StringBuilder.class, "append",
+                    StringBuilder.class, adaptToStringBuilder(appendType));
+
+            // appenders should return void, this would not modify the target signature during folding
+            MethodType nt = MethodType.methodType(void.class, StringBuilder.class, appendType);
+            return appender.asType(nt);
+        }
+
+        private static String toStringChecked(StringBuilder sb) {
+            String s = sb.toString();
+            if (s.length() != sb.capacity()) {
+                throw new AssertionError("Exactness check failed: result length = " + s.length() + ", buffer capacity = " + sb.capacity());
+            }
+            return s;
+        }
+
+        private static int sum(int v1, int v2) {
+            return v1 + v2;
+        }
+
+        private static int sum(int v1, int v2, int v3) {
+            return v1 + v2 + v3;
+        }
+
+        private static int sum(int v1, int v2, int v3, int v4) {
+            return v1 + v2 + v3 + v4;
+        }
+
+        private static int sum(int v1, int v2, int v3, int v4, int v5) {
+            return v1 + v2 + v3 + v4 + v5;
+        }
+
+        private static int sum(int v1, int v2, int v3, int v4, int v5, int v6) {
+            return v1 + v2 + v3 + v4 + v5 + v6;
+        }
+
+        private static int sum(int v1, int v2, int v3, int v4, int v5, int v6, int v7) {
+            return v1 + v2 + v3 + v4 + v5 + v6 + v7;
+        }
+
+        private static int sum(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8) {
+            return v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
+        }
+
+        private static int sum(int initial, int[] vs) {
+            int sum = initial;
+            for (int v : vs) {
+                sum += v;
+            }
+            return sum;
+        }
+
+        private static final ConcurrentMap<Integer, MethodHandle> SUMMERS;
+
+        // This one is deliberately non-lambdified to optimize startup time:
+        private static final Function<Integer, MethodHandle> SUMMER = new Function<Integer, MethodHandle>() {
+            @Override
+            public MethodHandle apply(Integer cnt) {
+                if (cnt == 1) {
+                    return MethodHandles.identity(int.class);
+                } else if (cnt <= 8) {
+                    // Variable-arity collectors are not as efficient as small-count methods,
+                    // unroll some initial sizes.
+                    Class<?>[] cls = new Class<?>[cnt];
+                    Arrays.fill(cls, int.class);
+                    return lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleStringBuilderStrategy.class, "sum", int.class, cls);
+                } else {
+                    return lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleStringBuilderStrategy.class, "sum", int.class, int.class, int[].class)
+                            .asCollector(int[].class, cnt - 1);
+                }
+            }
+        };
+
+        private static final MethodHandle NEW_STRING_BUILDER, STRING_LENGTH, BUILDER_TO_STRING, BUILDER_TO_STRING_CHECKED;
+
+        static {
+            SUMMERS = new ConcurrentHashMap<>();
+            Lookup publicLookup = MethodHandles.publicLookup();
+            NEW_STRING_BUILDER = lookupConstructor(publicLookup, StringBuilder.class, int.class);
+            STRING_LENGTH = lookupVirtual(publicLookup, String.class, "length", int.class);
+            BUILDER_TO_STRING = lookupVirtual(publicLookup, StringBuilder.class, "toString", String.class);
+            if (DEBUG) {
+                BUILDER_TO_STRING_CHECKED = lookupStatic(MethodHandles.Lookup.IMPL_LOOKUP,
+                        MethodHandleStringBuilderStrategy.class, "toStringChecked", String.class, StringBuilder.class);
+            } else {
+                BUILDER_TO_STRING_CHECKED = null;
+            }
+        }
+
+    }
+
+
+    /**
+     * <p><b>{@link Strategy#MH_INLINE_SIZED_EXACT}: "MethodHandles inline,
+     * sized exactly".</b>
+     *
+     * <p>This strategy replicates what StringBuilders are doing: it builds the
+     * byte[] array on its own and passes that byte[] array to String
+     * constructor. This strategy requires access to some private APIs in JDK,
+     * most notably, the read-only Integer/Long.stringSize methods that measure
+     * the character length of the integers, and the private String constructor
+     * that accepts byte[] arrays without copying. While this strategy assumes a
+     * particular implementation details for String, this opens the door for
+     * building a very optimal concatenation sequence. This is the only strategy
+     * that requires porting if there are private JDK changes occur.
+     */
+    private static final class MethodHandleInlineCopyStrategy {
+
+        private MethodHandleInlineCopyStrategy() {
+            // no instantiation
+        }
+
+        static MethodHandle generate(MethodType mt, Recipe recipe) throws Throwable {
+
+            // Create filters and obtain filtered parameter types. Filters would be used in the beginning
+            // to convert the incoming arguments into the arguments we can process (e.g. Objects -> Strings).
+            // The filtered argument type list is used all over in the combinators below.
+            Class<?>[] ptypes = mt.parameterArray();
+            MethodHandle[] filters = null;
+            for (int i = 0; i < ptypes.length; i++) {
+                MethodHandle filter = Stringifiers.forMost(ptypes[i]);
+                if (filter != null) {
+                    if (filters == null) {
+                        filters = new MethodHandle[ptypes.length];
+                    }
+                    filters[i] = filter;
+                    ptypes[i] = filter.type().returnType();
+                }
+            }
+            List<Class<?>> ptypesList = Arrays.asList(ptypes);
+
+            // Start building the combinator tree. The tree "starts" with (<parameters>)String, and "finishes"
+            // with the (int, byte[], byte)String in String helper. The combinators are assembled bottom-up,
+            // which makes the code arguably hard to read.
+
+            // Drop all remaining parameter types, leave only helper arguments:
+            MethodHandle mh;
+
+            mh = MethodHandles.dropArguments(NEW_STRING, 2, ptypes);
+            mh = MethodHandles.dropArguments(mh, 0, int.class);
+
+            // In debug mode, check that remaining index is zero.
+            if (DEBUG) {
+                mh = MethodHandles.filterArgument(mh, 0, CHECK_INDEX);
+            }
+
+            // Mix in prependers. This happens when (int, byte[], byte) = (index, storage, coder) is already
+            // known from the combinators below. We are assembling the string backwards, so "index" is the
+            // *ending* index.
+            for (RecipeElement el : recipe.getElements()) {
+                MethodHandle prepender;
+                switch (el.getTag()) {
+                    case CONST: {
+                        Object cnst = el.getValue();
+                        prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
+                        break;
+                    }
+                    case ARG: {
+                        int pos = el.getArgPos();
+                        prepender = selectArgument(prepender(ptypesList.get(pos)), 3, ptypesList, pos);
+                        break;
+                    }
+                    default:
+                        throw new StringConcatException("Unhandled tag: " + el.getTag());
+                }
+
+                // Remove "old" index from arguments
+                mh = MethodHandles.dropArguments(mh, 1, int.class);
+
+                // Do the prepend, and put "new" index at index 0
+                mh = MethodHandles.foldArguments(mh, prepender);
+            }
+
+            // Prepare the argument list for prepending. The tree below would instantiate
+            // the storage byte[] into argument 0, so we need to swap "storage" and "index".
+            // The index at this point equals to "size", and resides at argument 1.
+            {
+                MethodType nmt = mh.type()
+                        .changeParameterType(0, byte[].class)
+                        .changeParameterType(1, int.class);
+                mh = MethodHandles.permuteArguments(mh, nmt, swap10(nmt.parameterCount()));
+            }
+
+            // Fold in byte[] instantiation at argument 0.
+            MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypesList);
+            mh = MethodHandles.foldArguments(mh, combiner);
+
+            // Start combining length and coder mixers.
+            //
+            // Length is easy: constant lengths can be computed on the spot, and all non-constant
+            // shapes have been either converted to Strings, or explicit methods for getting the
+            // string length out of primitives are provided.
+            //
+            // Coders are more interesting. Only Object, String and char arguments (and constants)
+            // can have non-Latin1 encoding. It is easier to blindly convert constants to String,
+            // and deduce the coder from there. Arguments would be either converted to Strings
+            // during the initial filtering, or handled by primitive specializations in CODER_MIXERS.
+            //
+            // The method handle shape after all length and coder mixers is:
+            //   (int, byte, <args>)String = ("index", "coder", <args>)
+            byte initialCoder = 0; // initial coder
+            int initialLen = 0;    // initial length, in characters
+            for (RecipeElement el : recipe.getElements()) {
+                switch (el.getTag()) {
+                    case CONST: {
+                        Object constant = el.getValue();
+                        String s = constant.toString();
+                        initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
+                        initialLen += s.length();
+                        break;
+                    }
+                    case ARG: {
+                        int ac = el.getArgPos();
+
+                        Class<?> argClass = ptypesList.get(ac);
+                        MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypesList, ac);
+                        lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
+                        lm = MethodHandles.dropArguments(lm, 2, byte.class);
+
+                        MethodHandle cm = selectArgument(coderMixer(argClass),  1, ptypesList, ac);
+                        cm = MethodHandles.dropArguments(cm, 0, int.class);  // (**)
+
+                        // Read this bottom up:
+
+                        // 4. Drop old index and coder, producing ("new-index", "new-coder", <args>)
+                        mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
+
+                        // 3. Compute "new-index", producing ("new-index", "new-coder", "old-index", "old-coder", <args>)
+                        //    Length mixer ignores both "new-coder" and "old-coder" due to dropArguments above (*)
+                        mh = MethodHandles.foldArguments(mh, lm);
+
+                        // 2. Compute "new-coder", producing ("new-coder", "old-index", "old-coder", <args>)
+                        //    Coder mixer ignores the "old-index" arg due to dropArguments above (**)
+                        mh = MethodHandles.foldArguments(mh, cm);
+
+                        // 1. The mh shape here is ("old-index", "old-coder", <args>)
+                        break;
+                    }
+                    default:
+                        throw new StringConcatException("Unhandled tag: " + el.getTag());
+                }
+            }
+
+            // Insert initial lengths and coders here.
+            // The method handle shape here is (<args>).
+            mh = MethodHandles.insertArguments(mh, 0, initialLen, initialCoder);
+
+            // Apply filters, converting the arguments:
+            if (filters != null) {
+                mh = MethodHandles.filterArguments(mh, 0, filters);
+            }
+
+            return mh;
+        }
+
+        private static int[] swap10(int count) {
+            int[] perm = new int[count];
+            perm[0] = 1;
+            perm[1] = 0;
+            for (int i = 2; i < count; i++) {
+                perm[i] = i;
+            }
+            return perm;
+        }
+
+        // Adapts: (...prefix..., parameter[pos])R -> (...prefix..., ...parameters...)R
+        private static MethodHandle selectArgument(MethodHandle mh, int prefix, List<Class<?>> ptypes, int pos) {
+            if (pos == 0) {
+                return MethodHandles.dropArguments(mh, prefix + 1, ptypes.subList(1, ptypes.size()));
+            } else if (pos == ptypes.size() - 1) {
+                return MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, ptypes.size() - 1));
+            } else { // 0 < pos < ptypes.size() - 1
+                MethodHandle t = MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, pos));
+                return MethodHandles.dropArguments(t, prefix + 1 + pos, ptypes.subList(pos + 1, ptypes.size()));
+            }
+        }
+
+        @ForceInline
+        private static byte[] newArray(int length, byte coder) {
+            return new byte[length << coder];
+        }
+
+        @ForceInline
+        private static int checkIndex(int index) {
+            if (index != 0) {
+                throw new AssertionError("Exactness check failed: " + index + " characters left in the buffer.");
+            }
+            return index;
+        }
+
+        private static MethodHandle prepender(Class<?> cl) {
+            return PREPENDERS.computeIfAbsent(cl, PREPEND);
+        }
+
+        private static MethodHandle coderMixer(Class<?> cl) {
+            return CODER_MIXERS.computeIfAbsent(cl, CODER_MIX);
+        }
+
+        private static MethodHandle lengthMixer(Class<?> cl) {
+            return LENGTH_MIXERS.computeIfAbsent(cl, LENGTH_MIX);
+        }
+
+        // This one is deliberately non-lambdified to optimize startup time:
+        private static final Function<Class<?>, MethodHandle> PREPEND = new Function<Class<?>, MethodHandle>() {
+            @Override
+            public MethodHandle apply(Class<?> c) {
+                return lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "prepend", int.class, int.class, byte[].class, byte.class, c);
+            }
+        };
+
+        // This one is deliberately non-lambdified to optimize startup time:
+        private static final Function<Class<?>, MethodHandle> CODER_MIX = new Function<Class<?>, MethodHandle>() {
+            @Override
+            public MethodHandle apply(Class<?> c) {
+                return lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "mixCoder", byte.class, byte.class, c);
+            }
+        };
+
+        // This one is deliberately non-lambdified to optimize startup time:
+        private static final Function<Class<?>, MethodHandle> LENGTH_MIX = new Function<Class<?>, MethodHandle>() {
+            @Override
+            public MethodHandle apply(Class<?> c) {
+                return lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "mixLen", int.class, int.class, c);
+            }
+        };
+
+        private static final MethodHandle NEW_STRING;
+        private static final MethodHandle CHECK_INDEX;
+        private static final MethodHandle NEW_ARRAY;
+        private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS;
+        private static final ConcurrentMap<Class<?>, MethodHandle> LENGTH_MIXERS;
+        private static final ConcurrentMap<Class<?>, MethodHandle> CODER_MIXERS;
+        private static final Class<?> STRING_HELPER;
+
+        static {
+            try {
+                STRING_HELPER = Class.forName("java.lang.StringConcatHelper");
+            } catch (ClassNotFoundException e) {
+                throw new AssertionError(e);
+            }
+
+            PREPENDERS = new ConcurrentHashMap<>();
+            LENGTH_MIXERS = new ConcurrentHashMap<>();
+            CODER_MIXERS = new ConcurrentHashMap<>();
+
+            NEW_STRING = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newString", String.class, byte[].class, byte.class);
+            NEW_ARRAY  = lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleInlineCopyStrategy.class, "newArray", byte[].class, int.class, byte.class);
+
+            if (DEBUG) {
+                CHECK_INDEX = lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleInlineCopyStrategy.class, "checkIndex", int.class, int.class);
+            } else {
+                CHECK_INDEX = null;
+            }
+        }
+    }
+
+    /**
+     * Public gateways to public "stringify" methods. These methods have the form String apply(T obj), and normally
+     * delegate to {@code String.valueOf}, depending on argument's type.
+     */
+    private static final class Stringifiers {
+        private Stringifiers() {
+            // no instantiation
+        }
+
+        // This one is deliberately non-lambdified to optimize startup time:
+        private static final Function<Class<?>, MethodHandle> MOST = new Function<Class<?>, MethodHandle>() {
+            @Override
+            public MethodHandle apply(Class<?> cl) {
+                MethodHandle mhObject = lookupStatic(Lookup.PUBLIC_LOOKUP, String.class, "valueOf", String.class, Object.class);
+
+                // We need the additional conversion here, because String.valueOf(Object) may return null.
+                // String conversion rules in Java state we need to produce "null" String in this case.
+                // It can be easily done with applying valueOf the second time.
+                MethodHandle mhObjectNoNulls = MethodHandles.filterReturnValue(mhObject,
+                        mhObject.asType(MethodType.methodType(String.class, String.class)));
+
+                if (cl == String.class) {
+                    return mhObject;
+                } else if (cl == float.class) {
+                    return lookupStatic(Lookup.PUBLIC_LOOKUP, String.class, "valueOf", String.class, float.class);
+                } else if (cl == double.class) {
+                    return lookupStatic(Lookup.PUBLIC_LOOKUP, String.class, "valueOf", String.class, double.class);
+                } else if (!cl.isPrimitive()) {
+                    return mhObjectNoNulls;
+                }
+
+                return null;
+            }
+        };
+
+        // This one is deliberately non-lambdified to optimize startup time:
+        private static final Function<Class<?>, MethodHandle> ANY = new Function<Class<?>, MethodHandle>() {
+            @Override
+            public MethodHandle apply(Class<?> cl) {
+                MethodHandle mh = MOST.apply(cl);
+                if (mh != null) {
+                    return mh;
+                }
+
+                if (cl == byte.class || cl == short.class || cl == int.class) {
+                    return lookupStatic(Lookup.PUBLIC_LOOKUP, String.class, "valueOf", String.class, int.class);
+                } else if (cl == boolean.class) {
+                    return lookupStatic(Lookup.PUBLIC_LOOKUP, String.class, "valueOf", String.class, boolean.class);
+                } else if (cl == char.class) {
+                    return lookupStatic(Lookup.PUBLIC_LOOKUP, String.class, "valueOf", String.class, char.class);
+                } else if (cl == long.class) {
+                    return lookupStatic(Lookup.PUBLIC_LOOKUP, String.class, "valueOf", String.class, long.class);
+                } else {
+                    throw new IllegalStateException("Unknown class: " + cl);
+                }
+            }
+        };
+
+        private static final ConcurrentMap<Class<?>, MethodHandle> STRINGIFIERS_MOST = new ConcurrentHashMap<>();
+        private static final ConcurrentMap<Class<?>, MethodHandle> STRINGIFIERS_ANY = new ConcurrentHashMap<>();
+
+        /**
+         * Returns a stringifier for references and floats/doubles only.
+         * Always returns null for other primitives.
+         *
+         * @param t class to stringify
+         * @return stringifier; null, if not available
+         */
+        static MethodHandle forMost(Class<?> t) {
+            return STRINGIFIERS_MOST.computeIfAbsent(t, MOST);
+        }
+
+        /**
+         * Returns a stringifier for any type. Never returns null.
+         *
+         * @param t class to stringify
+         * @return stringifier
+         */
+        static MethodHandle forAny(Class<?> t) {
+            return STRINGIFIERS_ANY.computeIfAbsent(t, ANY);
+        }
+    }
+
+    /* ------------------------------- Common utilities ------------------------------------ */
+
+    private static MethodHandle lookupStatic(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
+        try {
+            return lookup.findStatic(refc, name, MethodType.methodType(rtype, ptypes));
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    private static MethodHandle lookupVirtual(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
+        try {
+            return lookup.findVirtual(refc, name, MethodType.methodType(rtype, ptypes));
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    private static MethodHandle lookupConstructor(Lookup lookup, Class<?> refc, Class<?> ptypes) {
+        try {
+            return lookup.findConstructor(refc, MethodType.methodType(void.class, ptypes));
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    private static int estimateSize(Class<?> cl) {
+        if (cl == Integer.TYPE) {
+            return 11; // "-2147483648"
+        } else if (cl == Boolean.TYPE) {
+            return 5; // "false"
+        } else if (cl == Byte.TYPE) {
+            return 4; // "-128"
+        } else if (cl == Character.TYPE) {
+            return 1; // duh
+        } else if (cl == Short.TYPE) {
+            return 6; // "-32768"
+        } else if (cl == Double.TYPE) {
+            return 26; // apparently, no larger than this, see FloatingDecimal.BinaryToASCIIBuffer.buffer
+        } else if (cl == Float.TYPE) {
+            return 26; // apparently, no larger than this, see FloatingDecimal.BinaryToASCIIBuffer.buffer
+        } else if (cl == Long.TYPE)  {
+            return 20; // "-9223372036854775808"
+        } else {
+            throw new IllegalArgumentException("Cannot estimate the size for " + cl);
+        }
+    }
+
+    private static Class<?> adaptToStringBuilder(Class<?> c) {
+        if (c.isPrimitive()) {
+            if (c == Byte.TYPE || c == Short.TYPE) {
+                return int.class;
+            }
+        } else {
+            if (c != String.class) {
+                return Object.class;
+            }
+        }
+        return c;
+    }
+
+    private StringConcatFactory() {
+        // no instantiation
+    }
+
+}
--- a/jdk/src/java.base/share/classes/java/net/URL.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/net/URL.java	Thu Jan 28 15:43:15 2016 -0800
@@ -36,6 +36,7 @@
 import java.io.ObjectStreamField;
 import java.io.ObjectInputStream.GetField;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.NoSuchElementException;
 import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
@@ -405,7 +406,7 @@
             }
         }
 
-        protocol = protocol.toLowerCase();
+        protocol = protocol.toLowerCase(Locale.ROOT);
         this.protocol = protocol;
         if (host != null) {
 
@@ -579,8 +580,7 @@
             for (i = start ; !aRef && (i < limit) &&
                      ((c = spec.charAt(i)) != '/') ; i++) {
                 if (c == ':') {
-
-                    String s = spec.substring(start, i).toLowerCase();
+                    String s = spec.substring(start, i).toLowerCase(Locale.ROOT);
                     if (isValidProtocol(s)) {
                         newProtocol = s;
                         start = i + 1;
--- a/jdk/src/java.base/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/nio/file/attribute/FileOwnerAttributeView.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, 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
@@ -59,7 +59,7 @@
     /**
      * Read the file owner.
      *
-     * <p> It it implementation specific if the file owner can be a {@link
+     * <p> It is implementation specific if the file owner can be a {@link
      * GroupPrincipal group}.
      *
      * @return  the file owner
@@ -78,7 +78,7 @@
     /**
      * Updates the file owner.
      *
-     * <p> It it implementation specific if the file owner can be a {@link
+     * <p> It is implementation specific if the file owner can be a {@link
      * GroupPrincipal group}. To ensure consistent and correct behavior
      * across platforms it is recommended that this method should only be used
      * to set the file owner to a user principal that is not a group.
--- a/jdk/src/java.base/share/classes/java/util/Vector.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Vector.java	Thu Jan 28 15:43:15 2016 -0800
@@ -233,42 +233,56 @@
     public synchronized void ensureCapacity(int minCapacity) {
         if (minCapacity > 0) {
             modCount++;
-            ensureCapacityHelper(minCapacity);
+            if (minCapacity > elementData.length)
+                grow(minCapacity);
         }
     }
 
     /**
-     * This implements the unsynchronized semantics of ensureCapacity.
-     * Synchronized methods in this class can internally call this
-     * method for ensuring capacity without incurring the cost of an
-     * extra synchronization.
-     *
-     * @see #ensureCapacity(int)
-     */
-    private void ensureCapacityHelper(int minCapacity) {
-        // overflow-conscious code
-        if (minCapacity - elementData.length > 0)
-            grow(minCapacity);
-    }
-
-    /**
-     * The maximum size of array to allocate.
+     * The maximum size of array to allocate (unless necessary).
      * Some VMs reserve some header words in an array.
      * Attempts to allocate larger arrays may result in
      * OutOfMemoryError: Requested array size exceeds VM limit
      */
     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
 
-    private void grow(int minCapacity) {
+    /**
+     * Increases the capacity to ensure that it can hold at least the
+     * number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity the desired minimum capacity
+     * @throws OutOfMemoryError if minCapacity is less than zero
+     */
+    private Object[] grow(int minCapacity) {
+        return elementData = Arrays.copyOf(elementData,
+                                           newCapacity(minCapacity));
+    }
+
+    private Object[] grow() {
+        return grow(elementCount + 1);
+    }
+
+    /**
+     * Returns a capacity at least as large as the given minimum capacity.
+     * Will not return a capacity greater than MAX_ARRAY_SIZE unless
+     * the given minimum capacity is greater than MAX_ARRAY_SIZE.
+     *
+     * @param minCapacity the desired minimum capacity
+     * @throws OutOfMemoryError if minCapacity is less than zero
+     */
+    private int newCapacity(int minCapacity) {
         // overflow-conscious code
         int oldCapacity = elementData.length;
         int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                          capacityIncrement : oldCapacity);
-        if (newCapacity - minCapacity < 0)
-            newCapacity = minCapacity;
-        if (newCapacity - MAX_ARRAY_SIZE > 0)
-            newCapacity = hugeCapacity(minCapacity);
-        elementData = Arrays.copyOf(elementData, newCapacity);
+        if (newCapacity - minCapacity <= 0) {
+            if (minCapacity < 0) // overflow
+                throw new OutOfMemoryError();
+            return minCapacity;
+        }
+        return (newCapacity - MAX_ARRAY_SIZE <= 0)
+            ? newCapacity
+            : hugeCapacity(minCapacity);
     }
 
     private static int hugeCapacity(int minCapacity) {
@@ -290,13 +304,10 @@
      */
     public synchronized void setSize(int newSize) {
         modCount++;
-        if (newSize > elementCount) {
-            ensureCapacityHelper(newSize);
-        } else {
-            for (int i = newSize ; i < elementCount ; i++) {
-                elementData[i] = null;
-            }
-        }
+        if (newSize > elementData.length)
+            grow(newSize);
+        for (int i = newSize; i < elementCount; i++)
+            elementData[i] = null;
         elementCount = newSize;
     }
 
@@ -604,11 +615,16 @@
             throw new ArrayIndexOutOfBoundsException(index
                                                      + " > " + elementCount);
         }
-        ensureCapacityHelper(elementCount + 1);
-        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
+        modCount++;
+        final int s = elementCount;
+        Object[] elementData = this.elementData;
+        if (s == elementData.length)
+            elementData = grow();
+        System.arraycopy(elementData, index,
+                         elementData, index + 1,
+                         s - index);
         elementData[index] = obj;
-        modCount++;
-        elementCount++;
+        elementCount = s + 1;
     }
 
     /**
@@ -623,9 +639,8 @@
      * @param   obj   the component to be added
      */
     public synchronized void addElement(E obj) {
-        ensureCapacityHelper(elementCount + 1);
         modCount++;
-        elementData[elementCount++] = obj;
+        add(obj, elementData, elementCount);
     }
 
     /**
@@ -781,6 +796,18 @@
     }
 
     /**
+     * This helper method split out from add(E) to keep method
+     * bytecode size under 35 (the -XX:MaxInlineSize default value),
+     * which helps when add(E) is called in a C1-compiled loop.
+     */
+    private void add(E e, Object[] elementData, int s) {
+        if (s == elementData.length)
+            elementData = grow();
+        elementData[s] = e;
+        elementCount = s + 1;
+    }
+
+    /**
      * Appends the specified element to the end of this Vector.
      *
      * @param e element to be appended to this Vector
@@ -788,9 +815,8 @@
      * @since 1.2
      */
     public synchronized boolean add(E e) {
-        ensureCapacityHelper(elementCount + 1);
         modCount++;
-        elementData[elementCount++] = e;
+        add(e, elementData, elementCount);
         return true;
     }
 
@@ -891,16 +917,19 @@
      */
     public boolean addAll(Collection<? extends E> c) {
         Object[] a = c.toArray();
+        modCount++;
         int numNew = a.length;
-        if (numNew > 0) {
-            synchronized (this) {
-                ensureCapacityHelper(elementCount + numNew);
-                System.arraycopy(a, 0, elementData, elementCount, numNew);
-                modCount++;
-                elementCount += numNew;
-            }
+        if (numNew == 0)
+            return false;
+        synchronized (this) {
+            Object[] elementData = this.elementData;
+            final int s = elementCount;
+            if (numNew > elementData.length - s)
+                elementData = grow(s + numNew);
+            System.arraycopy(a, 0, elementData, s, numNew);
+            elementCount = s + numNew;
+            return true;
         }
-        return numNew > 0;
     }
 
     /**
@@ -969,21 +998,23 @@
             throw new ArrayIndexOutOfBoundsException(index);
 
         Object[] a = c.toArray();
+        modCount++;
         int numNew = a.length;
-
-        if (numNew > 0) {
-            ensureCapacityHelper(elementCount + numNew);
+        if (numNew == 0)
+            return false;
+        Object[] elementData = this.elementData;
+        final int s = elementCount;
+        if (numNew > elementData.length - s)
+            elementData = grow(s + numNew);
 
-            int numMoved = elementCount - index;
-            if (numMoved > 0)
-                System.arraycopy(elementData, index, elementData,
-                        index + numNew, numMoved);
-
-             System.arraycopy(a, 0, elementData, index, numNew);
-             elementCount += numNew;
-             modCount++;
-        }
-        return numNew > 0;
+        int numMoved = s - index;
+        if (numMoved > 0)
+            System.arraycopy(elementData, index,
+                             elementData, index + numNew,
+                             numMoved);
+        System.arraycopy(a, 0, elementData, index, numNew);
+        elementCount = s + numNew;
+        return true;
     }
 
     /**
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -44,6 +44,9 @@
     // The number of temp buffers in our pool
     private static final int TEMP_BUF_POOL_SIZE = IOUtil.IOV_MAX;
 
+    // The max size allowed for a cached temp buffer, in bytes
+    private static final long MAX_CACHED_BUFFER_SIZE = getMaxCachedBufferSize();
+
     // Per-thread cache of temporary direct buffers
     private static ThreadLocal<BufferCache> bufferCache =
         new ThreadLocal<BufferCache>()
@@ -55,6 +58,52 @@
     };
 
     /**
+     * Returns the max size allowed for a cached temp buffers, in
+     * bytes. It defaults to Long.MAX_VALUE. It can be set with the
+     * jdk.nio.maxCachedBufferSize property. Even though
+     * ByteBuffer.capacity() returns an int, we're using a long here
+     * for potential future-proofing.
+     */
+    private static long getMaxCachedBufferSize() {
+        String s = java.security.AccessController.doPrivileged(
+            new PrivilegedAction<String>() {
+                @Override
+                public String run() {
+                    return System.getProperty("jdk.nio.maxCachedBufferSize");
+                }
+            });
+        if (s != null) {
+            try {
+                long m = Long.parseLong(s);
+                if (m >= 0) {
+                    return m;
+                } else {
+                    // if it's negative, ignore the system property
+                }
+            } catch (NumberFormatException e) {
+                // if the string is not well formed, ignore the system property
+            }
+        }
+        return Long.MAX_VALUE;
+    }
+
+    /**
+     * Returns true if a buffer of this size is too large to be
+     * added to the buffer cache, false otherwise.
+     */
+    private static boolean isBufferTooLarge(int size) {
+        return size > MAX_CACHED_BUFFER_SIZE;
+    }
+
+    /**
+     * Returns true if the buffer is too large to be added to the
+     * buffer cache, false otherwise.
+     */
+    private static boolean isBufferTooLarge(ByteBuffer buf) {
+        return isBufferTooLarge(buf.capacity());
+    }
+
+    /**
      * A simple cache of direct buffers.
      */
     private static class BufferCache {
@@ -80,6 +129,9 @@
          * size (or null if no suitable buffer is found).
          */
         ByteBuffer get(int size) {
+            // Don't call this if the buffer would be too large.
+            assert !isBufferTooLarge(size);
+
             if (count == 0)
                 return null;  // cache is empty
 
@@ -117,6 +169,9 @@
         }
 
         boolean offerFirst(ByteBuffer buf) {
+            // Don't call this if the buffer is too large.
+            assert !isBufferTooLarge(buf);
+
             if (count >= TEMP_BUF_POOL_SIZE) {
                 return false;
             } else {
@@ -128,6 +183,9 @@
         }
 
         boolean offerLast(ByteBuffer buf) {
+            // Don't call this if the buffer is too large.
+            assert !isBufferTooLarge(buf);
+
             if (count >= TEMP_BUF_POOL_SIZE) {
                 return false;
             } else {
@@ -156,6 +214,15 @@
      * Returns a temporary buffer of at least the given size
      */
     public static ByteBuffer getTemporaryDirectBuffer(int size) {
+        // If a buffer of this size is too large for the cache, there
+        // should not be a buffer in the cache that is at least as
+        // large. So we'll just create a new one. Also, we don't have
+        // to remove the buffer from the cache (as this method does
+        // below) given that we won't put the new buffer in the cache.
+        if (isBufferTooLarge(size)) {
+            return ByteBuffer.allocateDirect(size);
+        }
+
         BufferCache cache = bufferCache.get();
         ByteBuffer buf = cache.get(size);
         if (buf != null) {
@@ -185,6 +252,13 @@
      * likely to be returned by a subsequent call to getTemporaryDirectBuffer.
      */
     static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) {
+        // If the buffer is too large for the cache we don't have to
+        // check the cache. We'll just free it.
+        if (isBufferTooLarge(buf)) {
+            free(buf);
+            return;
+        }
+
         assert buf != null;
         BufferCache cache = bufferCache.get();
         if (!cache.offerFirst(buf)) {
@@ -200,6 +274,13 @@
      * cache in same order that they were obtained.
      */
     static void offerLastTemporaryDirectBuffer(ByteBuffer buf) {
+        // If the buffer is too large for the cache we don't have to
+        // check the cache. We'll just free it.
+        if (isBufferTooLarge(buf)) {
+            free(buf);
+            return;
+        }
+
         assert buf != null;
         BufferCache cache = bufferCache.get();
         if (!cache.offerLast(buf)) {
--- a/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java	Thu Jan 28 15:43:15 2016 -0800
@@ -59,7 +59,11 @@
         AccessController.doPrivileged(new PrivilegedAction<>() {
             @Override
             public Object run() {
-                Thread thr = new Thread(null, thisRunnable, "FileSystemWatchService", 0, false);
+                Thread thr = new Thread(null,
+                                        thisRunnable,
+                                        "FileSystemWatchService",
+                                        0,
+                                        false);
                 thr.setDaemon(true);
                 thr.start();
                 return null;
@@ -216,11 +220,11 @@
                 throw new ClosedWatchServiceException();
             }
             requestList.add(req);
+
+            // wakeup thread
+            wakeup();
         }
 
-        // wakeup thread
-        wakeup();
-
         // wait for result
         Object result = req.awaitResult();
 
@@ -244,6 +248,7 @@
                 // if in process of shutdown then reject request
                 if (shutdown) {
                     req.release(new ClosedWatchServiceException());
+                    continue;
                 }
 
                 switch (req.type()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/jdk/internal/joptsimple/AbstractOptionSpec.java	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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	Thu Jan 28 15:43:15 2016 -0800
@@ -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();
+    }
+}
--- a/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java	Thu Jan 28 15:43:15 2016 -0800
@@ -65,8 +65,11 @@
  *
  * @see java.security.Policy
  * @since   1.2
+ * @deprecated The policytool tool has been deprecated and
+ * is planned to be removed in a future release.
  */
 
+@Deprecated
 public class PolicyTool {
 
     // for i18n
@@ -738,6 +741,8 @@
      * run the PolicyTool
      */
     public static void main(String args[]) {
+        System.out.println("Note: The policytool tool has been deprecated and" +
+                " is planned to be removed in a future release.\n");
         parseArgs(args);
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
@@ -873,6 +878,7 @@
  * The Permission contains the (Type, Name, Action) triplet.
  *
  */
+@SuppressWarnings("deprecation")
 class PolicyEntry {
 
     private CodeSource codesource;
@@ -1012,6 +1018,7 @@
 /**
  * The main window for the PolicyTool
  */
+@SuppressWarnings("deprecation")
 class ToolWindow extends JFrame {
     // use serialVersionUID from JDK 1.2.2 for interoperability
     private static final long serialVersionUID = 5682568601210376777L;
@@ -1549,6 +1556,7 @@
 /**
  * General dialog window
  */
+@SuppressWarnings("deprecation")
 class ToolDialog extends JDialog {
     // use serialVersionUID from JDK 1.2.2 for interoperability
     private static final long serialVersionUID = -372244357011301190L;
@@ -2912,6 +2920,7 @@
 /**
  * Event handler for the PolicyTool window
  */
+@SuppressWarnings("deprecation")
 class ToolWindowListener implements WindowListener {
 
     private PolicyTool tool;
@@ -2956,6 +2965,7 @@
 /**
  * Event handler for the Policy List
  */
+@SuppressWarnings("deprecation")
 class PolicyListListener extends MouseAdapter implements ActionListener {
 
     private PolicyTool tool;
@@ -2985,6 +2995,7 @@
 /**
  * Event handler for the File Menu
  */
+@SuppressWarnings("deprecation")
 class FileMenuListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3083,6 +3094,7 @@
 /**
  * Event handler for the main window buttons and Edit Menu
  */
+@SuppressWarnings("deprecation")
 class MainWindowListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3158,6 +3170,7 @@
  *    if edit is FALSE, then we are ADDing a new PolicyEntry,
  *    so we only need to update the GUI listing.
  */
+@SuppressWarnings("deprecation")
 class AddEntryDoneButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3224,6 +3237,7 @@
 /**
  * Event handler for ChangeKeyStoreOKButton button
  */
+@SuppressWarnings("deprecation")
 class ChangeKeyStoreOKButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3270,6 +3284,7 @@
 /**
  * Event handler for AddPrinButton button
  */
+@SuppressWarnings("deprecation")
 class AddPrinButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3295,6 +3310,7 @@
 /**
  * Event handler for AddPermButton button
  */
+@SuppressWarnings("deprecation")
 class AddPermButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3320,6 +3336,7 @@
 /**
  * Event handler for AddPrinOKButton button
  */
+@SuppressWarnings("deprecation")
 class NewPolicyPrinOKButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3383,6 +3400,7 @@
 /**
  * Event handler for AddPermOKButton button
  */
+@SuppressWarnings("deprecation")
 class NewPolicyPermOKButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3446,6 +3464,7 @@
 /**
  * Event handler for RemovePrinButton button
  */
+@SuppressWarnings("deprecation")
 class RemovePrinButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3481,6 +3500,7 @@
 /**
  * Event handler for RemovePermButton button
  */
+@SuppressWarnings("deprecation")
 class RemovePermButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3523,6 +3543,7 @@
  * GUI listing.  If the user is editing an existing PolicyEntry, we
  * update both the GUI listing and the actual PolicyEntry.
  */
+@SuppressWarnings("deprecation")
 class EditPrinButtonListener extends MouseAdapter implements ActionListener {
 
     private PolicyTool tool;
@@ -3569,6 +3590,7 @@
  * GUI listing.  If the user is editing an existing PolicyEntry, we
  * update both the GUI listing and the actual PolicyEntry.
  */
+@SuppressWarnings("deprecation")
 class EditPermButtonListener extends MouseAdapter implements ActionListener {
 
     private PolicyTool tool;
@@ -3609,6 +3631,7 @@
 /**
  * Event handler for Principal Popup Menu
  */
+@SuppressWarnings("deprecation")
 class PrincipalTypeMenuListener implements ItemListener {
 
     private ToolDialog td;
@@ -3660,6 +3683,7 @@
 /**
  * Event handler for Permission Popup Menu
  */
+@SuppressWarnings("deprecation")
 class PermissionMenuListener implements ItemListener {
 
     private ToolDialog td;
@@ -3734,6 +3758,7 @@
 /**
  * Event handler for Permission Name Popup Menu
  */
+@SuppressWarnings("deprecation")
 class PermissionNameMenuListener implements ItemListener {
 
     private ToolDialog td;
@@ -3887,6 +3912,7 @@
 /**
  * Event handler for UserSaveYes button
  */
+@SuppressWarnings("deprecation")
 class UserSaveYesButtonListener implements ActionListener {
 
     private ToolDialog us;
@@ -3941,6 +3967,7 @@
 /**
  * Event handler for UserSaveNoButton
  */
+@SuppressWarnings("deprecation")
 class UserSaveNoButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3989,6 +4016,7 @@
 /**
  * Event handler for ConfirmRemovePolicyEntryOKButtonListener
  */
+@SuppressWarnings("deprecation")
 class ConfirmRemovePolicyEntryOKButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -4144,6 +4172,7 @@
     }
 }
 
+@SuppressWarnings("deprecation")
 class AuthPerm extends Perm {
     AuthPerm() {
         super(javax.security.auth.AuthPermission.class,
@@ -4216,6 +4245,7 @@
     }
 }
 
+@SuppressWarnings("deprecation")
 class URLPerm extends Perm {
     URLPerm() {
         super(java.net.URLPermission.class,
@@ -4380,6 +4410,7 @@
     }
 }
 
+@SuppressWarnings("deprecation")
 class RuntimePerm extends Perm {
     RuntimePerm() {
         super(java.lang.RuntimePermission.class,
@@ -4420,6 +4451,7 @@
     }
 }
 
+@SuppressWarnings("deprecation")
 class SecurityPerm extends Perm {
     SecurityPerm() {
         super(java.security.SecurityPermission.class,
--- a/jdk/test/TEST.groups	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/TEST.groups	Thu Jan 28 15:43:15 2016 -0800
@@ -77,6 +77,7 @@
     sun/misc \
     sun/reflect \
     jdk/lambda \
+    jdk/internal/misc \
     vm
 
 # All of the java.util package
@@ -144,7 +145,8 @@
     java/util/stream
 
 jdk_math = \
-    java/math
+    java/math \
+    jdk/internal/math
 
 jdk_io = \
     java/io
--- a/jdk/test/com/sun/jdi/LineNumberInfo.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/com/sun/jdi/LineNumberInfo.java	Thu Jan 28 15:43:15 2016 -0800
@@ -29,7 +29,7 @@
  *
  *  @modules jdk.jdi
  *  @run build TestScaffold VMConnection TargetListener TargetAdapter
- *  @run compile -g LineNumberInfo.java ControlFlow.java
+ *  @run compile -XDstringConcat=inline -g LineNumberInfo.java ControlFlow.java
  *
  *  @run driver LineNumberInfo
  */
--- a/jdk/test/com/sun/jdi/sde/InstallSDE.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/com/sun/jdi/sde/InstallSDE.java	Thu Jan 28 15:43:15 2016 -0800
@@ -253,12 +253,16 @@
                 case 3:  // Integer
                 case 4:  // Float
                 case 12: // NameAndType
+                case 18: // InvokeDynamic
                     copy(4);
                     break;
                 case 5:  // Long
                 case 6:  // Double
                     copy(8);
                     break;
+                case 15: // MethodHandle
+                    copy(3);
+                    break;
                 case 1:  // Utf8
                     int len = readU2();
                     writeU2(len);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/ImplicitStringConcat.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary test implicit String concatenations
+ *
+ * @compile ImplicitStringConcat.java
+ * @run main/othervm ImplicitStringConcat
+ *
+ * @compile -XDstringConcat=inline ImplicitStringConcat.java
+ * @run main/othervm ImplicitStringConcat
+ *
+ * @compile -XDstringConcat=indy -source 1.9 -target 1.9 ImplicitStringConcat.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcat
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ *
+ * @compile -XDstringConcat=indyWithConstants -source 1.9 -target 1.9 ImplicitStringConcat.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcat
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcat
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcat
+*/
+import java.lang.StringBuilder;
+
+public class ImplicitStringConcat {
+
+    static boolean b = true;
+    static byte by = 42;
+    static short sh = 42;
+    static char ch = 'a';
+    static int i = 42;
+    static float fl = 42.0f;
+    static long l = 42;
+    static double d = 42.0d;
+    static String s = "foo";
+    static String sNull = null;
+    static Object o = "bar";
+    static Object oNull = null;
+    static CharSequence cs = "bar";
+    static char[] chars = new char[] {'a'};
+
+    static MyClass myCl = new MyClass();
+    static MyClassNull myClNull = new MyClassNull();
+    static Object  myCl2 = new MyClass();
+    static Object[] myArr = new Object[] { myCl };
+    static final Object[] s_myArr = new Object[] { myCl };
+
+    static StringBuffer sb = new StringBuffer("a");
+
+    public static void main(String[] args) throws Exception {
+
+        test("footrue", s + b);
+        test("foo42",   s + by);
+        test("foo42",   s + sh);
+        test("fooa",    s + ch);
+        test("foo42",   s + i);
+        test("foo42",   s + l);
+        test("foo42.0", s + fl);
+        test("foo42.0", s + d);
+        test("foofoo",  s + s);
+        test("foonull", s + sNull);
+        test("foobar",  s + o);
+        test("foonull", s + oNull);
+        test("foobar",  s + cs);
+
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.append("foo");
+            sb.append(myArr.toString());
+            test(sb.toString(), s + myArr);
+        }
+
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.append("foo");
+            sb.append(s_myArr.toString());
+            test(sb.toString(), s + s_myArr);
+        }
+
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.append("foo[C@");
+            sb.append(Integer.toHexString(System.identityHashCode(chars)));
+            test(sb.toString(), s + chars);
+        }
+
+        test("fooa",    s + ImplicitStringConcat.sb);
+        test("foonull", s + null);
+        test("fooMyClass", s + myCl);
+        test("foonull",    s + myClNull);
+        test("fooMyClass", s + myCl2);
+
+        s = "foo";  s += b;     test("footrue", s);
+        s = "foo";  s += by;    test("foo42", s);
+        s = "foo";  s += sh;    test("foo42", s);
+        s = "foo";  s += ch;    test("fooa", s);
+        s = "foo";  s += i;     test("foo42", s);
+        s = "foo";  s += l;     test("foo42", s);
+        s = "foo";  s += fl;    test("foo42.0", s);
+        s = "foo";  s += d;     test("foo42.0", s);
+        s = "foo";  s += s;     test("foofoo", s);
+        s = "foo";  s += sNull; test("foonull", s);
+        s = "foo";  s += o;     test("foobar", s);
+        s = "foo";  s += oNull; test("foonull", s);
+        s = "foo";  s += cs;    test("foobar", s);
+
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.append("foo[C@");
+            sb.append(Integer.toHexString(System.identityHashCode(chars)));
+            s = "foo";
+            s += chars;
+            test(sb.toString(), s);
+        }
+
+        s = "foo";  s += ImplicitStringConcat.sb;    test("fooa", s);
+        s = "foo";  s += null;  test("foonull", s);
+        s = "foo";  s += myCl;  test("fooMyClass", s);
+        s = "foo";  s += myCl2; test("fooMyClass", s);
+    }
+
+    public static void test(String expected, String actual) {
+       // Fingers crossed: String concat should work.
+       if (!expected.equals(actual)) {
+           StringBuilder sb = new StringBuilder();
+           sb.append("Expected = ");
+           sb.append(expected);
+           sb.append(", actual = ");
+           sb.append(actual);
+           throw new IllegalStateException(sb.toString());
+       }
+    }
+
+    static class MyClass {
+        public String toString() {
+            return "MyClass";
+        }
+    }
+
+    static class MyClassNull {
+        public String toString() {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/ImplicitStringConcatArgCount.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary Test multiple number of arguments to concatenate.
+ *
+ * @compile ImplicitStringConcatArgCount.java
+ * @run main/othervm ImplicitStringConcatArgCount
+ *
+ * @compile -XDallowStringFolding=false -XDstringConcat=inline ImplicitStringConcatArgCount.java
+ * @run main/othervm ImplicitStringConcatArgCount
+ *
+ * @compile -XDallowStringFolding=false -XDstringConcat=indy -source 1.9 -target 1.9 ImplicitStringConcatArgCount.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatArgCount
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ *
+ * @compile -XDallowStringFolding=false -XDstringConcat=indyWithConstants -source 1.9 -target 1.9 ImplicitStringConcatArgCount.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatArgCount
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatArgCount
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatArgCount
+*/
+public class ImplicitStringConcatArgCount {
+    static final String s = "f";
+    static final String s1 = "o";
+    static String s2 = "o";
+    static int i = 7;
+
+    public static void main(String[] args) throws Exception {
+        test("fo",          s + s1);
+        test("foo",         s + s1 + s2);
+        test("foo7",        s + s1 + s2 + i);
+        test("foo77",       s + s1 + s2 + i + i);
+        test("foo777",      s + s1 + s2 + i + i + i);
+        test("foo7777",     s + s1 + s2 + i + i + i + i);
+        test("foo77777",    s + s1 + s2 + i + i + i + i + i);
+        test("foo777777",   s + s1 + s2 + i + i + i + i + i + i);
+        test("foo7777777",  s + s1 + s2 + i + i + i + i + i + i + i);
+        test("foo77777777", s + s1 + s2 + i + i + i + i + i + i + i + i);
+    }
+
+    public static void test(String expected, String actual) {
+       if (!expected.equals(actual)) {
+           StringBuilder sb = new StringBuilder();
+           sb.append("Expected = ");
+           sb.append(expected);
+           sb.append(", actual = ");
+           sb.append(actual);
+           throw new IllegalStateException(sb.toString());
+       }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/ImplicitStringConcatBoundaries.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary Test the boundary values for concatenation arguments.
+ *
+ * @compile ImplicitStringConcatBoundaries.java
+ * @run main/othervm ImplicitStringConcatBoundaries
+ *
+ * @compile -XDstringConcat=inline ImplicitStringConcatBoundaries.java
+ * @run main/othervm ImplicitStringConcatBoundaries
+ *
+ * @compile -XDstringConcat=indy -source 1.9 -target 1.9 ImplicitStringConcatBoundaries.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatBoundaries
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ *
+ * @compile -XDstringConcat=indyWithConstants -source 1.9 -target 1.9 ImplicitStringConcatBoundaries.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatBoundaries
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatBoundaries
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatBoundaries
+
+*/
+
+public class ImplicitStringConcatBoundaries {
+
+    public static final boolean BOOL_TRUE_1         = true;
+    public static       boolean BOOL_TRUE_2         = true;
+    public static final boolean BOOL_FALSE_1        = false;
+    public static       boolean BOOL_FALSE_2        = false;
+
+    public static final byte    BYTE_MIN_1          = Byte.MIN_VALUE;
+    public static       byte    BYTE_MIN_2          = Byte.MIN_VALUE;
+    public static final byte    BYTE_MAX_1          = Byte.MAX_VALUE;
+    public static       byte    BYTE_MAX_2          = Byte.MAX_VALUE;
+
+    public static final short   SHORT_MIN_1         = Short.MIN_VALUE;
+    public static       short   SHORT_MIN_2         = Short.MIN_VALUE;
+    public static final short   SHORT_MAX_1         = Short.MAX_VALUE;
+    public static       short   SHORT_MAX_2         = Short.MAX_VALUE;
+
+    public static final char    CHAR_MIN_1          = Character.MIN_VALUE;
+    public static       char    CHAR_MIN_2          = Character.MIN_VALUE;
+    public static final char    CHAR_MAX_1          = Character.MAX_VALUE;
+    public static       char    CHAR_MAX_2          = Character.MAX_VALUE;
+
+    public static final int     INT_MIN_1           = Integer.MIN_VALUE;
+    public static       int     INT_MIN_2           = Integer.MIN_VALUE;
+    public static final int     INT_MAX_1           = Integer.MAX_VALUE;
+    public static       int     INT_MAX_2           = Integer.MAX_VALUE;
+
+    public static final float   FLOAT_MIN_EXP_1     = Float.MIN_EXPONENT;
+    public static       float   FLOAT_MIN_EXP_2     = Float.MIN_EXPONENT;
+    public static final float   FLOAT_MIN_NORM_1    = Float.MIN_NORMAL;
+    public static       float   FLOAT_MIN_NORM_2    = Float.MIN_NORMAL;
+    public static final float   FLOAT_MIN_1         = Float.MIN_VALUE;
+    public static       float   FLOAT_MIN_2         = Float.MIN_VALUE;
+    public static final float   FLOAT_MAX_1         = Float.MAX_VALUE;
+    public static       float   FLOAT_MAX_2         = Float.MAX_VALUE;
+
+    public static final long    LONG_MIN_1          = Long.MIN_VALUE;
+    public static       long    LONG_MIN_2          = Long.MIN_VALUE;
+    public static final long    LONG_MAX_1          = Long.MAX_VALUE;
+    public static       long    LONG_MAX_2          = Long.MAX_VALUE;
+
+    public static final double  DOUBLE_MIN_EXP_1    = Double.MIN_EXPONENT;
+    public static       double  DOUBLE_MIN_EXP_2    = Double.MIN_EXPONENT;
+    public static final double  DOUBLE_MIN_NORM_1   = Double.MIN_NORMAL;
+    public static       double  DOUBLE_MIN_NORM_2   = Double.MIN_NORMAL;
+    public static final double  DOUBLE_MIN_1        = Double.MIN_VALUE;
+    public static       double  DOUBLE_MIN_2        = Double.MIN_VALUE;
+    public static final double  DOUBLE_MAX_1        = Double.MAX_VALUE;
+    public static       double  DOUBLE_MAX_2        = Double.MAX_VALUE;
+
+    public static void main(String[] args) throws Exception {
+        test("foofalse",                    "foo" + BOOL_FALSE_1);
+        test("foofalse",                    "foo" + BOOL_FALSE_2);
+        test("footrue",                     "foo" + BOOL_TRUE_1);
+        test("footrue",                     "foo" + BOOL_TRUE_2);
+
+        test("foo127",                      "foo" + BYTE_MAX_1);
+        test("foo127",                      "foo" + BYTE_MAX_2);
+        test("foo-128",                     "foo" + BYTE_MIN_1);
+        test("foo-128",                     "foo" + BYTE_MIN_2);
+
+        test("foo32767",                    "foo" + SHORT_MAX_1);
+        test("foo32767",                    "foo" + SHORT_MAX_2);
+        test("foo-32768",                   "foo" + SHORT_MIN_1);
+        test("foo-32768",                   "foo" + SHORT_MIN_2);
+
+        test("foo\u0000",                   "foo" + CHAR_MIN_1);
+        test("foo\u0000",                   "foo" + CHAR_MIN_2);
+        test("foo\uFFFF",                   "foo" + CHAR_MAX_1);
+        test("foo\uFFFF",                   "foo" + CHAR_MAX_2);
+
+        test("foo2147483647",               "foo" + INT_MAX_1);
+        test("foo2147483647",               "foo" + INT_MAX_2);
+        test("foo-2147483648",              "foo" + INT_MIN_1);
+        test("foo-2147483648",              "foo" + INT_MIN_2);
+
+        test("foo1.17549435E-38",           "foo" + FLOAT_MIN_NORM_1);
+        test("foo1.17549435E-38",           "foo" + FLOAT_MIN_NORM_2);
+        test("foo-126.0",                   "foo" + FLOAT_MIN_EXP_1);
+        test("foo-126.0",                   "foo" + FLOAT_MIN_EXP_2);
+        test("foo1.4E-45",                  "foo" + FLOAT_MIN_1);
+        test("foo1.4E-45",                  "foo" + FLOAT_MIN_2);
+        test("foo3.4028235E38",             "foo" + FLOAT_MAX_1);
+        test("foo3.4028235E38",             "foo" + FLOAT_MAX_2);
+
+        test("foo-9223372036854775808",     "foo" + LONG_MIN_1);
+        test("foo-9223372036854775808",     "foo" + LONG_MIN_2);
+        test("foo9223372036854775807",      "foo" + LONG_MAX_1);
+        test("foo9223372036854775807",      "foo" + LONG_MAX_2);
+
+        test("foo2.2250738585072014E-308",  "foo" + DOUBLE_MIN_NORM_1);
+        test("foo2.2250738585072014E-308",  "foo" + DOUBLE_MIN_NORM_2);
+        test("foo-1022.0",                  "foo" + DOUBLE_MIN_EXP_1);
+        test("foo-1022.0",                  "foo" + DOUBLE_MIN_EXP_2);
+        test("foo4.9E-324",                 "foo" + DOUBLE_MIN_1);
+        test("foo4.9E-324",                 "foo" + DOUBLE_MIN_2);
+        test("foo1.7976931348623157E308",   "foo" + DOUBLE_MAX_1);
+        test("foo1.7976931348623157E308",   "foo" + DOUBLE_MAX_2);
+    }
+
+    public static void test(String expected, String actual) {
+       if (!expected.equals(actual)) {
+           StringBuilder sb = new StringBuilder();
+           sb.append("Expected = ");
+           sb.append(expected);
+           sb.append(", actual = ");
+           sb.append(actual);
+           throw new IllegalStateException(sb.toString());
+       }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/ImplicitStringConcatMany.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary Test implicit String concatenations with lots of arguments.
+ *
+ * @compile ImplicitStringConcatMany.java
+ * @run main/othervm ImplicitStringConcatMany
+ *
+ * @compile -XDstringConcat=inline ImplicitStringConcatMany.java
+ * @run main/othervm ImplicitStringConcatMany
+ *
+ * @compile -XDstringConcat=indy -source 1.9 -target 1.9 ImplicitStringConcatMany.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatMany
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ *
+ * @compile -XDstringConcat=indyWithConstants -source 1.9 -target 1.9 ImplicitStringConcatMany.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatMany
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatMany
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatMany
+*/
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+public class ImplicitStringConcatMany {
+
+    static String s000, s001, s002, s003, s004, s005, s006, s007, s008, s009;
+    static String s010, s011, s012, s013, s014, s015, s016, s017, s018, s019;
+    static String s020, s021, s022, s023, s024, s025, s026, s027, s028, s029;
+    static String s030, s031, s032, s033, s034, s035, s036, s037, s038, s039;
+    static String s040, s041, s042, s043, s044, s045, s046, s047, s048, s049;
+    static String s050, s051, s052, s053, s054, s055, s056, s057, s058, s059;
+    static String s060, s061, s062, s063, s064, s065, s066, s067, s068, s069;
+    static String s070, s071, s072, s073, s074, s075, s076, s077, s078, s079;
+    static String s080, s081, s082, s083, s084, s085, s086, s087, s088, s089;
+    static String s090, s091, s092, s093, s094, s095, s096, s097, s098, s099;
+
+    static String s100, s101, s102, s103, s104, s105, s106, s107, s108, s109;
+    static String s110, s111, s112, s113, s114, s115, s116, s117, s118, s119;
+    static String s120, s121, s122, s123, s124, s125, s126, s127, s128, s129;
+    static String s130, s131, s132, s133, s134, s135, s136, s137, s138, s139;
+    static String s140, s141, s142, s143, s144, s145, s146, s147, s148, s149;
+    static String s150, s151, s152, s153, s154, s155, s156, s157, s158, s159;
+    static String s160, s161, s162, s163, s164, s165, s166, s167, s168, s169;
+    static String s170, s171, s172, s173, s174, s175, s176, s177, s178, s179;
+    static String s180, s181, s182, s183, s184, s185, s186, s187, s188, s189;
+    static String s190, s191, s192, s193, s194, s195, s196, s197, s198, s199;
+
+    static String s200, s201, s202, s203, s204, s205, s206, s207, s208, s209;
+    static String s210, s211, s212, s213, s214, s215, s216, s217, s218, s219;
+    static String s220, s221, s222, s223, s224, s225, s226, s227, s228, s229;
+    static String s230, s231, s232, s233, s234, s235, s236, s237, s238, s239;
+    static String s240, s241, s242, s243, s244, s245, s246, s247, s248, s249;
+    static String s250, s251, s252, s253, s254, s255, s256, s257, s258, s259;
+    static String s260, s261, s262, s263, s264, s265, s266, s267, s268, s269;
+    static String s270, s271, s272, s273, s274, s275, s276, s277, s278, s279;
+    static String s280, s281, s282, s283, s284, s285, s286, s287, s288, s289;
+    static String s290, s291, s292, s293, s294, s295, s296, s297, s298, s299;
+
+    static {
+        for (Field f : ImplicitStringConcatMany.class.getDeclaredFields()) {
+            if (Modifier.isStatic(f.getModifiers())) {
+                String name = f.getName();
+                try {
+                    f.set(null, name);
+                } catch (IllegalAccessException e) {
+                    throw new IllegalStateException(e);
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        String res =
+            s000 + s001 + s002 + s003 + s004 + s005 + s006 + s007 + s008 + s009 +
+            s010 + s011 + s012 + s013 + s014 + s015 + s016 + s017 + s018 + s019 +
+            s020 + s021 + s022 + s023 + s024 + s025 + s026 + s027 + s028 + s029 +
+            s030 + s031 + s032 + s033 + s034 + s035 + s036 + s037 + s038 + s039 +
+            s040 + s041 + s042 + s043 + s044 + s045 + s046 + s047 + s048 + s049 +
+            s050 + s051 + s052 + s053 + s054 + s055 + s056 + s057 + s058 + s059 +
+            s060 + s061 + s062 + s063 + s064 + s065 + s066 + s067 + s068 + s069 +
+            s070 + s071 + s072 + s073 + s074 + s075 + s076 + s077 + s078 + s079 +
+            s080 + s081 + s082 + s083 + s084 + s085 + s086 + s087 + s088 + s089 +
+            s090 + s091 + s092 + s093 + s094 + s095 + s096 + s097 + s098 + s099 +
+
+            s100 + s101 + s102 + s103 + s104 + s105 + s106 + s107 + s108 + s109 +
+            s110 + s111 + s112 + s113 + s114 + s115 + s116 + s117 + s118 + s119 +
+            s120 + s121 + s122 + s123 + s124 + s125 + s126 + s127 + s128 + s129 +
+            s130 + s131 + s132 + s133 + s134 + s135 + s136 + s137 + s138 + s139 +
+            s140 + s141 + s142 + s143 + s144 + s145 + s146 + s147 + s148 + s149 +
+            s150 + s151 + s152 + s153 + s154 + s155 + s156 + s157 + s158 + s159 +
+            s160 + s161 + s162 + s163 + s164 + s165 + s166 + s167 + s168 + s169 +
+            s170 + s171 + s172 + s173 + s174 + s175 + s176 + s177 + s178 + s179 +
+            s180 + s181 + s182 + s183 + s184 + s185 + s186 + s187 + s188 + s189 +
+            s190 + s191 + s192 + s193 + s194 + s195 + s196 + s197 + s198 + s199 +
+
+            s200 + s201 + s202 + s203 + s204 + s205 + s206 + s207 + s208 + s209 +
+            s210 + s211 + s212 + s213 + s214 + s215 + s216 + s217 + s218 + s219 +
+            s220 + s221 + s222 + s223 + s224 + s225 + s226 + s227 + s228 + s229 +
+            s230 + s231 + s232 + s233 + s234 + s235 + s236 + s237 + s238 + s239 +
+            s240 + s241 + s242 + s243 + s244 + s245 + s246 + s247 + s248 + s249 +
+            s250 + s251 + s252 + s253 + s254 + s255 + s256 + s257 + s258 + s259 +
+            s260 + s261 + s262 + s263 + s264 + s265 + s266 + s267 + s268 + s269 +
+            s270 + s271 + s272 + s273 + s274 + s275 + s276 + s277 + s278 + s279 +
+            s280 + s281 + s282 + s283 + s284 + s285 + s286 + s287 + s288 + s289 +
+            s290 + s291 + s292 + s293 + s294 + s295 + s296 + s297 + s298 + s299;
+
+       StringBuilder sb = new StringBuilder();
+       for (int c = 0; c < 300; c++) {
+            sb.append(String.format("s%03d", c));
+       }
+       test(sb.toString(), res);
+    }
+
+    public static void test(String expected, String actual) {
+       // Fingers crossed: String concat should work.
+       if (!expected.equals(actual)) {
+          throw new IllegalStateException("Expected = " + expected + ", actual = " + actual);
+       }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/ImplicitStringConcatManyLongs.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary Test implicit String concatenations with lots of arguments (two-slot version)
+ *
+ * @compile ImplicitStringConcatManyLongs.java
+ * @run main/othervm ImplicitStringConcatManyLongs
+ *
+ * @compile -XDstringConcat=inline ImplicitStringConcatManyLongs.java
+ * @run main/othervm ImplicitStringConcatManyLongs
+ *
+ * @compile -XDstringConcat=indy -source 1.9 -target 1.9 ImplicitStringConcatManyLongs.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatManyLongs
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ *
+ * @compile -XDstringConcat=indyWithConstants -source 1.9 -target 1.9 ImplicitStringConcatManyLongs.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatManyLongs
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatManyLongs
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatManyLongs
+*/
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+public class ImplicitStringConcatManyLongs {
+
+    static long s000, s001, s002, s003, s004, s005, s006, s007, s008, s009;
+    static long s010, s011, s012, s013, s014, s015, s016, s017, s018, s019;
+    static long s020, s021, s022, s023, s024, s025, s026, s027, s028, s029;
+    static long s030, s031, s032, s033, s034, s035, s036, s037, s038, s039;
+    static long s040, s041, s042, s043, s044, s045, s046, s047, s048, s049;
+    static long s050, s051, s052, s053, s054, s055, s056, s057, s058, s059;
+    static long s060, s061, s062, s063, s064, s065, s066, s067, s068, s069;
+    static long s070, s071, s072, s073, s074, s075, s076, s077, s078, s079;
+    static long s080, s081, s082, s083, s084, s085, s086, s087, s088, s089;
+    static long s090, s091, s092, s093, s094, s095, s096, s097, s098, s099;
+
+    static long s100, s101, s102, s103, s104, s105, s106, s107, s108, s109;
+    static long s110, s111, s112, s113, s114, s115, s116, s117, s118, s119;
+    static long s120, s121, s122, s123, s124, s125, s126, s127, s128, s129;
+    static long s130, s131, s132, s133, s134, s135, s136, s137, s138, s139;
+    static long s140, s141, s142, s143, s144, s145, s146, s147, s148, s149;
+    static long s150, s151, s152, s153, s154, s155, s156, s157, s158, s159;
+    static long s160, s161, s162, s163, s164, s165, s166, s167, s168, s169;
+    static long s170, s171, s172, s173, s174, s175, s176, s177, s178, s179;
+    static long s180, s181, s182, s183, s184, s185, s186, s187, s188, s189;
+    static long s190, s191, s192, s193, s194, s195, s196, s197, s198, s199;
+
+    static long s200, s201, s202, s203, s204, s205, s206, s207, s208, s209;
+    static long s210, s211, s212, s213, s214, s215, s216, s217, s218, s219;
+    static long s220, s221, s222, s223, s224, s225, s226, s227, s228, s229;
+    static long s230, s231, s232, s233, s234, s235, s236, s237, s238, s239;
+    static long s240, s241, s242, s243, s244, s245, s246, s247, s248, s249;
+    static long s250, s251, s252, s253, s254, s255, s256, s257, s258, s259;
+    static long s260, s261, s262, s263, s264, s265, s266, s267, s268, s269;
+    static long s270, s271, s272, s273, s274, s275, s276, s277, s278, s279;
+    static long s280, s281, s282, s283, s284, s285, s286, s287, s288, s289;
+    static long s290, s291, s292, s293, s294, s295, s296, s297, s298, s299;
+
+    static {
+        for (Field f : ImplicitStringConcatManyLongs.class.getDeclaredFields()) {
+            if (Modifier.isStatic(f.getModifiers())) {
+                String name = f.getName();
+                try {
+                    f.set(null, Long.valueOf(name.substring(1)));
+                } catch (IllegalAccessException e) {
+                    throw new IllegalStateException(e);
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        String res = "" +
+            s000 + s001 + s002 + s003 + s004 + s005 + s006 + s007 + s008 + s009 +
+            s010 + s011 + s012 + s013 + s014 + s015 + s016 + s017 + s018 + s019 +
+            s020 + s021 + s022 + s023 + s024 + s025 + s026 + s027 + s028 + s029 +
+            s030 + s031 + s032 + s033 + s034 + s035 + s036 + s037 + s038 + s039 +
+            s040 + s041 + s042 + s043 + s044 + s045 + s046 + s047 + s048 + s049 +
+            s050 + s051 + s052 + s053 + s054 + s055 + s056 + s057 + s058 + s059 +
+            s060 + s061 + s062 + s063 + s064 + s065 + s066 + s067 + s068 + s069 +
+            s070 + s071 + s072 + s073 + s074 + s075 + s076 + s077 + s078 + s079 +
+            s080 + s081 + s082 + s083 + s084 + s085 + s086 + s087 + s088 + s089 +
+            s090 + s091 + s092 + s093 + s094 + s095 + s096 + s097 + s098 + s099 +
+
+            s100 + s101 + s102 + s103 + s104 + s105 + s106 + s107 + s108 + s109 +
+            s110 + s111 + s112 + s113 + s114 + s115 + s116 + s117 + s118 + s119 +
+            s120 + s121 + s122 + s123 + s124 + s125 + s126 + s127 + s128 + s129 +
+            s130 + s131 + s132 + s133 + s134 + s135 + s136 + s137 + s138 + s139 +
+            s140 + s141 + s142 + s143 + s144 + s145 + s146 + s147 + s148 + s149 +
+            s150 + s151 + s152 + s153 + s154 + s155 + s156 + s157 + s158 + s159 +
+            s160 + s161 + s162 + s163 + s164 + s165 + s166 + s167 + s168 + s169 +
+            s170 + s171 + s172 + s173 + s174 + s175 + s176 + s177 + s178 + s179 +
+            s180 + s181 + s182 + s183 + s184 + s185 + s186 + s187 + s188 + s189 +
+            s190 + s191 + s192 + s193 + s194 + s195 + s196 + s197 + s198 + s199 +
+
+            s200 + s201 + s202 + s203 + s204 + s205 + s206 + s207 + s208 + s209 +
+            s210 + s211 + s212 + s213 + s214 + s215 + s216 + s217 + s218 + s219 +
+            s220 + s221 + s222 + s223 + s224 + s225 + s226 + s227 + s228 + s229 +
+            s230 + s231 + s232 + s233 + s234 + s235 + s236 + s237 + s238 + s239 +
+            s240 + s241 + s242 + s243 + s244 + s245 + s246 + s247 + s248 + s249 +
+            s250 + s251 + s252 + s253 + s254 + s255 + s256 + s257 + s258 + s259 +
+            s260 + s261 + s262 + s263 + s264 + s265 + s266 + s267 + s268 + s269 +
+            s270 + s271 + s272 + s273 + s274 + s275 + s276 + s277 + s278 + s279 +
+            s280 + s281 + s282 + s283 + s284 + s285 + s286 + s287 + s288 + s289 +
+            s290 + s291 + s292 + s293 + s294 + s295 + s296 + s297 + s298 + s299;
+
+       StringBuilder sb = new StringBuilder();
+       for (int c = 0; c < 300; c++) {
+            sb.append(c);
+       }
+       test(sb.toString(), res);
+    }
+
+    public static void test(String expected, String actual) {
+       // Fingers crossed: String concat should work.
+       if (!expected.equals(actual)) {
+          throw new IllegalStateException("Expected = " + expected + ", actual = " + actual);
+       }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/ImplicitStringConcatShapes-head.template	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary Test implicit String concatenations, multiple shapes.
+ *
+ * @compile ImplicitStringConcatShapes.java
+ * @run main/othervm ImplicitStringConcatShapes
+ *
+ * @compile -XDstringConcat=inline ImplicitStringConcatShapes.java
+ * @run main/othervm ImplicitStringConcatShapes
+ *
+ * @compile -XDstringConcat=indy -source 1.9 -target 1.9 ImplicitStringConcatShapes.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ *
+ * @compile -XDstringConcat=indyWithConstants -source 1.9 -target 1.9 ImplicitStringConcatShapes.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+*/
+public class ImplicitStringConcatShapes {
+    public static void test(String expected, String actual) {
+        // Fingers crossed: String concat should work.
+        if (!expected.equals(actual)) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Expected = ");
+            sb.append(expected);
+            sb.append(", actual = ");
+            sb.append(actual);
+            throw new IllegalStateException(sb.toString());
+        }
+    }
+
+    static class MyClass {
+        private final int i;
+
+        public MyClass(int i) {
+            this.i = i;
+        }
+
+        public String toString() {
+            return new StringBuilder("C(").append(i).append(")").toString();
+        }
+    }
+
+    static class MyClassNullToString {
+        public String toString() {
+            return null;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        new ImplicitStringConcatShapes().run();
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/ImplicitStringConcatShapes.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,5931 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @summary Test implicit String concatenations, multiple shapes.
+ *
+ * @compile ImplicitStringConcatShapes.java
+ * @run main/othervm ImplicitStringConcatShapes
+ *
+ * @compile -XDstringConcat=inline ImplicitStringConcatShapes.java
+ * @run main/othervm ImplicitStringConcatShapes
+ *
+ * @compile -XDstringConcat=indy -source 1.9 -target 1.9 ImplicitStringConcatShapes.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ *
+ * @compile -XDstringConcat=indyWithConstants -source 1.9 -target 1.9 ImplicitStringConcatShapes.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  ImplicitStringConcatShapes
+*/
+public class ImplicitStringConcatShapes {
+    public static void test(String expected, String actual) {
+        // Fingers crossed: String concat should work.
+        if (!expected.equals(actual)) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Expected = ");
+            sb.append(expected);
+            sb.append(", actual = ");
+            sb.append(actual);
+            throw new IllegalStateException(sb.toString());
+        }
+    }
+
+    static class MyClass {
+        private final int i;
+
+        public MyClass(int i) {
+            this.i = i;
+        }
+
+        public String toString() {
+            return new StringBuilder("C(").append(i).append(")").toString();
+        }
+    }
+
+    static class MyClassNullToString {
+        public String toString() {
+            return null;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        new ImplicitStringConcatShapes().run();
+    }
+    static final boolean sf_bl = true;
+    static final byte sf_b = 80;
+    static final byte sf_bM = -41;
+    static final char sf_c = 'C';
+    static final short sf_s = 5500;
+    static final short sf_sM = -8400;
+    static final int sf_i = 75000000;
+    static final int sf_iM = -2000000;
+    static final Integer sf_I = 1000000;
+    static final Integer sf_IN = null;
+    static final float sf_f = 17.0f;
+    static final float sf_fM = -42.0f;
+    static final long sf_l = -194313216L;
+    static final long sf_lM = -1705032704L;
+    static final double sf_d = 12.0d;
+    static final double sf_dM = -84.0d;
+    static final Object sf_o = new MyClass(87);
+    static final Object sf_oN = null;
+    static final Object sf_oNtS = new MyClassNullToString();
+    static final String sf_str = "75";
+    static final String sf_strU = "\u04511";
+    static final String sf_strU1 = "\u000151";
+    static final String sf_strU2 = "\u000292";
+    static final int[] sf_iAN = null;
+    static final Object[] sf_oAN = null;
+    static  boolean s_bl = true;
+    static  byte s_b = 25;
+    static  byte s_bM = -43;
+    static  char s_c = 'T';
+    static  short s_s = 3900;
+    static  short s_sM = -2900;
+    static  int s_i = 97000000;
+    static  int s_iM = -1000000;
+    static  Integer s_I = 25000000;
+    static  Integer s_IN = null;
+    static  float s_f = 55.0f;
+    static  float s_fM = -52.0f;
+    static  long s_l = 935228928L;
+    static  long s_lM = -1410065408L;
+    static  double s_d = 8.0d;
+    static  double s_dM = -96.0d;
+    static  Object s_o = new MyClass(82);
+    static  Object s_oN = null;
+    static  Object s_oNtS = new MyClassNullToString();
+    static  String s_str = "18";
+    static  String s_strU = "\u045180";
+    static  String s_strU1 = "\u000112";
+    static  String s_strU2 = "\u000291";
+    static  int[] s_iAN = null;
+    static  Object[] s_oAN = null;
+     final boolean f_bl = false;
+     final byte f_b = 44;
+     final byte f_bM = -54;
+     final char f_c = 'I';
+     final short f_s = 8000;
+     final short f_sM = -9900;
+     final int f_i = 58000000;
+     final int f_iM = -55000000;
+     final Integer f_I = 94000000;
+     final Integer f_IN = null;
+     final float f_f = 94.0f;
+     final float f_fM = -87.0f;
+     final long f_l = 1460392448L;
+     final long f_lM = -820130816L;
+     final double f_d = 83.0d;
+     final double f_dM = -99.0d;
+     final Object f_o = new MyClass(70);
+     final Object f_oN = null;
+     final Object f_oNtS = new MyClassNullToString();
+     final String f_str = "19";
+     final String f_strU = "\u045176";
+     final String f_strU1 = "\u000121";
+     final String f_strU2 = "\u000218";
+     final int[] f_iAN = null;
+     final Object[] f_oAN = null;
+
+    public void run() {
+        run0();
+        run1();
+        run2();
+        run3();
+        run4();
+        run5();
+    }
+
+    public void run0() {
+        test("-96.0", "" + s_dM);
+        test("null", "" + s_oNtS);
+        test("\u045176", "" + f_strU);
+        test("92", "" + sf_strU2);
+        test("51", "" + sf_strU1);
+        test("null", "" + s_iAN);
+        test("-54", "" + f_bM);
+        test("-87.0", "" + f_fM);
+        test("null", "" + s_oAN);
+        test("19", "" + f_str);
+        test("-41", "" + sf_bM);
+        test("null", "" + sf_IN);
+        test("T", "" + s_c);
+        test("-42.0", "" + sf_fM);
+        test("25", "" + s_b);
+        test("null", "" + f_oN);
+        test("-1410065408", "" + s_lM);
+        test("8.0", "" + s_d);
+        test("55.0", "" + s_f);
+        test("97000000", "" + s_i);
+        test("-9900", "" + f_sM);
+        test("935228928", "" + s_l);
+        test("-8400", "" + sf_sM);
+        test("C(82)", "" + s_o);
+        test("null", "" + sf_oNtS);
+        test("true", "" + s_bl);
+        test("3900", "" + s_s);
+        test("null", "" + sf_oN);
+        test("94000000", "" + f_I);
+        test("null", "" + f_IN);
+        test("true", "" + sf_bl);
+        test("5500", "" + sf_s);
+        test("-2900", "" + s_sM);
+        test("-194313216", "" + sf_l);
+        test("12", "" + s_strU1);
+        test("C(87)", "" + sf_o);
+        test("91", "" + s_strU2);
+        test("21", "" + f_strU1);
+        test("18", "" + f_strU2);
+        test("null", "" + f_iAN);
+        test("null", "" + s_oN);
+        test("\u045180", "" + s_strU);
+        test("C", "" + sf_c);
+        test("75", "" + sf_str);
+        test("-43", "" + s_bM);
+        test("80", "" + sf_b);
+        test("null", "" + s_IN);
+        test("-52.0", "" + s_fM);
+        test("75000000", "" + sf_i);
+        test("44", "" + f_b);
+        test("-1705032704", "" + sf_lM);
+        test("null", "" + f_oAN);
+        test("83.0", "" + f_d);
+        test("I", "" + f_c);
+        test("94.0", "" + f_f);
+        test("12.0", "" + sf_d);
+        test("-99.0", "" + f_dM);
+        test("17.0", "" + sf_f);
+        test("-84.0", "" + sf_dM);
+        test("58000000", "" + f_i);
+        test("-55000000", "" + f_iM);
+        test("1460392448", "" + f_l);
+        test("C(70)", "" + f_o);
+        test("\u04511", "" + sf_strU);
+        test("8000", "" + f_s);
+        test("18", "" + s_str);
+        test("-1000000", "" + s_iM);
+        test("1000000", "" + sf_I);
+        test("null", "" + f_oNtS);
+        test("false", "" + f_bl);
+        test("null", "" + sf_iAN);
+        test("-2000000", "" + sf_iM);
+        test("-820130816", "" + f_lM);
+        test("null", "" + sf_oAN);
+        test("25000000", "" + s_I);
+        test("-96.0-96.0", "" + s_dM + s_dM);
+        test("-96.0null", "" + s_dM + s_oNtS);
+        test("-96.0\u045176", "" + s_dM + f_strU);
+        test("-96.092", "" + s_dM + sf_strU2);
+        test("-96.051", "" + s_dM + sf_strU1);
+        test("-96.0null", "" + s_dM + s_iAN);
+        test("-96.0-54", "" + s_dM + f_bM);
+        test("-96.0-87.0", "" + s_dM + f_fM);
+        test("-96.0null", "" + s_dM + s_oAN);
+        test("-96.019", "" + s_dM + f_str);
+        test("-96.0-41", "" + s_dM + sf_bM);
+        test("-96.0null", "" + s_dM + sf_IN);
+        test("-96.0T", "" + s_dM + s_c);
+        test("-96.0-42.0", "" + s_dM + sf_fM);
+        test("-96.025", "" + s_dM + s_b);
+        test("-96.0null", "" + s_dM + f_oN);
+        test("-96.0-1410065408", "" + s_dM + s_lM);
+        test("-96.08.0", "" + s_dM + s_d);
+        test("-96.055.0", "" + s_dM + s_f);
+        test("-96.097000000", "" + s_dM + s_i);
+        test("-96.0-9900", "" + s_dM + f_sM);
+        test("-96.0935228928", "" + s_dM + s_l);
+        test("-96.0-8400", "" + s_dM + sf_sM);
+        test("-96.0C(82)", "" + s_dM + s_o);
+        test("-96.0null", "" + s_dM + sf_oNtS);
+        test("-96.0true", "" + s_dM + s_bl);
+        test("-96.03900", "" + s_dM + s_s);
+        test("-96.0null", "" + s_dM + sf_oN);
+        test("-96.094000000", "" + s_dM + f_I);
+        test("-96.0null", "" + s_dM + f_IN);
+        test("-96.0true", "" + s_dM + sf_bl);
+        test("-96.05500", "" + s_dM + sf_s);
+        test("-96.0-2900", "" + s_dM + s_sM);
+        test("-96.0-194313216", "" + s_dM + sf_l);
+        test("-96.012", "" + s_dM + s_strU1);
+        test("-96.0C(87)", "" + s_dM + sf_o);
+        test("-96.091", "" + s_dM + s_strU2);
+        test("-96.021", "" + s_dM + f_strU1);
+        test("-96.018", "" + s_dM + f_strU2);
+        test("-96.0null", "" + s_dM + f_iAN);
+        test("-96.0null", "" + s_dM + s_oN);
+        test("-96.0\u045180", "" + s_dM + s_strU);
+        test("-96.0C", "" + s_dM + sf_c);
+        test("-96.075", "" + s_dM + sf_str);
+        test("-96.0-43", "" + s_dM + s_bM);
+        test("-96.080", "" + s_dM + sf_b);
+        test("-96.0null", "" + s_dM + s_IN);
+        test("-96.0-52.0", "" + s_dM + s_fM);
+        test("-96.075000000", "" + s_dM + sf_i);
+        test("-96.044", "" + s_dM + f_b);
+        test("-96.0-1705032704", "" + s_dM + sf_lM);
+        test("-96.0null", "" + s_dM + f_oAN);
+        test("-96.083.0", "" + s_dM + f_d);
+        test("-96.0I", "" + s_dM + f_c);
+        test("-96.094.0", "" + s_dM + f_f);
+        test("-96.012.0", "" + s_dM + sf_d);
+        test("-96.0-99.0", "" + s_dM + f_dM);
+        test("-96.017.0", "" + s_dM + sf_f);
+        test("-96.0-84.0", "" + s_dM + sf_dM);
+        test("-96.058000000", "" + s_dM + f_i);
+        test("-96.0-55000000", "" + s_dM + f_iM);
+        test("-96.01460392448", "" + s_dM + f_l);
+        test("-96.0C(70)", "" + s_dM + f_o);
+        test("-96.0\u04511", "" + s_dM + sf_strU);
+        test("-96.08000", "" + s_dM + f_s);
+        test("-96.018", "" + s_dM + s_str);
+        test("-96.0-1000000", "" + s_dM + s_iM);
+        test("-96.01000000", "" + s_dM + sf_I);
+        test("-96.0null", "" + s_dM + f_oNtS);
+        test("-96.0false", "" + s_dM + f_bl);
+        test("-96.0null", "" + s_dM + sf_iAN);
+        test("-96.0-2000000", "" + s_dM + sf_iM);
+        test("-96.0-820130816", "" + s_dM + f_lM);
+        test("-96.0null", "" + s_dM + sf_oAN);
+        test("-96.025000000", "" + s_dM + s_I);
+        test("null-96.0", "" + s_oNtS + s_dM);
+        test("nullnull", "" + s_oNtS + s_oNtS);
+        test("null\u045176", "" + s_oNtS + f_strU);
+        test("null92", "" + s_oNtS + sf_strU2);
+        test("null51", "" + s_oNtS + sf_strU1);
+        test("nullnull", "" + s_oNtS + s_iAN);
+        test("null-54", "" + s_oNtS + f_bM);
+        test("null-87.0", "" + s_oNtS + f_fM);
+        test("nullnull", "" + s_oNtS + s_oAN);
+        test("null19", "" + s_oNtS + f_str);
+        test("null-41", "" + s_oNtS + sf_bM);
+        test("nullnull", "" + s_oNtS + sf_IN);
+        test("nullT", "" + s_oNtS + s_c);
+        test("null-42.0", "" + s_oNtS + sf_fM);
+        test("null25", "" + s_oNtS + s_b);
+        test("nullnull", "" + s_oNtS + f_oN);
+        test("null-1410065408", "" + s_oNtS + s_lM);
+        test("null8.0", "" + s_oNtS + s_d);
+        test("null55.0", "" + s_oNtS + s_f);
+        test("null97000000", "" + s_oNtS + s_i);
+        test("null-9900", "" + s_oNtS + f_sM);
+        test("null935228928", "" + s_oNtS + s_l);
+        test("null-8400", "" + s_oNtS + sf_sM);
+        test("nullC(82)", "" + s_oNtS + s_o);
+        test("nullnull", "" + s_oNtS + sf_oNtS);
+        test("nulltrue", "" + s_oNtS + s_bl);
+        test("null3900", "" + s_oNtS + s_s);
+        test("nullnull", "" + s_oNtS + sf_oN);
+        test("null94000000", "" + s_oNtS + f_I);
+        test("nullnull", "" + s_oNtS + f_IN);
+        test("nulltrue", "" + s_oNtS + sf_bl);
+        test("null5500", "" + s_oNtS + sf_s);
+        test("null-2900", "" + s_oNtS + s_sM);
+        test("null-194313216", "" + s_oNtS + sf_l);
+        test("null12", "" + s_oNtS + s_strU1);
+        test("nullC(87)", "" + s_oNtS + sf_o);
+        test("null91", "" + s_oNtS + s_strU2);
+        test("null21", "" + s_oNtS + f_strU1);
+        test("null18", "" + s_oNtS + f_strU2);
+        test("nullnull", "" + s_oNtS + f_iAN);
+        test("nullnull", "" + s_oNtS + s_oN);
+        test("null\u045180", "" + s_oNtS + s_strU);
+        test("nullC", "" + s_oNtS + sf_c);
+        test("null75", "" + s_oNtS + sf_str);
+        test("null-43", "" + s_oNtS + s_bM);
+        test("null80", "" + s_oNtS + sf_b);
+        test("nullnull", "" + s_oNtS + s_IN);
+        test("null-52.0", "" + s_oNtS + s_fM);
+        test("null75000000", "" + s_oNtS + sf_i);
+        test("null44", "" + s_oNtS + f_b);
+        test("null-1705032704", "" + s_oNtS + sf_lM);
+        test("nullnull", "" + s_oNtS + f_oAN);
+        test("null83.0", "" + s_oNtS + f_d);
+        test("nullI", "" + s_oNtS + f_c);
+        test("null94.0", "" + s_oNtS + f_f);
+        test("null12.0", "" + s_oNtS + sf_d);
+        test("null-99.0", "" + s_oNtS + f_dM);
+        test("null17.0", "" + s_oNtS + sf_f);
+        test("null-84.0", "" + s_oNtS + sf_dM);
+        test("null58000000", "" + s_oNtS + f_i);
+        test("null-55000000", "" + s_oNtS + f_iM);
+        test("null1460392448", "" + s_oNtS + f_l);
+        test("nullC(70)", "" + s_oNtS + f_o);
+        test("null\u04511", "" + s_oNtS + sf_strU);
+        test("null8000", "" + s_oNtS + f_s);
+        test("null18", "" + s_oNtS + s_str);
+        test("null-1000000", "" + s_oNtS + s_iM);
+        test("null1000000", "" + s_oNtS + sf_I);
+        test("nullnull", "" + s_oNtS + f_oNtS);
+        test("nullfalse", "" + s_oNtS + f_bl);
+        test("nullnull", "" + s_oNtS + sf_iAN);
+        test("null-2000000", "" + s_oNtS + sf_iM);
+        test("null-820130816", "" + s_oNtS + f_lM);
+        test("nullnull", "" + s_oNtS + sf_oAN);
+        test("null25000000", "" + s_oNtS + s_I);
+        test("\u045176-96.0", "" + f_strU + s_dM);
+        test("\u045176null", "" + f_strU + s_oNtS);
+        test("\u045176\u045176", "" + f_strU + f_strU);
+        test("\u04517692", "" + f_strU + sf_strU2);
+        test("\u04517651", "" + f_strU + sf_strU1);
+        test("\u045176null", "" + f_strU + s_iAN);
+        test("\u045176-54", "" + f_strU + f_bM);
+        test("\u045176-87.0", "" + f_strU + f_fM);
+        test("\u045176null", "" + f_strU + s_oAN);
+        test("\u04517619", "" + f_strU + f_str);
+        test("\u045176-41", "" + f_strU + sf_bM);
+        test("\u045176null", "" + f_strU + sf_IN);
+        test("\u045176T", "" + f_strU + s_c);
+        test("\u045176-42.0", "" + f_strU + sf_fM);
+        test("\u04517625", "" + f_strU + s_b);
+        test("\u045176null", "" + f_strU + f_oN);
+        test("\u045176-1410065408", "" + f_strU + s_lM);
+        test("\u0451768.0", "" + f_strU + s_d);
+        test("\u04517655.0", "" + f_strU + s_f);
+        test("\u04517697000000", "" + f_strU + s_i);
+        test("\u045176-9900", "" + f_strU + f_sM);
+        test("\u045176935228928", "" + f_strU + s_l);
+        test("\u045176-8400", "" + f_strU + sf_sM);
+        test("\u045176C(82)", "" + f_strU + s_o);
+        test("\u045176null", "" + f_strU + sf_oNtS);
+        test("\u045176true", "" + f_strU + s_bl);
+        test("\u0451763900", "" + f_strU + s_s);
+        test("\u045176null", "" + f_strU + sf_oN);
+        test("\u04517694000000", "" + f_strU + f_I);
+        test("\u045176null", "" + f_strU + f_IN);
+        test("\u045176true", "" + f_strU + sf_bl);
+        test("\u0451765500", "" + f_strU + sf_s);
+        test("\u045176-2900", "" + f_strU + s_sM);
+        test("\u045176-194313216", "" + f_strU + sf_l);
+        test("\u04517612", "" + f_strU + s_strU1);
+        test("\u045176C(87)", "" + f_strU + sf_o);
+        test("\u04517691", "" + f_strU + s_strU2);
+        test("\u04517621", "" + f_strU + f_strU1);
+        test("\u04517618", "" + f_strU + f_strU2);
+        test("\u045176null", "" + f_strU + f_iAN);
+        test("\u045176null", "" + f_strU + s_oN);
+        test("\u045176\u045180", "" + f_strU + s_strU);
+        test("\u045176C", "" + f_strU + sf_c);
+        test("\u04517675", "" + f_strU + sf_str);
+        test("\u045176-43", "" + f_strU + s_bM);
+        test("\u04517680", "" + f_strU + sf_b);
+        test("\u045176null", "" + f_strU + s_IN);
+        test("\u045176-52.0", "" + f_strU + s_fM);
+        test("\u04517675000000", "" + f_strU + sf_i);
+        test("\u04517644", "" + f_strU + f_b);
+        test("\u045176-1705032704", "" + f_strU + sf_lM);
+        test("\u045176null", "" + f_strU + f_oAN);
+        test("\u04517683.0", "" + f_strU + f_d);
+        test("\u045176I", "" + f_strU + f_c);
+        test("\u04517694.0", "" + f_strU + f_f);
+        test("\u04517612.0", "" + f_strU + sf_d);
+        test("\u045176-99.0", "" + f_strU + f_dM);
+        test("\u04517617.0", "" + f_strU + sf_f);
+        test("\u045176-84.0", "" + f_strU + sf_dM);
+        test("\u04517658000000", "" + f_strU + f_i);
+        test("\u045176-55000000", "" + f_strU + f_iM);
+        test("\u0451761460392448", "" + f_strU + f_l);
+        test("\u045176C(70)", "" + f_strU + f_o);
+        test("\u045176\u04511", "" + f_strU + sf_strU);
+        test("\u0451768000", "" + f_strU + f_s);
+        test("\u04517618", "" + f_strU + s_str);
+        test("\u045176-1000000", "" + f_strU + s_iM);
+        test("\u0451761000000", "" + f_strU + sf_I);
+        test("\u045176null", "" + f_strU + f_oNtS);
+        test("\u045176false", "" + f_strU + f_bl);
+        test("\u045176null", "" + f_strU + sf_iAN);
+        test("\u045176-2000000", "" + f_strU + sf_iM);
+        test("\u045176-820130816", "" + f_strU + f_lM);
+        test("\u045176null", "" + f_strU + sf_oAN);
+        test("\u04517625000000", "" + f_strU + s_I);
+        test("92-96.0", "" + sf_strU2 + s_dM);
+        test("92null", "" + sf_strU2 + s_oNtS);
+        test("92\u045176", "" + sf_strU2 + f_strU);
+        test("9292", "" + sf_strU2 + sf_strU2);
+        test("9251", "" + sf_strU2 + sf_strU1);
+        test("92null", "" + sf_strU2 + s_iAN);
+        test("92-54", "" + sf_strU2 + f_bM);
+        test("92-87.0", "" + sf_strU2 + f_fM);
+        test("92null", "" + sf_strU2 + s_oAN);
+        test("9219", "" + sf_strU2 + f_str);
+        test("92-41", "" + sf_strU2 + sf_bM);
+        test("92null", "" + sf_strU2 + sf_IN);
+        test("92T", "" + sf_strU2 + s_c);
+        test("92-42.0", "" + sf_strU2 + sf_fM);
+        test("9225", "" + sf_strU2 + s_b);
+        test("92null", "" + sf_strU2 + f_oN);
+        test("92-1410065408", "" + sf_strU2 + s_lM);
+        test("928.0", "" + sf_strU2 + s_d);
+        test("9255.0", "" + sf_strU2 + s_f);
+        test("9297000000", "" + sf_strU2 + s_i);
+        test("92-9900", "" + sf_strU2 + f_sM);
+        test("92935228928", "" + sf_strU2 + s_l);
+        test("92-8400", "" + sf_strU2 + sf_sM);
+        test("92C(82)", "" + sf_strU2 + s_o);
+        test("92null", "" + sf_strU2 + sf_oNtS);
+        test("92true", "" + sf_strU2 + s_bl);
+        test("923900", "" + sf_strU2 + s_s);
+        test("92null", "" + sf_strU2 + sf_oN);
+        test("9294000000", "" + sf_strU2 + f_I);
+        test("92null", "" + sf_strU2 + f_IN);
+        test("92true", "" + sf_strU2 + sf_bl);
+        test("925500", "" + sf_strU2 + sf_s);
+        test("92-2900", "" + sf_strU2 + s_sM);
+        test("92-194313216", "" + sf_strU2 + sf_l);
+        test("9212", "" + sf_strU2 + s_strU1);
+        test("92C(87)", "" + sf_strU2 + sf_o);
+        test("9291", "" + sf_strU2 + s_strU2);
+        test("9221", "" + sf_strU2 + f_strU1);
+        test("9218", "" + sf_strU2 + f_strU2);
+        test("92null", "" + sf_strU2 + f_iAN);
+        test("92null", "" + sf_strU2 + s_oN);
+        test("92\u045180", "" + sf_strU2 + s_strU);
+        test("92C", "" + sf_strU2 + sf_c);
+        test("9275", "" + sf_strU2 + sf_str);
+        test("92-43", "" + sf_strU2 + s_bM);
+        test("9280", "" + sf_strU2 + sf_b);
+        test("92null", "" + sf_strU2 + s_IN);
+        test("92-52.0", "" + sf_strU2 + s_fM);
+        test("9275000000", "" + sf_strU2 + sf_i);
+        test("9244", "" + sf_strU2 + f_b);
+        test("92-1705032704", "" + sf_strU2 + sf_lM);
+        test("92null", "" + sf_strU2 + f_oAN);
+        test("9283.0", "" + sf_strU2 + f_d);
+        test("92I", "" + sf_strU2 + f_c);
+        test("9294.0", "" + sf_strU2 + f_f);
+        test("9212.0", "" + sf_strU2 + sf_d);
+        test("92-99.0", "" + sf_strU2 + f_dM);
+        test("9217.0", "" + sf_strU2 + sf_f);
+        test("92-84.0", "" + sf_strU2 + sf_dM);
+        test("9258000000", "" + sf_strU2 + f_i);
+        test("92-55000000", "" + sf_strU2 + f_iM);
+        test("921460392448", "" + sf_strU2 + f_l);
+        test("92C(70)", "" + sf_strU2 + f_o);
+        test("92\u04511", "" + sf_strU2 + sf_strU);
+        test("928000", "" + sf_strU2 + f_s);
+        test("9218", "" + sf_strU2 + s_str);
+        test("92-1000000", "" + sf_strU2 + s_iM);
+        test("921000000", "" + sf_strU2 + sf_I);
+        test("92null", "" + sf_strU2 + f_oNtS);
+        test("92false", "" + sf_strU2 + f_bl);
+        test("92null", "" + sf_strU2 + sf_iAN);
+        test("92-2000000", "" + sf_strU2 + sf_iM);
+        test("92-820130816", "" + sf_strU2 + f_lM);
+        test("92null", "" + sf_strU2 + sf_oAN);
+        test("9225000000", "" + sf_strU2 + s_I);
+        test("51-96.0", "" + sf_strU1 + s_dM);
+        test("51null", "" + sf_strU1 + s_oNtS);
+        test("51\u045176", "" + sf_strU1 + f_strU);
+        test("5192", "" + sf_strU1 + sf_strU2);
+        test("5151", "" + sf_strU1 + sf_strU1);
+        test("51null", "" + sf_strU1 + s_iAN);
+        test("51-54", "" + sf_strU1 + f_bM);
+        test("51-87.0", "" + sf_strU1 + f_fM);
+        test("51null", "" + sf_strU1 + s_oAN);
+        test("5119", "" + sf_strU1 + f_str);
+        test("51-41", "" + sf_strU1 + sf_bM);
+        test("51null", "" + sf_strU1 + sf_IN);
+        test("51T", "" + sf_strU1 + s_c);
+        test("51-42.0", "" + sf_strU1 + sf_fM);
+        test("5125", "" + sf_strU1 + s_b);
+        test("51null", "" + sf_strU1 + f_oN);
+        test("51-1410065408", "" + sf_strU1 + s_lM);
+        test("518.0", "" + sf_strU1 + s_d);
+        test("5155.0", "" + sf_strU1 + s_f);
+        test("5197000000", "" + sf_strU1 + s_i);
+        test("51-9900", "" + sf_strU1 + f_sM);
+        test("51935228928", "" + sf_strU1 + s_l);
+        test("51-8400", "" + sf_strU1 + sf_sM);
+        test("51C(82)", "" + sf_strU1 + s_o);
+        test("51null", "" + sf_strU1 + sf_oNtS);
+        test("51true", "" + sf_strU1 + s_bl);
+        test("513900", "" + sf_strU1 + s_s);
+        test("51null", "" + sf_strU1 + sf_oN);
+        test("5194000000", "" + sf_strU1 + f_I);
+        test("51null", "" + sf_strU1 + f_IN);
+        test("51true", "" + sf_strU1 + sf_bl);
+        test("515500", "" + sf_strU1 + sf_s);
+        test("51-2900", "" + sf_strU1 + s_sM);
+        test("51-194313216", "" + sf_strU1 + sf_l);
+        test("5112", "" + sf_strU1 + s_strU1);
+        test("51C(87)", "" + sf_strU1 + sf_o);
+        test("5191", "" + sf_strU1 + s_strU2);
+        test("5121", "" + sf_strU1 + f_strU1);
+        test("5118", "" + sf_strU1 + f_strU2);
+        test("51null", "" + sf_strU1 + f_iAN);
+        test("51null", "" + sf_strU1 + s_oN);
+        test("51\u045180", "" + sf_strU1 + s_strU);
+        test("51C", "" + sf_strU1 + sf_c);
+        test("5175", "" + sf_strU1 + sf_str);
+        test("51-43", "" + sf_strU1 + s_bM);
+        test("5180", "" + sf_strU1 + sf_b);
+        test("51null", "" + sf_strU1 + s_IN);
+        test("51-52.0", "" + sf_strU1 + s_fM);
+        test("5175000000", "" + sf_strU1 + sf_i);
+        test("5144", "" + sf_strU1 + f_b);
+        test("51-1705032704", "" + sf_strU1 + sf_lM);
+        test("51null", "" + sf_strU1 + f_oAN);
+        test("5183.0", "" + sf_strU1 + f_d);
+        test("51I", "" + sf_strU1 + f_c);
+        test("5194.0", "" + sf_strU1 + f_f);
+        test("5112.0", "" + sf_strU1 + sf_d);
+        test("51-99.0", "" + sf_strU1 + f_dM);
+        test("5117.0", "" + sf_strU1 + sf_f);
+        test("51-84.0", "" + sf_strU1 + sf_dM);
+        test("5158000000", "" + sf_strU1 + f_i);
+        test("51-55000000", "" + sf_strU1 + f_iM);
+        test("511460392448", "" + sf_strU1 + f_l);
+        test("51C(70)", "" + sf_strU1 + f_o);
+        test("51\u04511", "" + sf_strU1 + sf_strU);
+        test("518000", "" + sf_strU1 + f_s);
+        test("5118", "" + sf_strU1 + s_str);
+        test("51-1000000", "" + sf_strU1 + s_iM);
+        test("511000000", "" + sf_strU1 + sf_I);
+        test("51null", "" + sf_strU1 + f_oNtS);
+        test("51false", "" + sf_strU1 + f_bl);
+        test("51null", "" + sf_strU1 + sf_iAN);
+        test("51-2000000", "" + sf_strU1 + sf_iM);
+        test("51-820130816", "" + sf_strU1 + f_lM);
+        test("51null", "" + sf_strU1 + sf_oAN);
+        test("5125000000", "" + sf_strU1 + s_I);
+        test("null-96.0", "" + s_iAN + s_dM);
+        test("nullnull", "" + s_iAN + s_oNtS);
+        test("null\u045176", "" + s_iAN + f_strU);
+        test("null92", "" + s_iAN + sf_strU2);
+        test("null51", "" + s_iAN + sf_strU1);
+        test("nullnull", "" + s_iAN + s_iAN);
+        test("null-54", "" + s_iAN + f_bM);
+        test("null-87.0", "" + s_iAN + f_fM);
+        test("nullnull", "" + s_iAN + s_oAN);
+        test("null19", "" + s_iAN + f_str);
+        test("null-41", "" + s_iAN + sf_bM);
+        test("nullnull", "" + s_iAN + sf_IN);
+        test("nullT", "" + s_iAN + s_c);
+        test("null-42.0", "" + s_iAN + sf_fM);
+        test("null25", "" + s_iAN + s_b);
+        test("nullnull", "" + s_iAN + f_oN);
+        test("null-1410065408", "" + s_iAN + s_lM);
+        test("null8.0", "" + s_iAN + s_d);
+        test("null55.0", "" + s_iAN + s_f);
+        test("null97000000", "" + s_iAN + s_i);
+        test("null-9900", "" + s_iAN + f_sM);
+        test("null935228928", "" + s_iAN + s_l);
+        test("null-8400", "" + s_iAN + sf_sM);
+        test("nullC(82)", "" + s_iAN + s_o);
+        test("nullnull", "" + s_iAN + sf_oNtS);
+        test("nulltrue", "" + s_iAN + s_bl);
+        test("null3900", "" + s_iAN + s_s);
+        test("nullnull", "" + s_iAN + sf_oN);
+        test("null94000000", "" + s_iAN + f_I);
+        test("nullnull", "" + s_iAN + f_IN);
+        test("nulltrue", "" + s_iAN + sf_bl);
+        test("null5500", "" + s_iAN + sf_s);
+        test("null-2900", "" + s_iAN + s_sM);
+        test("null-194313216", "" + s_iAN + sf_l);
+        test("null12", "" + s_iAN + s_strU1);
+        test("nullC(87)", "" + s_iAN + sf_o);
+        test("null91", "" + s_iAN + s_strU2);
+        test("null21", "" + s_iAN + f_strU1);
+        test("null18", "" + s_iAN + f_strU2);
+        test("nullnull", "" + s_iAN + f_iAN);
+        test("nullnull", "" + s_iAN + s_oN);
+        test("null\u045180", "" + s_iAN + s_strU);
+        test("nullC", "" + s_iAN + sf_c);
+        test("null75", "" + s_iAN + sf_str);
+        test("null-43", "" + s_iAN + s_bM);
+        test("null80", "" + s_iAN + sf_b);
+        test("nullnull", "" + s_iAN + s_IN);
+        test("null-52.0", "" + s_iAN + s_fM);
+        test("null75000000", "" + s_iAN + sf_i);
+        test("null44", "" + s_iAN + f_b);
+        test("null-1705032704", "" + s_iAN + sf_lM);
+        test("nullnull", "" + s_iAN + f_oAN);
+        test("null83.0", "" + s_iAN + f_d);
+        test("nullI", "" + s_iAN + f_c);
+        test("null94.0", "" + s_iAN + f_f);
+        test("null12.0", "" + s_iAN + sf_d);
+        test("null-99.0", "" + s_iAN + f_dM);
+        test("null17.0", "" + s_iAN + sf_f);
+        test("null-84.0", "" + s_iAN + sf_dM);
+        test("null58000000", "" + s_iAN + f_i);
+        test("null-55000000", "" + s_iAN + f_iM);
+        test("null1460392448", "" + s_iAN + f_l);
+        test("nullC(70)", "" + s_iAN + f_o);
+        test("null\u04511", "" + s_iAN + sf_strU);
+        test("null8000", "" + s_iAN + f_s);
+        test("null18", "" + s_iAN + s_str);
+        test("null-1000000", "" + s_iAN + s_iM);
+        test("null1000000", "" + s_iAN + sf_I);
+        test("nullnull", "" + s_iAN + f_oNtS);
+        test("nullfalse", "" + s_iAN + f_bl);
+        test("nullnull", "" + s_iAN + sf_iAN);
+        test("null-2000000", "" + s_iAN + sf_iM);
+        test("null-820130816", "" + s_iAN + f_lM);
+        test("nullnull", "" + s_iAN + sf_oAN);
+        test("null25000000", "" + s_iAN + s_I);
+        test("-54-96.0", "" + f_bM + s_dM);
+        test("-54null", "" + f_bM + s_oNtS);
+        test("-54\u045176", "" + f_bM + f_strU);
+        test("-5492", "" + f_bM + sf_strU2);
+        test("-5451", "" + f_bM + sf_strU1);
+        test("-54null", "" + f_bM + s_iAN);
+        test("-54-54", "" + f_bM + f_bM);
+        test("-54-87.0", "" + f_bM + f_fM);
+        test("-54null", "" + f_bM + s_oAN);
+        test("-5419", "" + f_bM + f_str);
+        test("-54-41", "" + f_bM + sf_bM);
+        test("-54null", "" + f_bM + sf_IN);
+        test("-54T", "" + f_bM + s_c);
+        test("-54-42.0", "" + f_bM + sf_fM);
+        test("-5425", "" + f_bM + s_b);
+        test("-54null", "" + f_bM + f_oN);
+        test("-54-1410065408", "" + f_bM + s_lM);
+        test("-548.0", "" + f_bM + s_d);
+        test("-5455.0", "" + f_bM + s_f);
+        test("-5497000000", "" + f_bM + s_i);
+        test("-54-9900", "" + f_bM + f_sM);
+        test("-54935228928", "" + f_bM + s_l);
+        test("-54-8400", "" + f_bM + sf_sM);
+        test("-54C(82)", "" + f_bM + s_o);
+        test("-54null", "" + f_bM + sf_oNtS);
+        test("-54true", "" + f_bM + s_bl);
+        test("-543900", "" + f_bM + s_s);
+        test("-54null", "" + f_bM + sf_oN);
+        test("-5494000000", "" + f_bM + f_I);
+        test("-54null", "" + f_bM + f_IN);
+        test("-54true", "" + f_bM + sf_bl);
+        test("-545500", "" + f_bM + sf_s);
+        test("-54-2900", "" + f_bM + s_sM);
+        test("-54-194313216", "" + f_bM + sf_l);
+        test("-5412", "" + f_bM + s_strU1);
+        test("-54C(87)", "" + f_bM + sf_o);
+        test("-5491", "" + f_bM + s_strU2);
+        test("-5421", "" + f_bM + f_strU1);
+        test("-5418", "" + f_bM + f_strU2);
+        test("-54null", "" + f_bM + f_iAN);
+        test("-54null", "" + f_bM + s_oN);
+        test("-54\u045180", "" + f_bM + s_strU);
+        test("-54C", "" + f_bM + sf_c);
+        test("-5475", "" + f_bM + sf_str);
+        test("-54-43", "" + f_bM + s_bM);
+        test("-5480", "" + f_bM + sf_b);
+        test("-54null", "" + f_bM + s_IN);
+        test("-54-52.0", "" + f_bM + s_fM);
+        test("-5475000000", "" + f_bM + sf_i);
+        test("-5444", "" + f_bM + f_b);
+        test("-54-1705032704", "" + f_bM + sf_lM);
+        test("-54null", "" + f_bM + f_oAN);
+        test("-5483.0", "" + f_bM + f_d);
+        test("-54I", "" + f_bM + f_c);
+        test("-5494.0", "" + f_bM + f_f);
+        test("-5412.0", "" + f_bM + sf_d);
+        test("-54-99.0", "" + f_bM + f_dM);
+        test("-5417.0", "" + f_bM + sf_f);
+        test("-54-84.0", "" + f_bM + sf_dM);
+        test("-5458000000", "" + f_bM + f_i);
+        test("-54-55000000", "" + f_bM + f_iM);
+        test("-541460392448", "" + f_bM + f_l);
+        test("-54C(70)", "" + f_bM + f_o);
+        test("-54\u04511", "" + f_bM + sf_strU);
+        test("-548000", "" + f_bM + f_s);
+        test("-5418", "" + f_bM + s_str);
+        test("-54-1000000", "" + f_bM + s_iM);
+        test("-541000000", "" + f_bM + sf_I);
+        test("-54null", "" + f_bM + f_oNtS);
+        test("-54false", "" + f_bM + f_bl);
+        test("-54null", "" + f_bM + sf_iAN);
+        test("-54-2000000", "" + f_bM + sf_iM);
+        test("-54-820130816", "" + f_bM + f_lM);
+        test("-54null", "" + f_bM + sf_oAN);
+        test("-5425000000", "" + f_bM + s_I);
+        test("-87.0-96.0", "" + f_fM + s_dM);
+        test("-87.0null", "" + f_fM + s_oNtS);
+        test("-87.0\u045176", "" + f_fM + f_strU);
+        test("-87.092", "" + f_fM + sf_strU2);
+        test("-87.051", "" + f_fM + sf_strU1);
+        test("-87.0null", "" + f_fM + s_iAN);
+        test("-87.0-54", "" + f_fM + f_bM);
+        test("-87.0-87.0", "" + f_fM + f_fM);
+        test("-87.0null", "" + f_fM + s_oAN);
+        test("-87.019", "" + f_fM + f_str);
+        test("-87.0-41", "" + f_fM + sf_bM);
+        test("-87.0null", "" + f_fM + sf_IN);
+        test("-87.0T", "" + f_fM + s_c);
+        test("-87.0-42.0", "" + f_fM + sf_fM);
+        test("-87.025", "" + f_fM + s_b);
+        test("-87.0null", "" + f_fM + f_oN);
+        test("-87.0-1410065408", "" + f_fM + s_lM);
+        test("-87.08.0", "" + f_fM + s_d);
+        test("-87.055.0", "" + f_fM + s_f);
+        test("-87.097000000", "" + f_fM + s_i);
+        test("-87.0-9900", "" + f_fM + f_sM);
+        test("-87.0935228928", "" + f_fM + s_l);
+        test("-87.0-8400", "" + f_fM + sf_sM);
+        test("-87.0C(82)", "" + f_fM + s_o);
+        test("-87.0null", "" + f_fM + sf_oNtS);
+        test("-87.0true", "" + f_fM + s_bl);
+        test("-87.03900", "" + f_fM + s_s);
+        test("-87.0null", "" + f_fM + sf_oN);
+        test("-87.094000000", "" + f_fM + f_I);
+        test("-87.0null", "" + f_fM + f_IN);
+        test("-87.0true", "" + f_fM + sf_bl);
+        test("-87.05500", "" + f_fM + sf_s);
+        test("-87.0-2900", "" + f_fM + s_sM);
+        test("-87.0-194313216", "" + f_fM + sf_l);
+        test("-87.012", "" + f_fM + s_strU1);
+        test("-87.0C(87)", "" + f_fM + sf_o);
+        test("-87.091", "" + f_fM + s_strU2);
+        test("-87.021", "" + f_fM + f_strU1);
+        test("-87.018", "" + f_fM + f_strU2);
+        test("-87.0null", "" + f_fM + f_iAN);
+        test("-87.0null", "" + f_fM + s_oN);
+        test("-87.0\u045180", "" + f_fM + s_strU);
+        test("-87.0C", "" + f_fM + sf_c);
+        test("-87.075", "" + f_fM + sf_str);
+        test("-87.0-43", "" + f_fM + s_bM);
+        test("-87.080", "" + f_fM + sf_b);
+        test("-87.0null", "" + f_fM + s_IN);
+        test("-87.0-52.0", "" + f_fM + s_fM);
+        test("-87.075000000", "" + f_fM + sf_i);
+        test("-87.044", "" + f_fM + f_b);
+        test("-87.0-1705032704", "" + f_fM + sf_lM);
+        test("-87.0null", "" + f_fM + f_oAN);
+        test("-87.083.0", "" + f_fM + f_d);
+        test("-87.0I", "" + f_fM + f_c);
+        test("-87.094.0", "" + f_fM + f_f);
+        test("-87.012.0", "" + f_fM + sf_d);
+        test("-87.0-99.0", "" + f_fM + f_dM);
+        test("-87.017.0", "" + f_fM + sf_f);
+        test("-87.0-84.0", "" + f_fM + sf_dM);
+        test("-87.058000000", "" + f_fM + f_i);
+        test("-87.0-55000000", "" + f_fM + f_iM);
+        test("-87.01460392448", "" + f_fM + f_l);
+        test("-87.0C(70)", "" + f_fM + f_o);
+        test("-87.0\u04511", "" + f_fM + sf_strU);
+        test("-87.08000", "" + f_fM + f_s);
+        test("-87.018", "" + f_fM + s_str);
+        test("-87.0-1000000", "" + f_fM + s_iM);
+        test("-87.01000000", "" + f_fM + sf_I);
+        test("-87.0null", "" + f_fM + f_oNtS);
+        test("-87.0false", "" + f_fM + f_bl);
+        test("-87.0null", "" + f_fM + sf_iAN);
+        test("-87.0-2000000", "" + f_fM + sf_iM);
+        test("-87.0-820130816", "" + f_fM + f_lM);
+        test("-87.0null", "" + f_fM + sf_oAN);
+        test("-87.025000000", "" + f_fM + s_I);
+        test("null-96.0", "" + s_oAN + s_dM);
+        test("nullnull", "" + s_oAN + s_oNtS);
+        test("null\u045176", "" + s_oAN + f_strU);
+        test("null92", "" + s_oAN + sf_strU2);
+        test("null51", "" + s_oAN + sf_strU1);
+        test("nullnull", "" + s_oAN + s_iAN);
+        test("null-54", "" + s_oAN + f_bM);
+        test("null-87.0", "" + s_oAN + f_fM);
+        test("nullnull", "" + s_oAN + s_oAN);
+        test("null19", "" + s_oAN + f_str);
+        test("null-41", "" + s_oAN + sf_bM);
+        test("nullnull", "" + s_oAN + sf_IN);
+        test("nullT", "" + s_oAN + s_c);
+        test("null-42.0", "" + s_oAN + sf_fM);
+        test("null25", "" + s_oAN + s_b);
+        test("nullnull", "" + s_oAN + f_oN);
+        test("null-1410065408", "" + s_oAN + s_lM);
+        test("null8.0", "" + s_oAN + s_d);
+        test("null55.0", "" + s_oAN + s_f);
+        test("null97000000", "" + s_oAN + s_i);
+        test("null-9900", "" + s_oAN + f_sM);
+        test("null935228928", "" + s_oAN + s_l);
+        test("null-8400", "" + s_oAN + sf_sM);
+        test("nullC(82)", "" + s_oAN + s_o);
+        test("nullnull", "" + s_oAN + sf_oNtS);
+        test("nulltrue", "" + s_oAN + s_bl);
+        test("null3900", "" + s_oAN + s_s);
+        test("nullnull", "" + s_oAN + sf_oN);
+        test("null94000000", "" + s_oAN + f_I);
+        test("nullnull", "" + s_oAN + f_IN);
+        test("nulltrue", "" + s_oAN + sf_bl);
+        test("null5500", "" + s_oAN + sf_s);
+        test("null-2900", "" + s_oAN + s_sM);
+        test("null-194313216", "" + s_oAN + sf_l);
+        test("null12", "" + s_oAN + s_strU1);
+        test("nullC(87)", "" + s_oAN + sf_o);
+        test("null91", "" + s_oAN + s_strU2);
+        test("null21", "" + s_oAN + f_strU1);
+        test("null18", "" + s_oAN + f_strU2);
+        test("nullnull", "" + s_oAN + f_iAN);
+        test("nullnull", "" + s_oAN + s_oN);
+        test("null\u045180", "" + s_oAN + s_strU);
+        test("nullC", "" + s_oAN + sf_c);
+        test("null75", "" + s_oAN + sf_str);
+        test("null-43", "" + s_oAN + s_bM);
+        test("null80", "" + s_oAN + sf_b);
+        test("nullnull", "" + s_oAN + s_IN);
+        test("null-52.0", "" + s_oAN + s_fM);
+        test("null75000000", "" + s_oAN + sf_i);
+        test("null44", "" + s_oAN + f_b);
+        test("null-1705032704", "" + s_oAN + sf_lM);
+        test("nullnull", "" + s_oAN + f_oAN);
+        test("null83.0", "" + s_oAN + f_d);
+        test("nullI", "" + s_oAN + f_c);
+        test("null94.0", "" + s_oAN + f_f);
+        test("null12.0", "" + s_oAN + sf_d);
+        test("null-99.0", "" + s_oAN + f_dM);
+        test("null17.0", "" + s_oAN + sf_f);
+        test("null-84.0", "" + s_oAN + sf_dM);
+        test("null58000000", "" + s_oAN + f_i);
+        test("null-55000000", "" + s_oAN + f_iM);
+        test("null1460392448", "" + s_oAN + f_l);
+        test("nullC(70)", "" + s_oAN + f_o);
+        test("null\u04511", "" + s_oAN + sf_strU);
+        test("null8000", "" + s_oAN + f_s);
+        test("null18", "" + s_oAN + s_str);
+        test("null-1000000", "" + s_oAN + s_iM);
+        test("null1000000", "" + s_oAN + sf_I);
+        test("nullnull", "" + s_oAN + f_oNtS);
+        test("nullfalse", "" + s_oAN + f_bl);
+        test("nullnull", "" + s_oAN + sf_iAN);
+        test("null-2000000", "" + s_oAN + sf_iM);
+        test("null-820130816", "" + s_oAN + f_lM);
+        test("nullnull", "" + s_oAN + sf_oAN);
+        test("null25000000", "" + s_oAN + s_I);
+        test("19-96.0", "" + f_str + s_dM);
+        test("19null", "" + f_str + s_oNtS);
+        test("19\u045176", "" + f_str + f_strU);
+        test("1992", "" + f_str + sf_strU2);
+        test("1951", "" + f_str + sf_strU1);
+        test("19null", "" + f_str + s_iAN);
+        test("19-54", "" + f_str + f_bM);
+        test("19-87.0", "" + f_str + f_fM);
+        test("19null", "" + f_str + s_oAN);
+        test("1919", "" + f_str + f_str);
+        test("19-41", "" + f_str + sf_bM);
+        test("19null", "" + f_str + sf_IN);
+        test("19T", "" + f_str + s_c);
+        test("19-42.0", "" + f_str + sf_fM);
+        test("1925", "" + f_str + s_b);
+        test("19null", "" + f_str + f_oN);
+        test("19-1410065408", "" + f_str + s_lM);
+        test("198.0", "" + f_str + s_d);
+        test("1955.0", "" + f_str + s_f);
+        test("1997000000", "" + f_str + s_i);
+        test("19-9900", "" + f_str + f_sM);
+        test("19935228928", "" + f_str + s_l);
+        test("19-8400", "" + f_str + sf_sM);
+        test("19C(82)", "" + f_str + s_o);
+        test("19null", "" + f_str + sf_oNtS);
+        test("19true", "" + f_str + s_bl);
+        test("193900", "" + f_str + s_s);
+        test("19null", "" + f_str + sf_oN);
+        test("1994000000", "" + f_str + f_I);
+        test("19null", "" + f_str + f_IN);
+        test("19true", "" + f_str + sf_bl);
+        test("195500", "" + f_str + sf_s);
+        test("19-2900", "" + f_str + s_sM);
+        test("19-194313216", "" + f_str + sf_l);
+        test("1912", "" + f_str + s_strU1);
+        test("19C(87)", "" + f_str + sf_o);
+        test("1991", "" + f_str + s_strU2);
+        test("1921", "" + f_str + f_strU1);
+        test("1918", "" + f_str + f_strU2);
+        test("19null", "" + f_str + f_iAN);
+        test("19null", "" + f_str + s_oN);
+        test("19\u045180", "" + f_str + s_strU);
+        test("19C", "" + f_str + sf_c);
+        test("1975", "" + f_str + sf_str);
+        test("19-43", "" + f_str + s_bM);
+        test("1980", "" + f_str + sf_b);
+        test("19null", "" + f_str + s_IN);
+        test("19-52.0", "" + f_str + s_fM);
+        test("1975000000", "" + f_str + sf_i);
+        test("1944", "" + f_str + f_b);
+        test("19-1705032704", "" + f_str + sf_lM);
+        test("19null", "" + f_str + f_oAN);
+        test("1983.0", "" + f_str + f_d);
+        test("19I", "" + f_str + f_c);
+        test("1994.0", "" + f_str + f_f);
+        test("1912.0", "" + f_str + sf_d);
+        test("19-99.0", "" + f_str + f_dM);
+        test("1917.0", "" + f_str + sf_f);
+        test("19-84.0", "" + f_str + sf_dM);
+        test("1958000000", "" + f_str + f_i);
+        test("19-55000000", "" + f_str + f_iM);
+        test("191460392448", "" + f_str + f_l);
+        test("19C(70)", "" + f_str + f_o);
+        test("19\u04511", "" + f_str + sf_strU);
+        test("198000", "" + f_str + f_s);
+        test("1918", "" + f_str + s_str);
+        test("19-1000000", "" + f_str + s_iM);
+        test("191000000", "" + f_str + sf_I);
+        test("19null", "" + f_str + f_oNtS);
+        test("19false", "" + f_str + f_bl);
+        test("19null", "" + f_str + sf_iAN);
+        test("19-2000000", "" + f_str + sf_iM);
+        test("19-820130816", "" + f_str + f_lM);
+        test("19null", "" + f_str + sf_oAN);
+        test("1925000000", "" + f_str + s_I);
+        test("-41-96.0", "" + sf_bM + s_dM);
+        test("-41null", "" + sf_bM + s_oNtS);
+        test("-41\u045176", "" + sf_bM + f_strU);
+        test("-4192", "" + sf_bM + sf_strU2);
+        test("-4151", "" + sf_bM + sf_strU1);
+        test("-41null", "" + sf_bM + s_iAN);
+        test("-41-54", "" + sf_bM + f_bM);
+        test("-41-87.0", "" + sf_bM + f_fM);
+        test("-41null", "" + sf_bM + s_oAN);
+        test("-4119", "" + sf_bM + f_str);
+        test("-41-41", "" + sf_bM + sf_bM);
+        test("-41null", "" + sf_bM + sf_IN);
+        test("-41T", "" + sf_bM + s_c);
+        test("-41-42.0", "" + sf_bM + sf_fM);
+        test("-4125", "" + sf_bM + s_b);
+        test("-41null", "" + sf_bM + f_oN);
+        test("-41-1410065408", "" + sf_bM + s_lM);
+        test("-418.0", "" + sf_bM + s_d);
+        test("-4155.0", "" + sf_bM + s_f);
+        test("-4197000000", "" + sf_bM + s_i);
+        test("-41-9900", "" + sf_bM + f_sM);
+        test("-41935228928", "" + sf_bM + s_l);
+        test("-41-8400", "" + sf_bM + sf_sM);
+        test("-41C(82)", "" + sf_bM + s_o);
+        test("-41null", "" + sf_bM + sf_oNtS);
+        test("-41true", "" + sf_bM + s_bl);
+        test("-413900", "" + sf_bM + s_s);
+        test("-41null", "" + sf_bM + sf_oN);
+        test("-4194000000", "" + sf_bM + f_I);
+        test("-41null", "" + sf_bM + f_IN);
+        test("-41true", "" + sf_bM + sf_bl);
+        test("-415500", "" + sf_bM + sf_s);
+        test("-41-2900", "" + sf_bM + s_sM);
+        test("-41-194313216", "" + sf_bM + sf_l);
+        test("-4112", "" + sf_bM + s_strU1);
+        test("-41C(87)", "" + sf_bM + sf_o);
+        test("-4191", "" + sf_bM + s_strU2);
+        test("-4121", "" + sf_bM + f_strU1);
+        test("-4118", "" + sf_bM + f_strU2);
+        test("-41null", "" + sf_bM + f_iAN);
+        test("-41null", "" + sf_bM + s_oN);
+        test("-41\u045180", "" + sf_bM + s_strU);
+        test("-41C", "" + sf_bM + sf_c);
+        test("-4175", "" + sf_bM + sf_str);
+        test("-41-43", "" + sf_bM + s_bM);
+        test("-4180", "" + sf_bM + sf_b);
+        test("-41null", "" + sf_bM + s_IN);
+        test("-41-52.0", "" + sf_bM + s_fM);
+        test("-4175000000", "" + sf_bM + sf_i);
+        test("-4144", "" + sf_bM + f_b);
+        test("-41-1705032704", "" + sf_bM + sf_lM);
+        test("-41null", "" + sf_bM + f_oAN);
+        test("-4183.0", "" + sf_bM + f_d);
+        test("-41I", "" + sf_bM + f_c);
+        test("-4194.0", "" + sf_bM + f_f);
+        test("-4112.0", "" + sf_bM + sf_d);
+        test("-41-99.0", "" + sf_bM + f_dM);
+        test("-4117.0", "" + sf_bM + sf_f);
+        test("-41-84.0", "" + sf_bM + sf_dM);
+        test("-4158000000", "" + sf_bM + f_i);
+        test("-41-55000000", "" + sf_bM + f_iM);
+        test("-411460392448", "" + sf_bM + f_l);
+        test("-41C(70)", "" + sf_bM + f_o);
+        test("-41\u04511", "" + sf_bM + sf_strU);
+        test("-418000", "" + sf_bM + f_s);
+        test("-4118", "" + sf_bM + s_str);
+        test("-41-1000000", "" + sf_bM + s_iM);
+        test("-411000000", "" + sf_bM + sf_I);
+        test("-41null", "" + sf_bM + f_oNtS);
+        test("-41false", "" + sf_bM + f_bl);
+        test("-41null", "" + sf_bM + sf_iAN);
+        test("-41-2000000", "" + sf_bM + sf_iM);
+        test("-41-820130816", "" + sf_bM + f_lM);
+        test("-41null", "" + sf_bM + sf_oAN);
+        test("-4125000000", "" + sf_bM + s_I);
+        test("null-96.0", "" + sf_IN + s_dM);
+        test("nullnull", "" + sf_IN + s_oNtS);
+        test("null\u045176", "" + sf_IN + f_strU);
+        test("null92", "" + sf_IN + sf_strU2);
+        test("null51", "" + sf_IN + sf_strU1);
+        test("nullnull", "" + sf_IN + s_iAN);
+        test("null-54", "" + sf_IN + f_bM);
+        test("null-87.0", "" + sf_IN + f_fM);
+        test("nullnull", "" + sf_IN + s_oAN);
+        test("null19", "" + sf_IN + f_str);
+        test("null-41", "" + sf_IN + sf_bM);
+        test("nullnull", "" + sf_IN + sf_IN);
+        test("nullT", "" + sf_IN + s_c);
+        test("null-42.0", "" + sf_IN + sf_fM);
+        test("null25", "" + sf_IN + s_b);
+        test("nullnull", "" + sf_IN + f_oN);
+        test("null-1410065408", "" + sf_IN + s_lM);
+        test("null8.0", "" + sf_IN + s_d);
+        test("null55.0", "" + sf_IN + s_f);
+        test("null97000000", "" + sf_IN + s_i);
+        test("null-9900", "" + sf_IN + f_sM);
+        test("null935228928", "" + sf_IN + s_l);
+        test("null-8400", "" + sf_IN + sf_sM);
+        test("nullC(82)", "" + sf_IN + s_o);
+        test("nullnull", "" + sf_IN + sf_oNtS);
+        test("nulltrue", "" + sf_IN + s_bl);
+        test("null3900", "" + sf_IN + s_s);
+        test("nullnull", "" + sf_IN + sf_oN);
+        test("null94000000", "" + sf_IN + f_I);
+        test("nullnull", "" + sf_IN + f_IN);
+        test("nulltrue", "" + sf_IN + sf_bl);
+        test("null5500", "" + sf_IN + sf_s);
+        test("null-2900", "" + sf_IN + s_sM);
+        test("null-194313216", "" + sf_IN + sf_l);
+        test("null12", "" + sf_IN + s_strU1);
+        test("nullC(87)", "" + sf_IN + sf_o);
+        test("null91", "" + sf_IN + s_strU2);
+        test("null21", "" + sf_IN + f_strU1);
+        test("null18", "" + sf_IN + f_strU2);
+        test("nullnull", "" + sf_IN + f_iAN);
+        test("nullnull", "" + sf_IN + s_oN);
+        test("null\u045180", "" + sf_IN + s_strU);
+        test("nullC", "" + sf_IN + sf_c);
+        test("null75", "" + sf_IN + sf_str);
+        test("null-43", "" + sf_IN + s_bM);
+        test("null80", "" + sf_IN + sf_b);
+        test("nullnull", "" + sf_IN + s_IN);
+        test("null-52.0", "" + sf_IN + s_fM);
+        test("null75000000", "" + sf_IN + sf_i);
+        test("null44", "" + sf_IN + f_b);
+        test("null-1705032704", "" + sf_IN + sf_lM);
+        test("nullnull", "" + sf_IN + f_oAN);
+        test("null83.0", "" + sf_IN + f_d);
+        test("nullI", "" + sf_IN + f_c);
+        test("null94.0", "" + sf_IN + f_f);
+        test("null12.0", "" + sf_IN + sf_d);
+        test("null-99.0", "" + sf_IN + f_dM);
+        test("null17.0", "" + sf_IN + sf_f);
+        test("null-84.0", "" + sf_IN + sf_dM);
+        test("null58000000", "" + sf_IN + f_i);
+        test("null-55000000", "" + sf_IN + f_iM);
+        test("null1460392448", "" + sf_IN + f_l);
+        test("nullC(70)", "" + sf_IN + f_o);
+        test("null\u04511", "" + sf_IN + sf_strU);
+        test("null8000", "" + sf_IN + f_s);
+        test("null18", "" + sf_IN + s_str);
+        test("null-1000000", "" + sf_IN + s_iM);
+        test("null1000000", "" + sf_IN + sf_I);
+        test("nullnull", "" + sf_IN + f_oNtS);
+        test("nullfalse", "" + sf_IN + f_bl);
+        test("nullnull", "" + sf_IN + sf_iAN);
+        test("null-2000000", "" + sf_IN + sf_iM);
+        test("null-820130816", "" + sf_IN + f_lM);
+        test("nullnull", "" + sf_IN + sf_oAN);
+        test("null25000000", "" + sf_IN + s_I);
+        test("T-96.0", "" + s_c + s_dM);
+        test("Tnull", "" + s_c + s_oNtS);
+        test("T\u045176", "" + s_c + f_strU);
+        test("T92", "" + s_c + sf_strU2);
+        test("T51", "" + s_c + sf_strU1);
+        test("Tnull", "" + s_c + s_iAN);
+        test("T-54", "" + s_c + f_bM);
+        test("T-87.0", "" + s_c + f_fM);
+        test("Tnull", "" + s_c + s_oAN);
+        test("T19", "" + s_c + f_str);
+        test("T-41", "" + s_c + sf_bM);
+        test("Tnull", "" + s_c + sf_IN);
+        test("TT", "" + s_c + s_c);
+        test("T-42.0", "" + s_c + sf_fM);
+        test("T25", "" + s_c + s_b);
+        test("Tnull", "" + s_c + f_oN);
+        test("T-1410065408", "" + s_c + s_lM);
+        test("T8.0", "" + s_c + s_d);
+        test("T55.0", "" + s_c + s_f);
+        test("T97000000", "" + s_c + s_i);
+        test("T-9900", "" + s_c + f_sM);
+        test("T935228928", "" + s_c + s_l);
+        test("T-8400", "" + s_c + sf_sM);
+        test("TC(82)", "" + s_c + s_o);
+        test("Tnull", "" + s_c + sf_oNtS);
+    }
+
+    public void run1() {
+        test("Ttrue", "" + s_c + s_bl);
+        test("T3900", "" + s_c + s_s);
+        test("Tnull", "" + s_c + sf_oN);
+        test("T94000000", "" + s_c + f_I);
+        test("Tnull", "" + s_c + f_IN);
+        test("Ttrue", "" + s_c + sf_bl);
+        test("T5500", "" + s_c + sf_s);
+        test("T-2900", "" + s_c + s_sM);
+        test("T-194313216", "" + s_c + sf_l);
+        test("T12", "" + s_c + s_strU1);
+        test("TC(87)", "" + s_c + sf_o);
+        test("T91", "" + s_c + s_strU2);
+        test("T21", "" + s_c + f_strU1);
+        test("T18", "" + s_c + f_strU2);
+        test("Tnull", "" + s_c + f_iAN);
+        test("Tnull", "" + s_c + s_oN);
+        test("T\u045180", "" + s_c + s_strU);
+        test("TC", "" + s_c + sf_c);
+        test("T75", "" + s_c + sf_str);
+        test("T-43", "" + s_c + s_bM);
+        test("T80", "" + s_c + sf_b);
+        test("Tnull", "" + s_c + s_IN);
+        test("T-52.0", "" + s_c + s_fM);
+        test("T75000000", "" + s_c + sf_i);
+        test("T44", "" + s_c + f_b);
+        test("T-1705032704", "" + s_c + sf_lM);
+        test("Tnull", "" + s_c + f_oAN);
+        test("T83.0", "" + s_c + f_d);
+        test("TI", "" + s_c + f_c);
+        test("T94.0", "" + s_c + f_f);
+        test("T12.0", "" + s_c + sf_d);
+        test("T-99.0", "" + s_c + f_dM);
+        test("T17.0", "" + s_c + sf_f);
+        test("T-84.0", "" + s_c + sf_dM);
+        test("T58000000", "" + s_c + f_i);
+        test("T-55000000", "" + s_c + f_iM);
+        test("T1460392448", "" + s_c + f_l);
+        test("TC(70)", "" + s_c + f_o);
+        test("T\u04511", "" + s_c + sf_strU);
+        test("T8000", "" + s_c + f_s);
+        test("T18", "" + s_c + s_str);
+        test("T-1000000", "" + s_c + s_iM);
+        test("T1000000", "" + s_c + sf_I);
+        test("Tnull", "" + s_c + f_oNtS);
+        test("Tfalse", "" + s_c + f_bl);
+        test("Tnull", "" + s_c + sf_iAN);
+        test("T-2000000", "" + s_c + sf_iM);
+        test("T-820130816", "" + s_c + f_lM);
+        test("Tnull", "" + s_c + sf_oAN);
+        test("T25000000", "" + s_c + s_I);
+        test("-42.0-96.0", "" + sf_fM + s_dM);
+        test("-42.0null", "" + sf_fM + s_oNtS);
+        test("-42.0\u045176", "" + sf_fM + f_strU);
+        test("-42.092", "" + sf_fM + sf_strU2);
+        test("-42.051", "" + sf_fM + sf_strU1);
+        test("-42.0null", "" + sf_fM + s_iAN);
+        test("-42.0-54", "" + sf_fM + f_bM);
+        test("-42.0-87.0", "" + sf_fM + f_fM);
+        test("-42.0null", "" + sf_fM + s_oAN);
+        test("-42.019", "" + sf_fM + f_str);
+        test("-42.0-41", "" + sf_fM + sf_bM);
+        test("-42.0null", "" + sf_fM + sf_IN);
+        test("-42.0T", "" + sf_fM + s_c);
+        test("-42.0-42.0", "" + sf_fM + sf_fM);
+        test("-42.025", "" + sf_fM + s_b);
+        test("-42.0null", "" + sf_fM + f_oN);
+        test("-42.0-1410065408", "" + sf_fM + s_lM);
+        test("-42.08.0", "" + sf_fM + s_d);
+        test("-42.055.0", "" + sf_fM + s_f);
+        test("-42.097000000", "" + sf_fM + s_i);
+        test("-42.0-9900", "" + sf_fM + f_sM);
+        test("-42.0935228928", "" + sf_fM + s_l);
+        test("-42.0-8400", "" + sf_fM + sf_sM);
+        test("-42.0C(82)", "" + sf_fM + s_o);
+        test("-42.0null", "" + sf_fM + sf_oNtS);
+        test("-42.0true", "" + sf_fM + s_bl);
+        test("-42.03900", "" + sf_fM + s_s);
+        test("-42.0null", "" + sf_fM + sf_oN);
+        test("-42.094000000", "" + sf_fM + f_I);
+        test("-42.0null", "" + sf_fM + f_IN);
+        test("-42.0true", "" + sf_fM + sf_bl);
+        test("-42.05500", "" + sf_fM + sf_s);
+        test("-42.0-2900", "" + sf_fM + s_sM);
+        test("-42.0-194313216", "" + sf_fM + sf_l);
+        test("-42.012", "" + sf_fM + s_strU1);
+        test("-42.0C(87)", "" + sf_fM + sf_o);
+        test("-42.091", "" + sf_fM + s_strU2);
+        test("-42.021", "" + sf_fM + f_strU1);
+        test("-42.018", "" + sf_fM + f_strU2);
+        test("-42.0null", "" + sf_fM + f_iAN);
+        test("-42.0null", "" + sf_fM + s_oN);
+        test("-42.0\u045180", "" + sf_fM + s_strU);
+        test("-42.0C", "" + sf_fM + sf_c);
+        test("-42.075", "" + sf_fM + sf_str);
+        test("-42.0-43", "" + sf_fM + s_bM);
+        test("-42.080", "" + sf_fM + sf_b);
+        test("-42.0null", "" + sf_fM + s_IN);
+        test("-42.0-52.0", "" + sf_fM + s_fM);
+        test("-42.075000000", "" + sf_fM + sf_i);
+        test("-42.044", "" + sf_fM + f_b);
+        test("-42.0-1705032704", "" + sf_fM + sf_lM);
+        test("-42.0null", "" + sf_fM + f_oAN);
+        test("-42.083.0", "" + sf_fM + f_d);
+        test("-42.0I", "" + sf_fM + f_c);
+        test("-42.094.0", "" + sf_fM + f_f);
+        test("-42.012.0", "" + sf_fM + sf_d);
+        test("-42.0-99.0", "" + sf_fM + f_dM);
+        test("-42.017.0", "" + sf_fM + sf_f);
+        test("-42.0-84.0", "" + sf_fM + sf_dM);
+        test("-42.058000000", "" + sf_fM + f_i);
+        test("-42.0-55000000", "" + sf_fM + f_iM);
+        test("-42.01460392448", "" + sf_fM + f_l);
+        test("-42.0C(70)", "" + sf_fM + f_o);
+        test("-42.0\u04511", "" + sf_fM + sf_strU);
+        test("-42.08000", "" + sf_fM + f_s);
+        test("-42.018", "" + sf_fM + s_str);
+        test("-42.0-1000000", "" + sf_fM + s_iM);
+        test("-42.01000000", "" + sf_fM + sf_I);
+        test("-42.0null", "" + sf_fM + f_oNtS);
+        test("-42.0false", "" + sf_fM + f_bl);
+        test("-42.0null", "" + sf_fM + sf_iAN);
+        test("-42.0-2000000", "" + sf_fM + sf_iM);
+        test("-42.0-820130816", "" + sf_fM + f_lM);
+        test("-42.0null", "" + sf_fM + sf_oAN);
+        test("-42.025000000", "" + sf_fM + s_I);
+        test("25-96.0", "" + s_b + s_dM);
+        test("25null", "" + s_b + s_oNtS);
+        test("25\u045176", "" + s_b + f_strU);
+        test("2592", "" + s_b + sf_strU2);
+        test("2551", "" + s_b + sf_strU1);
+        test("25null", "" + s_b + s_iAN);
+        test("25-54", "" + s_b + f_bM);
+        test("25-87.0", "" + s_b + f_fM);
+        test("25null", "" + s_b + s_oAN);
+        test("2519", "" + s_b + f_str);
+        test("25-41", "" + s_b + sf_bM);
+        test("25null", "" + s_b + sf_IN);
+        test("25T", "" + s_b + s_c);
+        test("25-42.0", "" + s_b + sf_fM);
+        test("2525", "" + s_b + s_b);
+        test("25null", "" + s_b + f_oN);
+        test("25-1410065408", "" + s_b + s_lM);
+        test("258.0", "" + s_b + s_d);
+        test("2555.0", "" + s_b + s_f);
+        test("2597000000", "" + s_b + s_i);
+        test("25-9900", "" + s_b + f_sM);
+        test("25935228928", "" + s_b + s_l);
+        test("25-8400", "" + s_b + sf_sM);
+        test("25C(82)", "" + s_b + s_o);
+        test("25null", "" + s_b + sf_oNtS);
+        test("25true", "" + s_b + s_bl);
+        test("253900", "" + s_b + s_s);
+        test("25null", "" + s_b + sf_oN);
+        test("2594000000", "" + s_b + f_I);
+        test("25null", "" + s_b + f_IN);
+        test("25true", "" + s_b + sf_bl);
+        test("255500", "" + s_b + sf_s);
+        test("25-2900", "" + s_b + s_sM);
+        test("25-194313216", "" + s_b + sf_l);
+        test("2512", "" + s_b + s_strU1);
+        test("25C(87)", "" + s_b + sf_o);
+        test("2591", "" + s_b + s_strU2);
+        test("2521", "" + s_b + f_strU1);
+        test("2518", "" + s_b + f_strU2);
+        test("25null", "" + s_b + f_iAN);
+        test("25null", "" + s_b + s_oN);
+        test("25\u045180", "" + s_b + s_strU);
+        test("25C", "" + s_b + sf_c);
+        test("2575", "" + s_b + sf_str);
+        test("25-43", "" + s_b + s_bM);
+        test("2580", "" + s_b + sf_b);
+        test("25null", "" + s_b + s_IN);
+        test("25-52.0", "" + s_b + s_fM);
+        test("2575000000", "" + s_b + sf_i);
+        test("2544", "" + s_b + f_b);
+        test("25-1705032704", "" + s_b + sf_lM);
+        test("25null", "" + s_b + f_oAN);
+        test("2583.0", "" + s_b + f_d);
+        test("25I", "" + s_b + f_c);
+        test("2594.0", "" + s_b + f_f);
+        test("2512.0", "" + s_b + sf_d);
+        test("25-99.0", "" + s_b + f_dM);
+        test("2517.0", "" + s_b + sf_f);
+        test("25-84.0", "" + s_b + sf_dM);
+        test("2558000000", "" + s_b + f_i);
+        test("25-55000000", "" + s_b + f_iM);
+        test("251460392448", "" + s_b + f_l);
+        test("25C(70)", "" + s_b + f_o);
+        test("25\u04511", "" + s_b + sf_strU);
+        test("258000", "" + s_b + f_s);
+        test("2518", "" + s_b + s_str);
+        test("25-1000000", "" + s_b + s_iM);
+        test("251000000", "" + s_b + sf_I);
+        test("25null", "" + s_b + f_oNtS);
+        test("25false", "" + s_b + f_bl);
+        test("25null", "" + s_b + sf_iAN);
+        test("25-2000000", "" + s_b + sf_iM);
+        test("25-820130816", "" + s_b + f_lM);
+        test("25null", "" + s_b + sf_oAN);
+        test("2525000000", "" + s_b + s_I);
+        test("null-96.0", "" + f_oN + s_dM);
+        test("nullnull", "" + f_oN + s_oNtS);
+        test("null\u045176", "" + f_oN + f_strU);
+        test("null92", "" + f_oN + sf_strU2);
+        test("null51", "" + f_oN + sf_strU1);
+        test("nullnull", "" + f_oN + s_iAN);
+        test("null-54", "" + f_oN + f_bM);
+        test("null-87.0", "" + f_oN + f_fM);
+        test("nullnull", "" + f_oN + s_oAN);
+        test("null19", "" + f_oN + f_str);
+        test("null-41", "" + f_oN + sf_bM);
+        test("nullnull", "" + f_oN + sf_IN);
+        test("nullT", "" + f_oN + s_c);
+        test("null-42.0", "" + f_oN + sf_fM);
+        test("null25", "" + f_oN + s_b);
+        test("nullnull", "" + f_oN + f_oN);
+        test("null-1410065408", "" + f_oN + s_lM);
+        test("null8.0", "" + f_oN + s_d);
+        test("null55.0", "" + f_oN + s_f);
+        test("null97000000", "" + f_oN + s_i);
+        test("null-9900", "" + f_oN + f_sM);
+        test("null935228928", "" + f_oN + s_l);
+        test("null-8400", "" + f_oN + sf_sM);
+        test("nullC(82)", "" + f_oN + s_o);
+        test("nullnull", "" + f_oN + sf_oNtS);
+        test("nulltrue", "" + f_oN + s_bl);
+        test("null3900", "" + f_oN + s_s);
+        test("nullnull", "" + f_oN + sf_oN);
+        test("null94000000", "" + f_oN + f_I);
+        test("nullnull", "" + f_oN + f_IN);
+        test("nulltrue", "" + f_oN + sf_bl);
+        test("null5500", "" + f_oN + sf_s);
+        test("null-2900", "" + f_oN + s_sM);
+        test("null-194313216", "" + f_oN + sf_l);
+        test("null12", "" + f_oN + s_strU1);
+        test("nullC(87)", "" + f_oN + sf_o);
+        test("null91", "" + f_oN + s_strU2);
+        test("null21", "" + f_oN + f_strU1);
+        test("null18", "" + f_oN + f_strU2);
+        test("nullnull", "" + f_oN + f_iAN);
+        test("nullnull", "" + f_oN + s_oN);
+        test("null\u045180", "" + f_oN + s_strU);
+        test("nullC", "" + f_oN + sf_c);
+        test("null75", "" + f_oN + sf_str);
+        test("null-43", "" + f_oN + s_bM);
+        test("null80", "" + f_oN + sf_b);
+        test("nullnull", "" + f_oN + s_IN);
+        test("null-52.0", "" + f_oN + s_fM);
+        test("null75000000", "" + f_oN + sf_i);
+        test("null44", "" + f_oN + f_b);
+        test("null-1705032704", "" + f_oN + sf_lM);
+        test("nullnull", "" + f_oN + f_oAN);
+        test("null83.0", "" + f_oN + f_d);
+        test("nullI", "" + f_oN + f_c);
+        test("null94.0", "" + f_oN + f_f);
+        test("null12.0", "" + f_oN + sf_d);
+        test("null-99.0", "" + f_oN + f_dM);
+        test("null17.0", "" + f_oN + sf_f);
+        test("null-84.0", "" + f_oN + sf_dM);
+        test("null58000000", "" + f_oN + f_i);
+        test("null-55000000", "" + f_oN + f_iM);
+        test("null1460392448", "" + f_oN + f_l);
+        test("nullC(70)", "" + f_oN + f_o);
+        test("null\u04511", "" + f_oN + sf_strU);
+        test("null8000", "" + f_oN + f_s);
+        test("null18", "" + f_oN + s_str);
+        test("null-1000000", "" + f_oN + s_iM);
+        test("null1000000", "" + f_oN + sf_I);
+        test("nullnull", "" + f_oN + f_oNtS);
+        test("nullfalse", "" + f_oN + f_bl);
+        test("nullnull", "" + f_oN + sf_iAN);
+        test("null-2000000", "" + f_oN + sf_iM);
+        test("null-820130816", "" + f_oN + f_lM);
+        test("nullnull", "" + f_oN + sf_oAN);
+        test("null25000000", "" + f_oN + s_I);
+        test("-1410065408-96.0", "" + s_lM + s_dM);
+        test("-1410065408null", "" + s_lM + s_oNtS);
+        test("-1410065408\u045176", "" + s_lM + f_strU);
+        test("-141006540892", "" + s_lM + sf_strU2);
+        test("-141006540851", "" + s_lM + sf_strU1);
+        test("-1410065408null", "" + s_lM + s_iAN);
+        test("-1410065408-54", "" + s_lM + f_bM);
+        test("-1410065408-87.0", "" + s_lM + f_fM);
+        test("-1410065408null", "" + s_lM + s_oAN);
+        test("-141006540819", "" + s_lM + f_str);
+        test("-1410065408-41", "" + s_lM + sf_bM);
+        test("-1410065408null", "" + s_lM + sf_IN);
+        test("-1410065408T", "" + s_lM + s_c);
+        test("-1410065408-42.0", "" + s_lM + sf_fM);
+        test("-141006540825", "" + s_lM + s_b);
+        test("-1410065408null", "" + s_lM + f_oN);
+        test("-1410065408-1410065408", "" + s_lM + s_lM);
+        test("-14100654088.0", "" + s_lM + s_d);
+        test("-141006540855.0", "" + s_lM + s_f);
+        test("-141006540897000000", "" + s_lM + s_i);
+        test("-1410065408-9900", "" + s_lM + f_sM);
+        test("-1410065408935228928", "" + s_lM + s_l);
+        test("-1410065408-8400", "" + s_lM + sf_sM);
+        test("-1410065408C(82)", "" + s_lM + s_o);
+        test("-1410065408null", "" + s_lM + sf_oNtS);
+        test("-1410065408true", "" + s_lM + s_bl);
+        test("-14100654083900", "" + s_lM + s_s);
+        test("-1410065408null", "" + s_lM + sf_oN);
+        test("-141006540894000000", "" + s_lM + f_I);
+        test("-1410065408null", "" + s_lM + f_IN);
+        test("-1410065408true", "" + s_lM + sf_bl);
+        test("-14100654085500", "" + s_lM + sf_s);
+        test("-1410065408-2900", "" + s_lM + s_sM);
+        test("-1410065408-194313216", "" + s_lM + sf_l);
+        test("-141006540812", "" + s_lM + s_strU1);
+        test("-1410065408C(87)", "" + s_lM + sf_o);
+        test("-141006540891", "" + s_lM + s_strU2);
+        test("-141006540821", "" + s_lM + f_strU1);
+        test("-141006540818", "" + s_lM + f_strU2);
+        test("-1410065408null", "" + s_lM + f_iAN);
+        test("-1410065408null", "" + s_lM + s_oN);
+        test("-1410065408\u045180", "" + s_lM + s_strU);
+        test("-1410065408C", "" + s_lM + sf_c);
+        test("-141006540875", "" + s_lM + sf_str);
+        test("-1410065408-43", "" + s_lM + s_bM);
+        test("-141006540880", "" + s_lM + sf_b);
+        test("-1410065408null", "" + s_lM + s_IN);
+        test("-1410065408-52.0", "" + s_lM + s_fM);
+        test("-141006540875000000", "" + s_lM + sf_i);
+        test("-141006540844", "" + s_lM + f_b);
+        test("-1410065408-1705032704", "" + s_lM + sf_lM);
+        test("-1410065408null", "" + s_lM + f_oAN);
+        test("-141006540883.0", "" + s_lM + f_d);
+        test("-1410065408I", "" + s_lM + f_c);
+        test("-141006540894.0", "" + s_lM + f_f);
+        test("-141006540812.0", "" + s_lM + sf_d);
+        test("-1410065408-99.0", "" + s_lM + f_dM);
+        test("-141006540817.0", "" + s_lM + sf_f);
+        test("-1410065408-84.0", "" + s_lM + sf_dM);
+        test("-141006540858000000", "" + s_lM + f_i);
+        test("-1410065408-55000000", "" + s_lM + f_iM);
+        test("-14100654081460392448", "" + s_lM + f_l);
+        test("-1410065408C(70)", "" + s_lM + f_o);
+        test("-1410065408\u04511", "" + s_lM + sf_strU);
+        test("-14100654088000", "" + s_lM + f_s);
+        test("-141006540818", "" + s_lM + s_str);
+        test("-1410065408-1000000", "" + s_lM + s_iM);
+        test("-14100654081000000", "" + s_lM + sf_I);
+        test("-1410065408null", "" + s_lM + f_oNtS);
+        test("-1410065408false", "" + s_lM + f_bl);
+        test("-1410065408null", "" + s_lM + sf_iAN);
+        test("-1410065408-2000000", "" + s_lM + sf_iM);
+        test("-1410065408-820130816", "" + s_lM + f_lM);
+        test("-1410065408null", "" + s_lM + sf_oAN);
+        test("-141006540825000000", "" + s_lM + s_I);
+        test("8.0-96.0", "" + s_d + s_dM);
+        test("8.0null", "" + s_d + s_oNtS);
+        test("8.0\u045176", "" + s_d + f_strU);
+        test("8.092", "" + s_d + sf_strU2);
+        test("8.051", "" + s_d + sf_strU1);
+        test("8.0null", "" + s_d + s_iAN);
+        test("8.0-54", "" + s_d + f_bM);
+        test("8.0-87.0", "" + s_d + f_fM);
+        test("8.0null", "" + s_d + s_oAN);
+        test("8.019", "" + s_d + f_str);
+        test("8.0-41", "" + s_d + sf_bM);
+        test("8.0null", "" + s_d + sf_IN);
+        test("8.0T", "" + s_d + s_c);
+        test("8.0-42.0", "" + s_d + sf_fM);
+        test("8.025", "" + s_d + s_b);
+        test("8.0null", "" + s_d + f_oN);
+        test("8.0-1410065408", "" + s_d + s_lM);
+        test("8.08.0", "" + s_d + s_d);
+        test("8.055.0", "" + s_d + s_f);
+        test("8.097000000", "" + s_d + s_i);
+        test("8.0-9900", "" + s_d + f_sM);
+        test("8.0935228928", "" + s_d + s_l);
+        test("8.0-8400", "" + s_d + sf_sM);
+        test("8.0C(82)", "" + s_d + s_o);
+        test("8.0null", "" + s_d + sf_oNtS);
+        test("8.0true", "" + s_d + s_bl);
+        test("8.03900", "" + s_d + s_s);
+        test("8.0null", "" + s_d + sf_oN);
+        test("8.094000000", "" + s_d + f_I);
+        test("8.0null", "" + s_d + f_IN);
+        test("8.0true", "" + s_d + sf_bl);
+        test("8.05500", "" + s_d + sf_s);
+        test("8.0-2900", "" + s_d + s_sM);
+        test("8.0-194313216", "" + s_d + sf_l);
+        test("8.012", "" + s_d + s_strU1);
+        test("8.0C(87)", "" + s_d + sf_o);
+        test("8.091", "" + s_d + s_strU2);
+        test("8.021", "" + s_d + f_strU1);
+        test("8.018", "" + s_d + f_strU2);
+        test("8.0null", "" + s_d + f_iAN);
+        test("8.0null", "" + s_d + s_oN);
+        test("8.0\u045180", "" + s_d + s_strU);
+        test("8.0C", "" + s_d + sf_c);
+        test("8.075", "" + s_d + sf_str);
+        test("8.0-43", "" + s_d + s_bM);
+        test("8.080", "" + s_d + sf_b);
+        test("8.0null", "" + s_d + s_IN);
+        test("8.0-52.0", "" + s_d + s_fM);
+        test("8.075000000", "" + s_d + sf_i);
+        test("8.044", "" + s_d + f_b);
+        test("8.0-1705032704", "" + s_d + sf_lM);
+        test("8.0null", "" + s_d + f_oAN);
+        test("8.083.0", "" + s_d + f_d);
+        test("8.0I", "" + s_d + f_c);
+        test("8.094.0", "" + s_d + f_f);
+        test("8.012.0", "" + s_d + sf_d);
+        test("8.0-99.0", "" + s_d + f_dM);
+        test("8.017.0", "" + s_d + sf_f);
+        test("8.0-84.0", "" + s_d + sf_dM);
+        test("8.058000000", "" + s_d + f_i);
+        test("8.0-55000000", "" + s_d + f_iM);
+        test("8.01460392448", "" + s_d + f_l);
+        test("8.0C(70)", "" + s_d + f_o);
+        test("8.0\u04511", "" + s_d + sf_strU);
+        test("8.08000", "" + s_d + f_s);
+        test("8.018", "" + s_d + s_str);
+        test("8.0-1000000", "" + s_d + s_iM);
+        test("8.01000000", "" + s_d + sf_I);
+        test("8.0null", "" + s_d + f_oNtS);
+        test("8.0false", "" + s_d + f_bl);
+        test("8.0null", "" + s_d + sf_iAN);
+        test("8.0-2000000", "" + s_d + sf_iM);
+        test("8.0-820130816", "" + s_d + f_lM);
+        test("8.0null", "" + s_d + sf_oAN);
+        test("8.025000000", "" + s_d + s_I);
+        test("55.0-96.0", "" + s_f + s_dM);
+        test("55.0null", "" + s_f + s_oNtS);
+        test("55.0\u045176", "" + s_f + f_strU);
+        test("55.092", "" + s_f + sf_strU2);
+        test("55.051", "" + s_f + sf_strU1);
+        test("55.0null", "" + s_f + s_iAN);
+        test("55.0-54", "" + s_f + f_bM);
+        test("55.0-87.0", "" + s_f + f_fM);
+        test("55.0null", "" + s_f + s_oAN);
+        test("55.019", "" + s_f + f_str);
+        test("55.0-41", "" + s_f + sf_bM);
+        test("55.0null", "" + s_f + sf_IN);
+        test("55.0T", "" + s_f + s_c);
+        test("55.0-42.0", "" + s_f + sf_fM);
+        test("55.025", "" + s_f + s_b);
+        test("55.0null", "" + s_f + f_oN);
+        test("55.0-1410065408", "" + s_f + s_lM);
+        test("55.08.0", "" + s_f + s_d);
+        test("55.055.0", "" + s_f + s_f);
+        test("55.097000000", "" + s_f + s_i);
+        test("55.0-9900", "" + s_f + f_sM);
+        test("55.0935228928", "" + s_f + s_l);
+        test("55.0-8400", "" + s_f + sf_sM);
+        test("55.0C(82)", "" + s_f + s_o);
+        test("55.0null", "" + s_f + sf_oNtS);
+        test("55.0true", "" + s_f + s_bl);
+        test("55.03900", "" + s_f + s_s);
+        test("55.0null", "" + s_f + sf_oN);
+        test("55.094000000", "" + s_f + f_I);
+        test("55.0null", "" + s_f + f_IN);
+        test("55.0true", "" + s_f + sf_bl);
+        test("55.05500", "" + s_f + sf_s);
+        test("55.0-2900", "" + s_f + s_sM);
+        test("55.0-194313216", "" + s_f + sf_l);
+        test("55.012", "" + s_f + s_strU1);
+        test("55.0C(87)", "" + s_f + sf_o);
+        test("55.091", "" + s_f + s_strU2);
+        test("55.021", "" + s_f + f_strU1);
+        test("55.018", "" + s_f + f_strU2);
+        test("55.0null", "" + s_f + f_iAN);
+        test("55.0null", "" + s_f + s_oN);
+        test("55.0\u045180", "" + s_f + s_strU);
+        test("55.0C", "" + s_f + sf_c);
+        test("55.075", "" + s_f + sf_str);
+        test("55.0-43", "" + s_f + s_bM);
+        test("55.080", "" + s_f + sf_b);
+        test("55.0null", "" + s_f + s_IN);
+        test("55.0-52.0", "" + s_f + s_fM);
+        test("55.075000000", "" + s_f + sf_i);
+        test("55.044", "" + s_f + f_b);
+        test("55.0-1705032704", "" + s_f + sf_lM);
+        test("55.0null", "" + s_f + f_oAN);
+        test("55.083.0", "" + s_f + f_d);
+        test("55.0I", "" + s_f + f_c);
+        test("55.094.0", "" + s_f + f_f);
+        test("55.012.0", "" + s_f + sf_d);
+        test("55.0-99.0", "" + s_f + f_dM);
+        test("55.017.0", "" + s_f + sf_f);
+        test("55.0-84.0", "" + s_f + sf_dM);
+        test("55.058000000", "" + s_f + f_i);
+        test("55.0-55000000", "" + s_f + f_iM);
+        test("55.01460392448", "" + s_f + f_l);
+        test("55.0C(70)", "" + s_f + f_o);
+        test("55.0\u04511", "" + s_f + sf_strU);
+        test("55.08000", "" + s_f + f_s);
+        test("55.018", "" + s_f + s_str);
+        test("55.0-1000000", "" + s_f + s_iM);
+        test("55.01000000", "" + s_f + sf_I);
+        test("55.0null", "" + s_f + f_oNtS);
+        test("55.0false", "" + s_f + f_bl);
+        test("55.0null", "" + s_f + sf_iAN);
+        test("55.0-2000000", "" + s_f + sf_iM);
+        test("55.0-820130816", "" + s_f + f_lM);
+        test("55.0null", "" + s_f + sf_oAN);
+        test("55.025000000", "" + s_f + s_I);
+        test("97000000-96.0", "" + s_i + s_dM);
+        test("97000000null", "" + s_i + s_oNtS);
+        test("97000000\u045176", "" + s_i + f_strU);
+        test("9700000092", "" + s_i + sf_strU2);
+        test("9700000051", "" + s_i + sf_strU1);
+        test("97000000null", "" + s_i + s_iAN);
+        test("97000000-54", "" + s_i + f_bM);
+        test("97000000-87.0", "" + s_i + f_fM);
+        test("97000000null", "" + s_i + s_oAN);
+        test("9700000019", "" + s_i + f_str);
+        test("97000000-41", "" + s_i + sf_bM);
+        test("97000000null", "" + s_i + sf_IN);
+        test("97000000T", "" + s_i + s_c);
+        test("97000000-42.0", "" + s_i + sf_fM);
+        test("9700000025", "" + s_i + s_b);
+        test("97000000null", "" + s_i + f_oN);
+        test("97000000-1410065408", "" + s_i + s_lM);
+        test("970000008.0", "" + s_i + s_d);
+        test("9700000055.0", "" + s_i + s_f);
+        test("9700000097000000", "" + s_i + s_i);
+        test("97000000-9900", "" + s_i + f_sM);
+        test("97000000935228928", "" + s_i + s_l);
+        test("97000000-8400", "" + s_i + sf_sM);
+        test("97000000C(82)", "" + s_i + s_o);
+        test("97000000null", "" + s_i + sf_oNtS);
+        test("97000000true", "" + s_i + s_bl);
+        test("970000003900", "" + s_i + s_s);
+        test("97000000null", "" + s_i + sf_oN);
+        test("9700000094000000", "" + s_i + f_I);
+        test("97000000null", "" + s_i + f_IN);
+        test("97000000true", "" + s_i + sf_bl);
+        test("970000005500", "" + s_i + sf_s);
+        test("97000000-2900", "" + s_i + s_sM);
+        test("97000000-194313216", "" + s_i + sf_l);
+        test("9700000012", "" + s_i + s_strU1);
+        test("97000000C(87)", "" + s_i + sf_o);
+        test("9700000091", "" + s_i + s_strU2);
+        test("9700000021", "" + s_i + f_strU1);
+        test("9700000018", "" + s_i + f_strU2);
+        test("97000000null", "" + s_i + f_iAN);
+        test("97000000null", "" + s_i + s_oN);
+        test("97000000\u045180", "" + s_i + s_strU);
+        test("97000000C", "" + s_i + sf_c);
+        test("9700000075", "" + s_i + sf_str);
+        test("97000000-43", "" + s_i + s_bM);
+        test("9700000080", "" + s_i + sf_b);
+        test("97000000null", "" + s_i + s_IN);
+        test("97000000-52.0", "" + s_i + s_fM);
+        test("9700000075000000", "" + s_i + sf_i);
+        test("9700000044", "" + s_i + f_b);
+        test("97000000-1705032704", "" + s_i + sf_lM);
+        test("97000000null", "" + s_i + f_oAN);
+        test("9700000083.0", "" + s_i + f_d);
+        test("97000000I", "" + s_i + f_c);
+        test("9700000094.0", "" + s_i + f_f);
+        test("9700000012.0", "" + s_i + sf_d);
+        test("97000000-99.0", "" + s_i + f_dM);
+        test("9700000017.0", "" + s_i + sf_f);
+        test("97000000-84.0", "" + s_i + sf_dM);
+        test("9700000058000000", "" + s_i + f_i);
+        test("97000000-55000000", "" + s_i + f_iM);
+        test("970000001460392448", "" + s_i + f_l);
+        test("97000000C(70)", "" + s_i + f_o);
+        test("97000000\u04511", "" + s_i + sf_strU);
+        test("970000008000", "" + s_i + f_s);
+        test("9700000018", "" + s_i + s_str);
+        test("97000000-1000000", "" + s_i + s_iM);
+        test("970000001000000", "" + s_i + sf_I);
+        test("97000000null", "" + s_i + f_oNtS);
+        test("97000000false", "" + s_i + f_bl);
+        test("97000000null", "" + s_i + sf_iAN);
+        test("97000000-2000000", "" + s_i + sf_iM);
+        test("97000000-820130816", "" + s_i + f_lM);
+        test("97000000null", "" + s_i + sf_oAN);
+        test("9700000025000000", "" + s_i + s_I);
+        test("-9900-96.0", "" + f_sM + s_dM);
+        test("-9900null", "" + f_sM + s_oNtS);
+        test("-9900\u045176", "" + f_sM + f_strU);
+        test("-990092", "" + f_sM + sf_strU2);
+        test("-990051", "" + f_sM + sf_strU1);
+        test("-9900null", "" + f_sM + s_iAN);
+        test("-9900-54", "" + f_sM + f_bM);
+        test("-9900-87.0", "" + f_sM + f_fM);
+        test("-9900null", "" + f_sM + s_oAN);
+        test("-990019", "" + f_sM + f_str);
+        test("-9900-41", "" + f_sM + sf_bM);
+        test("-9900null", "" + f_sM + sf_IN);
+        test("-9900T", "" + f_sM + s_c);
+        test("-9900-42.0", "" + f_sM + sf_fM);
+        test("-990025", "" + f_sM + s_b);
+        test("-9900null", "" + f_sM + f_oN);
+        test("-9900-1410065408", "" + f_sM + s_lM);
+        test("-99008.0", "" + f_sM + s_d);
+        test("-990055.0", "" + f_sM + s_f);
+        test("-990097000000", "" + f_sM + s_i);
+        test("-9900-9900", "" + f_sM + f_sM);
+        test("-9900935228928", "" + f_sM + s_l);
+        test("-9900-8400", "" + f_sM + sf_sM);
+        test("-9900C(82)", "" + f_sM + s_o);
+        test("-9900null", "" + f_sM + sf_oNtS);
+        test("-9900true", "" + f_sM + s_bl);
+        test("-99003900", "" + f_sM + s_s);
+        test("-9900null", "" + f_sM + sf_oN);
+        test("-990094000000", "" + f_sM + f_I);
+        test("-9900null", "" + f_sM + f_IN);
+        test("-9900true", "" + f_sM + sf_bl);
+        test("-99005500", "" + f_sM + sf_s);
+        test("-9900-2900", "" + f_sM + s_sM);
+        test("-9900-194313216", "" + f_sM + sf_l);
+        test("-990012", "" + f_sM + s_strU1);
+        test("-9900C(87)", "" + f_sM + sf_o);
+        test("-990091", "" + f_sM + s_strU2);
+        test("-990021", "" + f_sM + f_strU1);
+        test("-990018", "" + f_sM + f_strU2);
+        test("-9900null", "" + f_sM + f_iAN);
+        test("-9900null", "" + f_sM + s_oN);
+        test("-9900\u045180", "" + f_sM + s_strU);
+        test("-9900C", "" + f_sM + sf_c);
+        test("-990075", "" + f_sM + sf_str);
+        test("-9900-43", "" + f_sM + s_bM);
+        test("-990080", "" + f_sM + sf_b);
+        test("-9900null", "" + f_sM + s_IN);
+        test("-9900-52.0", "" + f_sM + s_fM);
+        test("-990075000000", "" + f_sM + sf_i);
+        test("-990044", "" + f_sM + f_b);
+        test("-9900-1705032704", "" + f_sM + sf_lM);
+        test("-9900null", "" + f_sM + f_oAN);
+        test("-990083.0", "" + f_sM + f_d);
+        test("-9900I", "" + f_sM + f_c);
+        test("-990094.0", "" + f_sM + f_f);
+        test("-990012.0", "" + f_sM + sf_d);
+        test("-9900-99.0", "" + f_sM + f_dM);
+        test("-990017.0", "" + f_sM + sf_f);
+        test("-9900-84.0", "" + f_sM + sf_dM);
+        test("-990058000000", "" + f_sM + f_i);
+        test("-9900-55000000", "" + f_sM + f_iM);
+        test("-99001460392448", "" + f_sM + f_l);
+        test("-9900C(70)", "" + f_sM + f_o);
+        test("-9900\u04511", "" + f_sM + sf_strU);
+        test("-99008000", "" + f_sM + f_s);
+        test("-990018", "" + f_sM + s_str);
+        test("-9900-1000000", "" + f_sM + s_iM);
+        test("-99001000000", "" + f_sM + sf_I);
+        test("-9900null", "" + f_sM + f_oNtS);
+        test("-9900false", "" + f_sM + f_bl);
+        test("-9900null", "" + f_sM + sf_iAN);
+        test("-9900-2000000", "" + f_sM + sf_iM);
+        test("-9900-820130816", "" + f_sM + f_lM);
+        test("-9900null", "" + f_sM + sf_oAN);
+        test("-990025000000", "" + f_sM + s_I);
+        test("935228928-96.0", "" + s_l + s_dM);
+        test("935228928null", "" + s_l + s_oNtS);
+        test("935228928\u045176", "" + s_l + f_strU);
+        test("93522892892", "" + s_l + sf_strU2);
+        test("93522892851", "" + s_l + sf_strU1);
+        test("935228928null", "" + s_l + s_iAN);
+        test("935228928-54", "" + s_l + f_bM);
+        test("935228928-87.0", "" + s_l + f_fM);
+        test("935228928null", "" + s_l + s_oAN);
+        test("93522892819", "" + s_l + f_str);
+        test("935228928-41", "" + s_l + sf_bM);
+        test("935228928null", "" + s_l + sf_IN);
+        test("935228928T", "" + s_l + s_c);
+        test("935228928-42.0", "" + s_l + sf_fM);
+        test("93522892825", "" + s_l + s_b);
+        test("935228928null", "" + s_l + f_oN);
+        test("935228928-1410065408", "" + s_l + s_lM);
+        test("9352289288.0", "" + s_l + s_d);
+        test("93522892855.0", "" + s_l + s_f);
+        test("93522892897000000", "" + s_l + s_i);
+        test("935228928-9900", "" + s_l + f_sM);
+        test("935228928935228928", "" + s_l + s_l);
+        test("935228928-8400", "" + s_l + sf_sM);
+        test("935228928C(82)", "" + s_l + s_o);
+        test("935228928null", "" + s_l + sf_oNtS);
+        test("935228928true", "" + s_l + s_bl);
+        test("9352289283900", "" + s_l + s_s);
+        test("935228928null", "" + s_l + sf_oN);
+        test("93522892894000000", "" + s_l + f_I);
+        test("935228928null", "" + s_l + f_IN);
+        test("935228928true", "" + s_l + sf_bl);
+        test("9352289285500", "" + s_l + sf_s);
+        test("935228928-2900", "" + s_l + s_sM);
+        test("935228928-194313216", "" + s_l + sf_l);
+        test("93522892812", "" + s_l + s_strU1);
+        test("935228928C(87)", "" + s_l + sf_o);
+        test("93522892891", "" + s_l + s_strU2);
+        test("93522892821", "" + s_l + f_strU1);
+        test("93522892818", "" + s_l + f_strU2);
+        test("935228928null", "" + s_l + f_iAN);
+        test("935228928null", "" + s_l + s_oN);
+        test("935228928\u045180", "" + s_l + s_strU);
+        test("935228928C", "" + s_l + sf_c);
+        test("93522892875", "" + s_l + sf_str);
+        test("935228928-43", "" + s_l + s_bM);
+        test("93522892880", "" + s_l + sf_b);
+        test("935228928null", "" + s_l + s_IN);
+        test("935228928-52.0", "" + s_l + s_fM);
+        test("93522892875000000", "" + s_l + sf_i);
+        test("93522892844", "" + s_l + f_b);
+        test("935228928-1705032704", "" + s_l + sf_lM);
+        test("935228928null", "" + s_l + f_oAN);
+        test("93522892883.0", "" + s_l + f_d);
+        test("935228928I", "" + s_l + f_c);
+        test("93522892894.0", "" + s_l + f_f);
+        test("93522892812.0", "" + s_l + sf_d);
+        test("935228928-99.0", "" + s_l + f_dM);
+        test("93522892817.0", "" + s_l + sf_f);
+        test("935228928-84.0", "" + s_l + sf_dM);
+        test("93522892858000000", "" + s_l + f_i);
+        test("935228928-55000000", "" + s_l + f_iM);
+        test("9352289281460392448", "" + s_l + f_l);
+        test("935228928C(70)", "" + s_l + f_o);
+        test("935228928\u04511", "" + s_l + sf_strU);
+        test("9352289288000", "" + s_l + f_s);
+        test("93522892818", "" + s_l + s_str);
+        test("935228928-1000000", "" + s_l + s_iM);
+        test("9352289281000000", "" + s_l + sf_I);
+        test("935228928null", "" + s_l + f_oNtS);
+        test("935228928false", "" + s_l + f_bl);
+        test("935228928null", "" + s_l + sf_iAN);
+        test("935228928-2000000", "" + s_l + sf_iM);
+        test("935228928-820130816", "" + s_l + f_lM);
+        test("935228928null", "" + s_l + sf_oAN);
+        test("93522892825000000", "" + s_l + s_I);
+        test("-8400-96.0", "" + sf_sM + s_dM);
+        test("-8400null", "" + sf_sM + s_oNtS);
+        test("-8400\u045176", "" + sf_sM + f_strU);
+        test("-840092", "" + sf_sM + sf_strU2);
+        test("-840051", "" + sf_sM + sf_strU1);
+        test("-8400null", "" + sf_sM + s_iAN);
+        test("-8400-54", "" + sf_sM + f_bM);
+        test("-8400-87.0", "" + sf_sM + f_fM);
+        test("-8400null", "" + sf_sM + s_oAN);
+        test("-840019", "" + sf_sM + f_str);
+        test("-8400-41", "" + sf_sM + sf_bM);
+        test("-8400null", "" + sf_sM + sf_IN);
+        test("-8400T", "" + sf_sM + s_c);
+        test("-8400-42.0", "" + sf_sM + sf_fM);
+        test("-840025", "" + sf_sM + s_b);
+        test("-8400null", "" + sf_sM + f_oN);
+        test("-8400-1410065408", "" + sf_sM + s_lM);
+        test("-84008.0", "" + sf_sM + s_d);
+        test("-840055.0", "" + sf_sM + s_f);
+        test("-840097000000", "" + sf_sM + s_i);
+        test("-8400-9900", "" + sf_sM + f_sM);
+        test("-8400935228928", "" + sf_sM + s_l);
+        test("-8400-8400", "" + sf_sM + sf_sM);
+        test("-8400C(82)", "" + sf_sM + s_o);
+        test("-8400null", "" + sf_sM + sf_oNtS);
+        test("-8400true", "" + sf_sM + s_bl);
+        test("-84003900", "" + sf_sM + s_s);
+        test("-8400null", "" + sf_sM + sf_oN);
+        test("-840094000000", "" + sf_sM + f_I);
+        test("-8400null", "" + sf_sM + f_IN);
+        test("-8400true", "" + sf_sM + sf_bl);
+        test("-84005500", "" + sf_sM + sf_s);
+        test("-8400-2900", "" + sf_sM + s_sM);
+        test("-8400-194313216", "" + sf_sM + sf_l);
+        test("-840012", "" + sf_sM + s_strU1);
+        test("-8400C(87)", "" + sf_sM + sf_o);
+        test("-840091", "" + sf_sM + s_strU2);
+        test("-840021", "" + sf_sM + f_strU1);
+        test("-840018", "" + sf_sM + f_strU2);
+        test("-8400null", "" + sf_sM + f_iAN);
+        test("-8400null", "" + sf_sM + s_oN);
+        test("-8400\u045180", "" + sf_sM + s_strU);
+        test("-8400C", "" + sf_sM + sf_c);
+        test("-840075", "" + sf_sM + sf_str);
+        test("-8400-43", "" + sf_sM + s_bM);
+        test("-840080", "" + sf_sM + sf_b);
+        test("-8400null", "" + sf_sM + s_IN);
+        test("-8400-52.0", "" + sf_sM + s_fM);
+        test("-840075000000", "" + sf_sM + sf_i);
+        test("-840044", "" + sf_sM + f_b);
+        test("-8400-1705032704", "" + sf_sM + sf_lM);
+        test("-8400null", "" + sf_sM + f_oAN);
+        test("-840083.0", "" + sf_sM + f_d);
+        test("-8400I", "" + sf_sM + f_c);
+        test("-840094.0", "" + sf_sM + f_f);
+        test("-840012.0", "" + sf_sM + sf_d);
+        test("-8400-99.0", "" + sf_sM + f_dM);
+        test("-840017.0", "" + sf_sM + sf_f);
+        test("-8400-84.0", "" + sf_sM + sf_dM);
+        test("-840058000000", "" + sf_sM + f_i);
+        test("-8400-55000000", "" + sf_sM + f_iM);
+        test("-84001460392448", "" + sf_sM + f_l);
+        test("-8400C(70)", "" + sf_sM + f_o);
+        test("-8400\u04511", "" + sf_sM + sf_strU);
+        test("-84008000", "" + sf_sM + f_s);
+        test("-840018", "" + sf_sM + s_str);
+        test("-8400-1000000", "" + sf_sM + s_iM);
+        test("-84001000000", "" + sf_sM + sf_I);
+        test("-8400null", "" + sf_sM + f_oNtS);
+        test("-8400false", "" + sf_sM + f_bl);
+        test("-8400null", "" + sf_sM + sf_iAN);
+        test("-8400-2000000", "" + sf_sM + sf_iM);
+        test("-8400-820130816", "" + sf_sM + f_lM);
+        test("-8400null", "" + sf_sM + sf_oAN);
+        test("-840025000000", "" + sf_sM + s_I);
+        test("C(82)-96.0", "" + s_o + s_dM);
+        test("C(82)null", "" + s_o + s_oNtS);
+        test("C(82)\u045176", "" + s_o + f_strU);
+        test("C(82)92", "" + s_o + sf_strU2);
+        test("C(82)51", "" + s_o + sf_strU1);
+        test("C(82)null", "" + s_o + s_iAN);
+        test("C(82)-54", "" + s_o + f_bM);
+        test("C(82)-87.0", "" + s_o + f_fM);
+        test("C(82)null", "" + s_o + s_oAN);
+        test("C(82)19", "" + s_o + f_str);
+        test("C(82)-41", "" + s_o + sf_bM);
+        test("C(82)null", "" + s_o + sf_IN);
+        test("C(82)T", "" + s_o + s_c);
+        test("C(82)-42.0", "" + s_o + sf_fM);
+        test("C(82)25", "" + s_o + s_b);
+        test("C(82)null", "" + s_o + f_oN);
+        test("C(82)-1410065408", "" + s_o + s_lM);
+        test("C(82)8.0", "" + s_o + s_d);
+        test("C(82)55.0", "" + s_o + s_f);
+        test("C(82)97000000", "" + s_o + s_i);
+        test("C(82)-9900", "" + s_o + f_sM);
+        test("C(82)935228928", "" + s_o + s_l);
+        test("C(82)-8400", "" + s_o + sf_sM);
+        test("C(82)C(82)", "" + s_o + s_o);
+        test("C(82)null", "" + s_o + sf_oNtS);
+        test("C(82)true", "" + s_o + s_bl);
+        test("C(82)3900", "" + s_o + s_s);
+        test("C(82)null", "" + s_o + sf_oN);
+        test("C(82)94000000", "" + s_o + f_I);
+        test("C(82)null", "" + s_o + f_IN);
+        test("C(82)true", "" + s_o + sf_bl);
+        test("C(82)5500", "" + s_o + sf_s);
+        test("C(82)-2900", "" + s_o + s_sM);
+        test("C(82)-194313216", "" + s_o + sf_l);
+        test("C(82)12", "" + s_o + s_strU1);
+        test("C(82)C(87)", "" + s_o + sf_o);
+        test("C(82)91", "" + s_o + s_strU2);
+        test("C(82)21", "" + s_o + f_strU1);
+        test("C(82)18", "" + s_o + f_strU2);
+        test("C(82)null", "" + s_o + f_iAN);
+        test("C(82)null", "" + s_o + s_oN);
+        test("C(82)\u045180", "" + s_o + s_strU);
+        test("C(82)C", "" + s_o + sf_c);
+        test("C(82)75", "" + s_o + sf_str);
+        test("C(82)-43", "" + s_o + s_bM);
+        test("C(82)80", "" + s_o + sf_b);
+        test("C(82)null", "" + s_o + s_IN);
+        test("C(82)-52.0", "" + s_o + s_fM);
+        test("C(82)75000000", "" + s_o + sf_i);
+        test("C(82)44", "" + s_o + f_b);
+        test("C(82)-1705032704", "" + s_o + sf_lM);
+        test("C(82)null", "" + s_o + f_oAN);
+        test("C(82)83.0", "" + s_o + f_d);
+        test("C(82)I", "" + s_o + f_c);
+        test("C(82)94.0", "" + s_o + f_f);
+        test("C(82)12.0", "" + s_o + sf_d);
+        test("C(82)-99.0", "" + s_o + f_dM);
+        test("C(82)17.0", "" + s_o + sf_f);
+        test("C(82)-84.0", "" + s_o + sf_dM);
+        test("C(82)58000000", "" + s_o + f_i);
+        test("C(82)-55000000", "" + s_o + f_iM);
+        test("C(82)1460392448", "" + s_o + f_l);
+        test("C(82)C(70)", "" + s_o + f_o);
+        test("C(82)\u04511", "" + s_o + sf_strU);
+        test("C(82)8000", "" + s_o + f_s);
+        test("C(82)18", "" + s_o + s_str);
+        test("C(82)-1000000", "" + s_o + s_iM);
+        test("C(82)1000000", "" + s_o + sf_I);
+        test("C(82)null", "" + s_o + f_oNtS);
+        test("C(82)false", "" + s_o + f_bl);
+        test("C(82)null", "" + s_o + sf_iAN);
+        test("C(82)-2000000", "" + s_o + sf_iM);
+        test("C(82)-820130816", "" + s_o + f_lM);
+        test("C(82)null", "" + s_o + sf_oAN);
+        test("C(82)25000000", "" + s_o + s_I);
+        test("null-96.0", "" + sf_oNtS + s_dM);
+        test("nullnull", "" + sf_oNtS + s_oNtS);
+        test("null\u045176", "" + sf_oNtS + f_strU);
+        test("null92", "" + sf_oNtS + sf_strU2);
+        test("null51", "" + sf_oNtS + sf_strU1);
+        test("nullnull", "" + sf_oNtS + s_iAN);
+        test("null-54", "" + sf_oNtS + f_bM);
+        test("null-87.0", "" + sf_oNtS + f_fM);
+        test("nullnull", "" + sf_oNtS + s_oAN);
+        test("null19", "" + sf_oNtS + f_str);
+        test("null-41", "" + sf_oNtS + sf_bM);
+        test("nullnull", "" + sf_oNtS + sf_IN);
+        test("nullT", "" + sf_oNtS + s_c);
+        test("null-42.0", "" + sf_oNtS + sf_fM);
+        test("null25", "" + sf_oNtS + s_b);
+        test("nullnull", "" + sf_oNtS + f_oN);
+        test("null-1410065408", "" + sf_oNtS + s_lM);
+        test("null8.0", "" + sf_oNtS + s_d);
+        test("null55.0", "" + sf_oNtS + s_f);
+        test("null97000000", "" + sf_oNtS + s_i);
+        test("null-9900", "" + sf_oNtS + f_sM);
+        test("null935228928", "" + sf_oNtS + s_l);
+        test("null-8400", "" + sf_oNtS + sf_sM);
+        test("nullC(82)", "" + sf_oNtS + s_o);
+        test("nullnull", "" + sf_oNtS + sf_oNtS);
+        test("nulltrue", "" + sf_oNtS + s_bl);
+        test("null3900", "" + sf_oNtS + s_s);
+        test("nullnull", "" + sf_oNtS + sf_oN);
+        test("null94000000", "" + sf_oNtS + f_I);
+        test("nullnull", "" + sf_oNtS + f_IN);
+        test("nulltrue", "" + sf_oNtS + sf_bl);
+        test("null5500", "" + sf_oNtS + sf_s);
+        test("null-2900", "" + sf_oNtS + s_sM);
+        test("null-194313216", "" + sf_oNtS + sf_l);
+        test("null12", "" + sf_oNtS + s_strU1);
+        test("nullC(87)", "" + sf_oNtS + sf_o);
+        test("null91", "" + sf_oNtS + s_strU2);
+        test("null21", "" + sf_oNtS + f_strU1);
+        test("null18", "" + sf_oNtS + f_strU2);
+        test("nullnull", "" + sf_oNtS + f_iAN);
+        test("nullnull", "" + sf_oNtS + s_oN);
+        test("null\u045180", "" + sf_oNtS + s_strU);
+        test("nullC", "" + sf_oNtS + sf_c);
+        test("null75", "" + sf_oNtS + sf_str);
+        test("null-43", "" + sf_oNtS + s_bM);
+        test("null80", "" + sf_oNtS + sf_b);
+        test("nullnull", "" + sf_oNtS + s_IN);
+        test("null-52.0", "" + sf_oNtS + s_fM);
+        test("null75000000", "" + sf_oNtS + sf_i);
+        test("null44", "" + sf_oNtS + f_b);
+        test("null-1705032704", "" + sf_oNtS + sf_lM);
+        test("nullnull", "" + sf_oNtS + f_oAN);
+        test("null83.0", "" + sf_oNtS + f_d);
+        test("nullI", "" + sf_oNtS + f_c);
+        test("null94.0", "" + sf_oNtS + f_f);
+        test("null12.0", "" + sf_oNtS + sf_d);
+        test("null-99.0", "" + sf_oNtS + f_dM);
+        test("null17.0", "" + sf_oNtS + sf_f);
+        test("null-84.0", "" + sf_oNtS + sf_dM);
+        test("null58000000", "" + sf_oNtS + f_i);
+        test("null-55000000", "" + sf_oNtS + f_iM);
+        test("null1460392448", "" + sf_oNtS + f_l);
+        test("nullC(70)", "" + sf_oNtS + f_o);
+        test("null\u04511", "" + sf_oNtS + sf_strU);
+        test("null8000", "" + sf_oNtS + f_s);
+        test("null18", "" + sf_oNtS + s_str);
+        test("null-1000000", "" + sf_oNtS + s_iM);
+        test("null1000000", "" + sf_oNtS + sf_I);
+        test("nullnull", "" + sf_oNtS + f_oNtS);
+        test("nullfalse", "" + sf_oNtS + f_bl);
+        test("nullnull", "" + sf_oNtS + sf_iAN);
+        test("null-2000000", "" + sf_oNtS + sf_iM);
+        test("null-820130816", "" + sf_oNtS + f_lM);
+        test("nullnull", "" + sf_oNtS + sf_oAN);
+        test("null25000000", "" + sf_oNtS + s_I);
+        test("true-96.0", "" + s_bl + s_dM);
+        test("truenull", "" + s_bl + s_oNtS);
+        test("true\u045176", "" + s_bl + f_strU);
+        test("true92", "" + s_bl + sf_strU2);
+        test("true51", "" + s_bl + sf_strU1);
+        test("truenull", "" + s_bl + s_iAN);
+        test("true-54", "" + s_bl + f_bM);
+        test("true-87.0", "" + s_bl + f_fM);
+        test("truenull", "" + s_bl + s_oAN);
+        test("true19", "" + s_bl + f_str);
+        test("true-41", "" + s_bl + sf_bM);
+        test("truenull", "" + s_bl + sf_IN);
+        test("trueT", "" + s_bl + s_c);
+        test("true-42.0", "" + s_bl + sf_fM);
+        test("true25", "" + s_bl + s_b);
+        test("truenull", "" + s_bl + f_oN);
+        test("true-1410065408", "" + s_bl + s_lM);
+        test("true8.0", "" + s_bl + s_d);
+        test("true55.0", "" + s_bl + s_f);
+        test("true97000000", "" + s_bl + s_i);
+        test("true-9900", "" + s_bl + f_sM);
+        test("true935228928", "" + s_bl + s_l);
+        test("true-8400", "" + s_bl + sf_sM);
+        test("trueC(82)", "" + s_bl + s_o);
+        test("truenull", "" + s_bl + sf_oNtS);
+        test("truetrue", "" + s_bl + s_bl);
+        test("true3900", "" + s_bl + s_s);
+        test("truenull", "" + s_bl + sf_oN);
+        test("true94000000", "" + s_bl + f_I);
+        test("truenull", "" + s_bl + f_IN);
+        test("truetrue", "" + s_bl + sf_bl);
+        test("true5500", "" + s_bl + sf_s);
+        test("true-2900", "" + s_bl + s_sM);
+        test("true-194313216", "" + s_bl + sf_l);
+        test("true12", "" + s_bl + s_strU1);
+        test("trueC(87)", "" + s_bl + sf_o);
+        test("true91", "" + s_bl + s_strU2);
+        test("true21", "" + s_bl + f_strU1);
+        test("true18", "" + s_bl + f_strU2);
+        test("truenull", "" + s_bl + f_iAN);
+        test("truenull", "" + s_bl + s_oN);
+        test("true\u045180", "" + s_bl + s_strU);
+        test("trueC", "" + s_bl + sf_c);
+        test("true75", "" + s_bl + sf_str);
+        test("true-43", "" + s_bl + s_bM);
+        test("true80", "" + s_bl + sf_b);
+        test("truenull", "" + s_bl + s_IN);
+        test("true-52.0", "" + s_bl + s_fM);
+        test("true75000000", "" + s_bl + sf_i);
+        test("true44", "" + s_bl + f_b);
+    }
+
+    public void run2() {
+        test("true-1705032704", "" + s_bl + sf_lM);
+        test("truenull", "" + s_bl + f_oAN);
+        test("true83.0", "" + s_bl + f_d);
+        test("trueI", "" + s_bl + f_c);
+        test("true94.0", "" + s_bl + f_f);
+        test("true12.0", "" + s_bl + sf_d);
+        test("true-99.0", "" + s_bl + f_dM);
+        test("true17.0", "" + s_bl + sf_f);
+        test("true-84.0", "" + s_bl + sf_dM);
+        test("true58000000", "" + s_bl + f_i);
+        test("true-55000000", "" + s_bl + f_iM);
+        test("true1460392448", "" + s_bl + f_l);
+        test("trueC(70)", "" + s_bl + f_o);
+        test("true\u04511", "" + s_bl + sf_strU);
+        test("true8000", "" + s_bl + f_s);
+        test("true18", "" + s_bl + s_str);
+        test("true-1000000", "" + s_bl + s_iM);
+        test("true1000000", "" + s_bl + sf_I);
+        test("truenull", "" + s_bl + f_oNtS);
+        test("truefalse", "" + s_bl + f_bl);
+        test("truenull", "" + s_bl + sf_iAN);
+        test("true-2000000", "" + s_bl + sf_iM);
+        test("true-820130816", "" + s_bl + f_lM);
+        test("truenull", "" + s_bl + sf_oAN);
+        test("true25000000", "" + s_bl + s_I);
+        test("3900-96.0", "" + s_s + s_dM);
+        test("3900null", "" + s_s + s_oNtS);
+        test("3900\u045176", "" + s_s + f_strU);
+        test("390092", "" + s_s + sf_strU2);
+        test("390051", "" + s_s + sf_strU1);
+        test("3900null", "" + s_s + s_iAN);
+        test("3900-54", "" + s_s + f_bM);
+        test("3900-87.0", "" + s_s + f_fM);
+        test("3900null", "" + s_s + s_oAN);
+        test("390019", "" + s_s + f_str);
+        test("3900-41", "" + s_s + sf_bM);
+        test("3900null", "" + s_s + sf_IN);
+        test("3900T", "" + s_s + s_c);
+        test("3900-42.0", "" + s_s + sf_fM);
+        test("390025", "" + s_s + s_b);
+        test("3900null", "" + s_s + f_oN);
+        test("3900-1410065408", "" + s_s + s_lM);
+        test("39008.0", "" + s_s + s_d);
+        test("390055.0", "" + s_s + s_f);
+        test("390097000000", "" + s_s + s_i);
+        test("3900-9900", "" + s_s + f_sM);
+        test("3900935228928", "" + s_s + s_l);
+        test("3900-8400", "" + s_s + sf_sM);
+        test("3900C(82)", "" + s_s + s_o);
+        test("3900null", "" + s_s + sf_oNtS);
+        test("3900true", "" + s_s + s_bl);
+        test("39003900", "" + s_s + s_s);
+        test("3900null", "" + s_s + sf_oN);
+        test("390094000000", "" + s_s + f_I);
+        test("3900null", "" + s_s + f_IN);
+        test("3900true", "" + s_s + sf_bl);
+        test("39005500", "" + s_s + sf_s);
+        test("3900-2900", "" + s_s + s_sM);
+        test("3900-194313216", "" + s_s + sf_l);
+        test("390012", "" + s_s + s_strU1);
+        test("3900C(87)", "" + s_s + sf_o);
+        test("390091", "" + s_s + s_strU2);
+        test("390021", "" + s_s + f_strU1);
+        test("390018", "" + s_s + f_strU2);
+        test("3900null", "" + s_s + f_iAN);
+        test("3900null", "" + s_s + s_oN);
+        test("3900\u045180", "" + s_s + s_strU);
+        test("3900C", "" + s_s + sf_c);
+        test("390075", "" + s_s + sf_str);
+        test("3900-43", "" + s_s + s_bM);
+        test("390080", "" + s_s + sf_b);
+        test("3900null", "" + s_s + s_IN);
+        test("3900-52.0", "" + s_s + s_fM);
+        test("390075000000", "" + s_s + sf_i);
+        test("390044", "" + s_s + f_b);
+        test("3900-1705032704", "" + s_s + sf_lM);
+        test("3900null", "" + s_s + f_oAN);
+        test("390083.0", "" + s_s + f_d);
+        test("3900I", "" + s_s + f_c);
+        test("390094.0", "" + s_s + f_f);
+        test("390012.0", "" + s_s + sf_d);
+        test("3900-99.0", "" + s_s + f_dM);
+        test("390017.0", "" + s_s + sf_f);
+        test("3900-84.0", "" + s_s + sf_dM);
+        test("390058000000", "" + s_s + f_i);
+        test("3900-55000000", "" + s_s + f_iM);
+        test("39001460392448", "" + s_s + f_l);
+        test("3900C(70)", "" + s_s + f_o);
+        test("3900\u04511", "" + s_s + sf_strU);
+        test("39008000", "" + s_s + f_s);
+        test("390018", "" + s_s + s_str);
+        test("3900-1000000", "" + s_s + s_iM);
+        test("39001000000", "" + s_s + sf_I);
+        test("3900null", "" + s_s + f_oNtS);
+        test("3900false", "" + s_s + f_bl);
+        test("3900null", "" + s_s + sf_iAN);
+        test("3900-2000000", "" + s_s + sf_iM);
+        test("3900-820130816", "" + s_s + f_lM);
+        test("3900null", "" + s_s + sf_oAN);
+        test("390025000000", "" + s_s + s_I);
+        test("null-96.0", "" + sf_oN + s_dM);
+        test("nullnull", "" + sf_oN + s_oNtS);
+        test("null\u045176", "" + sf_oN + f_strU);
+        test("null92", "" + sf_oN + sf_strU2);
+        test("null51", "" + sf_oN + sf_strU1);
+        test("nullnull", "" + sf_oN + s_iAN);
+        test("null-54", "" + sf_oN + f_bM);
+        test("null-87.0", "" + sf_oN + f_fM);
+        test("nullnull", "" + sf_oN + s_oAN);
+        test("null19", "" + sf_oN + f_str);
+        test("null-41", "" + sf_oN + sf_bM);
+        test("nullnull", "" + sf_oN + sf_IN);
+        test("nullT", "" + sf_oN + s_c);
+        test("null-42.0", "" + sf_oN + sf_fM);
+        test("null25", "" + sf_oN + s_b);
+        test("nullnull", "" + sf_oN + f_oN);
+        test("null-1410065408", "" + sf_oN + s_lM);
+        test("null8.0", "" + sf_oN + s_d);
+        test("null55.0", "" + sf_oN + s_f);
+        test("null97000000", "" + sf_oN + s_i);
+        test("null-9900", "" + sf_oN + f_sM);
+        test("null935228928", "" + sf_oN + s_l);
+        test("null-8400", "" + sf_oN + sf_sM);
+        test("nullC(82)", "" + sf_oN + s_o);
+        test("nullnull", "" + sf_oN + sf_oNtS);
+        test("nulltrue", "" + sf_oN + s_bl);
+        test("null3900", "" + sf_oN + s_s);
+        test("nullnull", "" + sf_oN + sf_oN);
+        test("null94000000", "" + sf_oN + f_I);
+        test("nullnull", "" + sf_oN + f_IN);
+        test("nulltrue", "" + sf_oN + sf_bl);
+        test("null5500", "" + sf_oN + sf_s);
+        test("null-2900", "" + sf_oN + s_sM);
+        test("null-194313216", "" + sf_oN + sf_l);
+        test("null12", "" + sf_oN + s_strU1);
+        test("nullC(87)", "" + sf_oN + sf_o);
+        test("null91", "" + sf_oN + s_strU2);
+        test("null21", "" + sf_oN + f_strU1);
+        test("null18", "" + sf_oN + f_strU2);
+        test("nullnull", "" + sf_oN + f_iAN);
+        test("nullnull", "" + sf_oN + s_oN);
+        test("null\u045180", "" + sf_oN + s_strU);
+        test("nullC", "" + sf_oN + sf_c);
+        test("null75", "" + sf_oN + sf_str);
+        test("null-43", "" + sf_oN + s_bM);
+        test("null80", "" + sf_oN + sf_b);
+        test("nullnull", "" + sf_oN + s_IN);
+        test("null-52.0", "" + sf_oN + s_fM);
+        test("null75000000", "" + sf_oN + sf_i);
+        test("null44", "" + sf_oN + f_b);
+        test("null-1705032704", "" + sf_oN + sf_lM);
+        test("nullnull", "" + sf_oN + f_oAN);
+        test("null83.0", "" + sf_oN + f_d);
+        test("nullI", "" + sf_oN + f_c);
+        test("null94.0", "" + sf_oN + f_f);
+        test("null12.0", "" + sf_oN + sf_d);
+        test("null-99.0", "" + sf_oN + f_dM);
+        test("null17.0", "" + sf_oN + sf_f);
+        test("null-84.0", "" + sf_oN + sf_dM);
+        test("null58000000", "" + sf_oN + f_i);
+        test("null-55000000", "" + sf_oN + f_iM);
+        test("null1460392448", "" + sf_oN + f_l);
+        test("nullC(70)", "" + sf_oN + f_o);
+        test("null\u04511", "" + sf_oN + sf_strU);
+        test("null8000", "" + sf_oN + f_s);
+        test("null18", "" + sf_oN + s_str);
+        test("null-1000000", "" + sf_oN + s_iM);
+        test("null1000000", "" + sf_oN + sf_I);
+        test("nullnull", "" + sf_oN + f_oNtS);
+        test("nullfalse", "" + sf_oN + f_bl);
+        test("nullnull", "" + sf_oN + sf_iAN);
+        test("null-2000000", "" + sf_oN + sf_iM);
+        test("null-820130816", "" + sf_oN + f_lM);
+        test("nullnull", "" + sf_oN + sf_oAN);
+        test("null25000000", "" + sf_oN + s_I);
+        test("94000000-96.0", "" + f_I + s_dM);
+        test("94000000null", "" + f_I + s_oNtS);
+        test("94000000\u045176", "" + f_I + f_strU);
+        test("9400000092", "" + f_I + sf_strU2);
+        test("9400000051", "" + f_I + sf_strU1);
+        test("94000000null", "" + f_I + s_iAN);
+        test("94000000-54", "" + f_I + f_bM);
+        test("94000000-87.0", "" + f_I + f_fM);
+        test("94000000null", "" + f_I + s_oAN);
+        test("9400000019", "" + f_I + f_str);
+        test("94000000-41", "" + f_I + sf_bM);
+        test("94000000null", "" + f_I + sf_IN);
+        test("94000000T", "" + f_I + s_c);
+        test("94000000-42.0", "" + f_I + sf_fM);
+        test("9400000025", "" + f_I + s_b);
+        test("94000000null", "" + f_I + f_oN);
+        test("94000000-1410065408", "" + f_I + s_lM);
+        test("940000008.0", "" + f_I + s_d);
+        test("9400000055.0", "" + f_I + s_f);
+        test("9400000097000000", "" + f_I + s_i);
+        test("94000000-9900", "" + f_I + f_sM);
+        test("94000000935228928", "" + f_I + s_l);
+        test("94000000-8400", "" + f_I + sf_sM);
+        test("94000000C(82)", "" + f_I + s_o);
+        test("94000000null", "" + f_I + sf_oNtS);
+        test("94000000true", "" + f_I + s_bl);
+        test("940000003900", "" + f_I + s_s);
+        test("94000000null", "" + f_I + sf_oN);
+        test("9400000094000000", "" + f_I + f_I);
+        test("94000000null", "" + f_I + f_IN);
+        test("94000000true", "" + f_I + sf_bl);
+        test("940000005500", "" + f_I + sf_s);
+        test("94000000-2900", "" + f_I + s_sM);
+        test("94000000-194313216", "" + f_I + sf_l);
+        test("9400000012", "" + f_I + s_strU1);
+        test("94000000C(87)", "" + f_I + sf_o);
+        test("9400000091", "" + f_I + s_strU2);
+        test("9400000021", "" + f_I + f_strU1);
+        test("9400000018", "" + f_I + f_strU2);
+        test("94000000null", "" + f_I + f_iAN);
+        test("94000000null", "" + f_I + s_oN);
+        test("94000000\u045180", "" + f_I + s_strU);
+        test("94000000C", "" + f_I + sf_c);
+        test("9400000075", "" + f_I + sf_str);
+        test("94000000-43", "" + f_I + s_bM);
+        test("9400000080", "" + f_I + sf_b);
+        test("94000000null", "" + f_I + s_IN);
+        test("94000000-52.0", "" + f_I + s_fM);
+        test("9400000075000000", "" + f_I + sf_i);
+        test("9400000044", "" + f_I + f_b);
+        test("94000000-1705032704", "" + f_I + sf_lM);
+        test("94000000null", "" + f_I + f_oAN);
+        test("9400000083.0", "" + f_I + f_d);
+        test("94000000I", "" + f_I + f_c);
+        test("9400000094.0", "" + f_I + f_f);
+        test("9400000012.0", "" + f_I + sf_d);
+        test("94000000-99.0", "" + f_I + f_dM);
+        test("9400000017.0", "" + f_I + sf_f);
+        test("94000000-84.0", "" + f_I + sf_dM);
+        test("9400000058000000", "" + f_I + f_i);
+        test("94000000-55000000", "" + f_I + f_iM);
+        test("940000001460392448", "" + f_I + f_l);
+        test("94000000C(70)", "" + f_I + f_o);
+        test("94000000\u04511", "" + f_I + sf_strU);
+        test("940000008000", "" + f_I + f_s);
+        test("9400000018", "" + f_I + s_str);
+        test("94000000-1000000", "" + f_I + s_iM);
+        test("940000001000000", "" + f_I + sf_I);
+        test("94000000null", "" + f_I + f_oNtS);
+        test("94000000false", "" + f_I + f_bl);
+        test("94000000null", "" + f_I + sf_iAN);
+        test("94000000-2000000", "" + f_I + sf_iM);
+        test("94000000-820130816", "" + f_I + f_lM);
+        test("94000000null", "" + f_I + sf_oAN);
+        test("9400000025000000", "" + f_I + s_I);
+        test("null-96.0", "" + f_IN + s_dM);
+        test("nullnull", "" + f_IN + s_oNtS);
+        test("null\u045176", "" + f_IN + f_strU);
+        test("null92", "" + f_IN + sf_strU2);
+        test("null51", "" + f_IN + sf_strU1);
+        test("nullnull", "" + f_IN + s_iAN);
+        test("null-54", "" + f_IN + f_bM);
+        test("null-87.0", "" + f_IN + f_fM);
+        test("nullnull", "" + f_IN + s_oAN);
+        test("null19", "" + f_IN + f_str);
+        test("null-41", "" + f_IN + sf_bM);
+        test("nullnull", "" + f_IN + sf_IN);
+        test("nullT", "" + f_IN + s_c);
+        test("null-42.0", "" + f_IN + sf_fM);
+        test("null25", "" + f_IN + s_b);
+        test("nullnull", "" + f_IN + f_oN);
+        test("null-1410065408", "" + f_IN + s_lM);
+        test("null8.0", "" + f_IN + s_d);
+        test("null55.0", "" + f_IN + s_f);
+        test("null97000000", "" + f_IN + s_i);
+        test("null-9900", "" + f_IN + f_sM);
+        test("null935228928", "" + f_IN + s_l);
+        test("null-8400", "" + f_IN + sf_sM);
+        test("nullC(82)", "" + f_IN + s_o);
+        test("nullnull", "" + f_IN + sf_oNtS);
+        test("nulltrue", "" + f_IN + s_bl);
+        test("null3900", "" + f_IN + s_s);
+        test("nullnull", "" + f_IN + sf_oN);
+        test("null94000000", "" + f_IN + f_I);
+        test("nullnull", "" + f_IN + f_IN);
+        test("nulltrue", "" + f_IN + sf_bl);
+        test("null5500", "" + f_IN + sf_s);
+        test("null-2900", "" + f_IN + s_sM);
+        test("null-194313216", "" + f_IN + sf_l);
+        test("null12", "" + f_IN + s_strU1);
+        test("nullC(87)", "" + f_IN + sf_o);
+        test("null91", "" + f_IN + s_strU2);
+        test("null21", "" + f_IN + f_strU1);
+        test("null18", "" + f_IN + f_strU2);
+        test("nullnull", "" + f_IN + f_iAN);
+        test("nullnull", "" + f_IN + s_oN);
+        test("null\u045180", "" + f_IN + s_strU);
+        test("nullC", "" + f_IN + sf_c);
+        test("null75", "" + f_IN + sf_str);
+        test("null-43", "" + f_IN + s_bM);
+        test("null80", "" + f_IN + sf_b);
+        test("nullnull", "" + f_IN + s_IN);
+        test("null-52.0", "" + f_IN + s_fM);
+        test("null75000000", "" + f_IN + sf_i);
+        test("null44", "" + f_IN + f_b);
+        test("null-1705032704", "" + f_IN + sf_lM);
+        test("nullnull", "" + f_IN + f_oAN);
+        test("null83.0", "" + f_IN + f_d);
+        test("nullI", "" + f_IN + f_c);
+        test("null94.0", "" + f_IN + f_f);
+        test("null12.0", "" + f_IN + sf_d);
+        test("null-99.0", "" + f_IN + f_dM);
+        test("null17.0", "" + f_IN + sf_f);
+        test("null-84.0", "" + f_IN + sf_dM);
+        test("null58000000", "" + f_IN + f_i);
+        test("null-55000000", "" + f_IN + f_iM);
+        test("null1460392448", "" + f_IN + f_l);
+        test("nullC(70)", "" + f_IN + f_o);
+        test("null\u04511", "" + f_IN + sf_strU);
+        test("null8000", "" + f_IN + f_s);
+        test("null18", "" + f_IN + s_str);
+        test("null-1000000", "" + f_IN + s_iM);
+        test("null1000000", "" + f_IN + sf_I);
+        test("nullnull", "" + f_IN + f_oNtS);
+        test("nullfalse", "" + f_IN + f_bl);
+        test("nullnull", "" + f_IN + sf_iAN);
+        test("null-2000000", "" + f_IN + sf_iM);
+        test("null-820130816", "" + f_IN + f_lM);
+        test("nullnull", "" + f_IN + sf_oAN);
+        test("null25000000", "" + f_IN + s_I);
+        test("true-96.0", "" + sf_bl + s_dM);
+        test("truenull", "" + sf_bl + s_oNtS);
+        test("true\u045176", "" + sf_bl + f_strU);
+        test("true92", "" + sf_bl + sf_strU2);
+        test("true51", "" + sf_bl + sf_strU1);
+        test("truenull", "" + sf_bl + s_iAN);
+        test("true-54", "" + sf_bl + f_bM);
+        test("true-87.0", "" + sf_bl + f_fM);
+        test("truenull", "" + sf_bl + s_oAN);
+        test("true19", "" + sf_bl + f_str);
+        test("true-41", "" + sf_bl + sf_bM);
+        test("truenull", "" + sf_bl + sf_IN);
+        test("trueT", "" + sf_bl + s_c);
+        test("true-42.0", "" + sf_bl + sf_fM);
+        test("true25", "" + sf_bl + s_b);
+        test("truenull", "" + sf_bl + f_oN);
+        test("true-1410065408", "" + sf_bl + s_lM);
+        test("true8.0", "" + sf_bl + s_d);
+        test("true55.0", "" + sf_bl + s_f);
+        test("true97000000", "" + sf_bl + s_i);
+        test("true-9900", "" + sf_bl + f_sM);
+        test("true935228928", "" + sf_bl + s_l);
+        test("true-8400", "" + sf_bl + sf_sM);
+        test("trueC(82)", "" + sf_bl + s_o);
+        test("truenull", "" + sf_bl + sf_oNtS);
+        test("truetrue", "" + sf_bl + s_bl);
+        test("true3900", "" + sf_bl + s_s);
+        test("truenull", "" + sf_bl + sf_oN);
+        test("true94000000", "" + sf_bl + f_I);
+        test("truenull", "" + sf_bl + f_IN);
+        test("truetrue", "" + sf_bl + sf_bl);
+        test("true5500", "" + sf_bl + sf_s);
+        test("true-2900", "" + sf_bl + s_sM);
+        test("true-194313216", "" + sf_bl + sf_l);
+        test("true12", "" + sf_bl + s_strU1);
+        test("trueC(87)", "" + sf_bl + sf_o);
+        test("true91", "" + sf_bl + s_strU2);
+        test("true21", "" + sf_bl + f_strU1);
+        test("true18", "" + sf_bl + f_strU2);
+        test("truenull", "" + sf_bl + f_iAN);
+        test("truenull", "" + sf_bl + s_oN);
+        test("true\u045180", "" + sf_bl + s_strU);
+        test("trueC", "" + sf_bl + sf_c);
+        test("true75", "" + sf_bl + sf_str);
+        test("true-43", "" + sf_bl + s_bM);
+        test("true80", "" + sf_bl + sf_b);
+        test("truenull", "" + sf_bl + s_IN);
+        test("true-52.0", "" + sf_bl + s_fM);
+        test("true75000000", "" + sf_bl + sf_i);
+        test("true44", "" + sf_bl + f_b);
+        test("true-1705032704", "" + sf_bl + sf_lM);
+        test("truenull", "" + sf_bl + f_oAN);
+        test("true83.0", "" + sf_bl + f_d);
+        test("trueI", "" + sf_bl + f_c);
+        test("true94.0", "" + sf_bl + f_f);
+        test("true12.0", "" + sf_bl + sf_d);
+        test("true-99.0", "" + sf_bl + f_dM);
+        test("true17.0", "" + sf_bl + sf_f);
+        test("true-84.0", "" + sf_bl + sf_dM);
+        test("true58000000", "" + sf_bl + f_i);
+        test("true-55000000", "" + sf_bl + f_iM);
+        test("true1460392448", "" + sf_bl + f_l);
+        test("trueC(70)", "" + sf_bl + f_o);
+        test("true\u04511", "" + sf_bl + sf_strU);
+        test("true8000", "" + sf_bl + f_s);
+        test("true18", "" + sf_bl + s_str);
+        test("true-1000000", "" + sf_bl + s_iM);
+        test("true1000000", "" + sf_bl + sf_I);
+        test("truenull", "" + sf_bl + f_oNtS);
+        test("truefalse", "" + sf_bl + f_bl);
+        test("truenull", "" + sf_bl + sf_iAN);
+        test("true-2000000", "" + sf_bl + sf_iM);
+        test("true-820130816", "" + sf_bl + f_lM);
+        test("truenull", "" + sf_bl + sf_oAN);
+        test("true25000000", "" + sf_bl + s_I);
+        test("5500-96.0", "" + sf_s + s_dM);
+        test("5500null", "" + sf_s + s_oNtS);
+        test("5500\u045176", "" + sf_s + f_strU);
+        test("550092", "" + sf_s + sf_strU2);
+        test("550051", "" + sf_s + sf_strU1);
+        test("5500null", "" + sf_s + s_iAN);
+        test("5500-54", "" + sf_s + f_bM);
+        test("5500-87.0", "" + sf_s + f_fM);
+        test("5500null", "" + sf_s + s_oAN);
+        test("550019", "" + sf_s + f_str);
+        test("5500-41", "" + sf_s + sf_bM);
+        test("5500null", "" + sf_s + sf_IN);
+        test("5500T", "" + sf_s + s_c);
+        test("5500-42.0", "" + sf_s + sf_fM);
+        test("550025", "" + sf_s + s_b);
+        test("5500null", "" + sf_s + f_oN);
+        test("5500-1410065408", "" + sf_s + s_lM);
+        test("55008.0", "" + sf_s + s_d);
+        test("550055.0", "" + sf_s + s_f);
+        test("550097000000", "" + sf_s + s_i);
+        test("5500-9900", "" + sf_s + f_sM);
+        test("5500935228928", "" + sf_s + s_l);
+        test("5500-8400", "" + sf_s + sf_sM);
+        test("5500C(82)", "" + sf_s + s_o);
+        test("5500null", "" + sf_s + sf_oNtS);
+        test("5500true", "" + sf_s + s_bl);
+        test("55003900", "" + sf_s + s_s);
+        test("5500null", "" + sf_s + sf_oN);
+        test("550094000000", "" + sf_s + f_I);
+        test("5500null", "" + sf_s + f_IN);
+        test("5500true", "" + sf_s + sf_bl);
+        test("55005500", "" + sf_s + sf_s);
+        test("5500-2900", "" + sf_s + s_sM);
+        test("5500-194313216", "" + sf_s + sf_l);
+        test("550012", "" + sf_s + s_strU1);
+        test("5500C(87)", "" + sf_s + sf_o);
+        test("550091", "" + sf_s + s_strU2);
+        test("550021", "" + sf_s + f_strU1);
+        test("550018", "" + sf_s + f_strU2);
+        test("5500null", "" + sf_s + f_iAN);
+        test("5500null", "" + sf_s + s_oN);
+        test("5500\u045180", "" + sf_s + s_strU);
+        test("5500C", "" + sf_s + sf_c);
+        test("550075", "" + sf_s + sf_str);
+        test("5500-43", "" + sf_s + s_bM);
+        test("550080", "" + sf_s + sf_b);
+        test("5500null", "" + sf_s + s_IN);
+        test("5500-52.0", "" + sf_s + s_fM);
+        test("550075000000", "" + sf_s + sf_i);
+        test("550044", "" + sf_s + f_b);
+        test("5500-1705032704", "" + sf_s + sf_lM);
+        test("5500null", "" + sf_s + f_oAN);
+        test("550083.0", "" + sf_s + f_d);
+        test("5500I", "" + sf_s + f_c);
+        test("550094.0", "" + sf_s + f_f);
+        test("550012.0", "" + sf_s + sf_d);
+        test("5500-99.0", "" + sf_s + f_dM);
+        test("550017.0", "" + sf_s + sf_f);
+        test("5500-84.0", "" + sf_s + sf_dM);
+        test("550058000000", "" + sf_s + f_i);
+        test("5500-55000000", "" + sf_s + f_iM);
+        test("55001460392448", "" + sf_s + f_l);
+        test("5500C(70)", "" + sf_s + f_o);
+        test("5500\u04511", "" + sf_s + sf_strU);
+        test("55008000", "" + sf_s + f_s);
+        test("550018", "" + sf_s + s_str);
+        test("5500-1000000", "" + sf_s + s_iM);
+        test("55001000000", "" + sf_s + sf_I);
+        test("5500null", "" + sf_s + f_oNtS);
+        test("5500false", "" + sf_s + f_bl);
+        test("5500null", "" + sf_s + sf_iAN);
+        test("5500-2000000", "" + sf_s + sf_iM);
+        test("5500-820130816", "" + sf_s + f_lM);
+        test("5500null", "" + sf_s + sf_oAN);
+        test("550025000000", "" + sf_s + s_I);
+        test("-2900-96.0", "" + s_sM + s_dM);
+        test("-2900null", "" + s_sM + s_oNtS);
+        test("-2900\u045176", "" + s_sM + f_strU);
+        test("-290092", "" + s_sM + sf_strU2);
+        test("-290051", "" + s_sM + sf_strU1);
+        test("-2900null", "" + s_sM + s_iAN);
+        test("-2900-54", "" + s_sM + f_bM);
+        test("-2900-87.0", "" + s_sM + f_fM);
+        test("-2900null", "" + s_sM + s_oAN);
+        test("-290019", "" + s_sM + f_str);
+        test("-2900-41", "" + s_sM + sf_bM);
+        test("-2900null", "" + s_sM + sf_IN);
+        test("-2900T", "" + s_sM + s_c);
+        test("-2900-42.0", "" + s_sM + sf_fM);
+        test("-290025", "" + s_sM + s_b);
+        test("-2900null", "" + s_sM + f_oN);
+        test("-2900-1410065408", "" + s_sM + s_lM);
+        test("-29008.0", "" + s_sM + s_d);
+        test("-290055.0", "" + s_sM + s_f);
+        test("-290097000000", "" + s_sM + s_i);
+        test("-2900-9900", "" + s_sM + f_sM);
+        test("-2900935228928", "" + s_sM + s_l);
+        test("-2900-8400", "" + s_sM + sf_sM);
+        test("-2900C(82)", "" + s_sM + s_o);
+        test("-2900null", "" + s_sM + sf_oNtS);
+        test("-2900true", "" + s_sM + s_bl);
+        test("-29003900", "" + s_sM + s_s);
+        test("-2900null", "" + s_sM + sf_oN);
+        test("-290094000000", "" + s_sM + f_I);
+        test("-2900null", "" + s_sM + f_IN);
+        test("-2900true", "" + s_sM + sf_bl);
+        test("-29005500", "" + s_sM + sf_s);
+        test("-2900-2900", "" + s_sM + s_sM);
+        test("-2900-194313216", "" + s_sM + sf_l);
+        test("-290012", "" + s_sM + s_strU1);
+        test("-2900C(87)", "" + s_sM + sf_o);
+        test("-290091", "" + s_sM + s_strU2);
+        test("-290021", "" + s_sM + f_strU1);
+        test("-290018", "" + s_sM + f_strU2);
+        test("-2900null", "" + s_sM + f_iAN);
+        test("-2900null", "" + s_sM + s_oN);
+        test("-2900\u045180", "" + s_sM + s_strU);
+        test("-2900C", "" + s_sM + sf_c);
+        test("-290075", "" + s_sM + sf_str);
+        test("-2900-43", "" + s_sM + s_bM);
+        test("-290080", "" + s_sM + sf_b);
+        test("-2900null", "" + s_sM + s_IN);
+        test("-2900-52.0", "" + s_sM + s_fM);
+        test("-290075000000", "" + s_sM + sf_i);
+        test("-290044", "" + s_sM + f_b);
+        test("-2900-1705032704", "" + s_sM + sf_lM);
+        test("-2900null", "" + s_sM + f_oAN);
+        test("-290083.0", "" + s_sM + f_d);
+        test("-2900I", "" + s_sM + f_c);
+        test("-290094.0", "" + s_sM + f_f);
+        test("-290012.0", "" + s_sM + sf_d);
+        test("-2900-99.0", "" + s_sM + f_dM);
+        test("-290017.0", "" + s_sM + sf_f);
+        test("-2900-84.0", "" + s_sM + sf_dM);
+        test("-290058000000", "" + s_sM + f_i);
+        test("-2900-55000000", "" + s_sM + f_iM);
+        test("-29001460392448", "" + s_sM + f_l);
+        test("-2900C(70)", "" + s_sM + f_o);
+        test("-2900\u04511", "" + s_sM + sf_strU);
+        test("-29008000", "" + s_sM + f_s);
+        test("-290018", "" + s_sM + s_str);
+        test("-2900-1000000", "" + s_sM + s_iM);
+        test("-29001000000", "" + s_sM + sf_I);
+        test("-2900null", "" + s_sM + f_oNtS);
+        test("-2900false", "" + s_sM + f_bl);
+        test("-2900null", "" + s_sM + sf_iAN);
+        test("-2900-2000000", "" + s_sM + sf_iM);
+        test("-2900-820130816", "" + s_sM + f_lM);
+        test("-2900null", "" + s_sM + sf_oAN);
+        test("-290025000000", "" + s_sM + s_I);
+        test("-194313216-96.0", "" + sf_l + s_dM);
+        test("-194313216null", "" + sf_l + s_oNtS);
+        test("-194313216\u045176", "" + sf_l + f_strU);
+        test("-19431321692", "" + sf_l + sf_strU2);
+        test("-19431321651", "" + sf_l + sf_strU1);
+        test("-194313216null", "" + sf_l + s_iAN);
+        test("-194313216-54", "" + sf_l + f_bM);
+        test("-194313216-87.0", "" + sf_l + f_fM);
+        test("-194313216null", "" + sf_l + s_oAN);
+        test("-19431321619", "" + sf_l + f_str);
+        test("-194313216-41", "" + sf_l + sf_bM);
+        test("-194313216null", "" + sf_l + sf_IN);
+        test("-194313216T", "" + sf_l + s_c);
+        test("-194313216-42.0", "" + sf_l + sf_fM);
+        test("-19431321625", "" + sf_l + s_b);
+        test("-194313216null", "" + sf_l + f_oN);
+        test("-194313216-1410065408", "" + sf_l + s_lM);
+        test("-1943132168.0", "" + sf_l + s_d);
+        test("-19431321655.0", "" + sf_l + s_f);
+        test("-19431321697000000", "" + sf_l + s_i);
+        test("-194313216-9900", "" + sf_l + f_sM);
+        test("-194313216935228928", "" + sf_l + s_l);
+        test("-194313216-8400", "" + sf_l + sf_sM);
+        test("-194313216C(82)", "" + sf_l + s_o);
+        test("-194313216null", "" + sf_l + sf_oNtS);
+        test("-194313216true", "" + sf_l + s_bl);
+        test("-1943132163900", "" + sf_l + s_s);
+        test("-194313216null", "" + sf_l + sf_oN);
+        test("-19431321694000000", "" + sf_l + f_I);
+        test("-194313216null", "" + sf_l + f_IN);
+        test("-194313216true", "" + sf_l + sf_bl);
+        test("-1943132165500", "" + sf_l + sf_s);
+        test("-194313216-2900", "" + sf_l + s_sM);
+        test("-194313216-194313216", "" + sf_l + sf_l);
+        test("-19431321612", "" + sf_l + s_strU1);
+        test("-194313216C(87)", "" + sf_l + sf_o);
+        test("-19431321691", "" + sf_l + s_strU2);
+        test("-19431321621", "" + sf_l + f_strU1);
+        test("-19431321618", "" + sf_l + f_strU2);
+        test("-194313216null", "" + sf_l + f_iAN);
+        test("-194313216null", "" + sf_l + s_oN);
+        test("-194313216\u045180", "" + sf_l + s_strU);
+        test("-194313216C", "" + sf_l + sf_c);
+        test("-19431321675", "" + sf_l + sf_str);
+        test("-194313216-43", "" + sf_l + s_bM);
+        test("-19431321680", "" + sf_l + sf_b);
+        test("-194313216null", "" + sf_l + s_IN);
+        test("-194313216-52.0", "" + sf_l + s_fM);
+        test("-19431321675000000", "" + sf_l + sf_i);
+        test("-19431321644", "" + sf_l + f_b);
+        test("-194313216-1705032704", "" + sf_l + sf_lM);
+        test("-194313216null", "" + sf_l + f_oAN);
+        test("-19431321683.0", "" + sf_l + f_d);
+        test("-194313216I", "" + sf_l + f_c);
+        test("-19431321694.0", "" + sf_l + f_f);
+        test("-19431321612.0", "" + sf_l + sf_d);
+        test("-194313216-99.0", "" + sf_l + f_dM);
+        test("-19431321617.0", "" + sf_l + sf_f);
+        test("-194313216-84.0", "" + sf_l + sf_dM);
+        test("-19431321658000000", "" + sf_l + f_i);
+        test("-194313216-55000000", "" + sf_l + f_iM);
+        test("-1943132161460392448", "" + sf_l + f_l);
+        test("-194313216C(70)", "" + sf_l + f_o);
+        test("-194313216\u04511", "" + sf_l + sf_strU);
+        test("-1943132168000", "" + sf_l + f_s);
+        test("-19431321618", "" + sf_l + s_str);
+        test("-194313216-1000000", "" + sf_l + s_iM);
+        test("-1943132161000000", "" + sf_l + sf_I);
+        test("-194313216null", "" + sf_l + f_oNtS);
+        test("-194313216false", "" + sf_l + f_bl);
+        test("-194313216null", "" + sf_l + sf_iAN);
+        test("-194313216-2000000", "" + sf_l + sf_iM);
+        test("-194313216-820130816", "" + sf_l + f_lM);
+        test("-194313216null", "" + sf_l + sf_oAN);
+        test("-19431321625000000", "" + sf_l + s_I);
+        test("12-96.0", "" + s_strU1 + s_dM);
+        test("12null", "" + s_strU1 + s_oNtS);
+        test("12\u045176", "" + s_strU1 + f_strU);
+        test("1292", "" + s_strU1 + sf_strU2);
+        test("1251", "" + s_strU1 + sf_strU1);
+        test("12null", "" + s_strU1 + s_iAN);
+        test("12-54", "" + s_strU1 + f_bM);
+        test("12-87.0", "" + s_strU1 + f_fM);
+        test("12null", "" + s_strU1 + s_oAN);
+        test("1219", "" + s_strU1 + f_str);
+        test("12-41", "" + s_strU1 + sf_bM);
+        test("12null", "" + s_strU1 + sf_IN);
+        test("12T", "" + s_strU1 + s_c);
+        test("12-42.0", "" + s_strU1 + sf_fM);
+        test("1225", "" + s_strU1 + s_b);
+        test("12null", "" + s_strU1 + f_oN);
+        test("12-1410065408", "" + s_strU1 + s_lM);
+        test("128.0", "" + s_strU1 + s_d);
+        test("1255.0", "" + s_strU1 + s_f);
+        test("1297000000", "" + s_strU1 + s_i);
+        test("12-9900", "" + s_strU1 + f_sM);
+        test("12935228928", "" + s_strU1 + s_l);
+        test("12-8400", "" + s_strU1 + sf_sM);
+        test("12C(82)", "" + s_strU1 + s_o);
+        test("12null", "" + s_strU1 + sf_oNtS);
+        test("12true", "" + s_strU1 + s_bl);
+        test("123900", "" + s_strU1 + s_s);
+        test("12null", "" + s_strU1 + sf_oN);
+        test("1294000000", "" + s_strU1 + f_I);
+        test("12null", "" + s_strU1 + f_IN);
+        test("12true", "" + s_strU1 + sf_bl);
+        test("125500", "" + s_strU1 + sf_s);
+        test("12-2900", "" + s_strU1 + s_sM);
+        test("12-194313216", "" + s_strU1 + sf_l);
+        test("1212", "" + s_strU1 + s_strU1);
+        test("12C(87)", "" + s_strU1 + sf_o);
+        test("1291", "" + s_strU1 + s_strU2);
+        test("1221", "" + s_strU1 + f_strU1);
+        test("1218", "" + s_strU1 + f_strU2);
+        test("12null", "" + s_strU1 + f_iAN);
+        test("12null", "" + s_strU1 + s_oN);
+        test("12\u045180", "" + s_strU1 + s_strU);
+        test("12C", "" + s_strU1 + sf_c);
+        test("1275", "" + s_strU1 + sf_str);
+        test("12-43", "" + s_strU1 + s_bM);
+        test("1280", "" + s_strU1 + sf_b);
+        test("12null", "" + s_strU1 + s_IN);
+        test("12-52.0", "" + s_strU1 + s_fM);
+        test("1275000000", "" + s_strU1 + sf_i);
+        test("1244", "" + s_strU1 + f_b);
+        test("12-1705032704", "" + s_strU1 + sf_lM);
+        test("12null", "" + s_strU1 + f_oAN);
+        test("1283.0", "" + s_strU1 + f_d);
+        test("12I", "" + s_strU1 + f_c);
+        test("1294.0", "" + s_strU1 + f_f);
+        test("1212.0", "" + s_strU1 + sf_d);
+        test("12-99.0", "" + s_strU1 + f_dM);
+        test("1217.0", "" + s_strU1 + sf_f);
+        test("12-84.0", "" + s_strU1 + sf_dM);
+        test("1258000000", "" + s_strU1 + f_i);
+        test("12-55000000", "" + s_strU1 + f_iM);
+        test("121460392448", "" + s_strU1 + f_l);
+        test("12C(70)", "" + s_strU1 + f_o);
+        test("12\u04511", "" + s_strU1 + sf_strU);
+        test("128000", "" + s_strU1 + f_s);
+        test("1218", "" + s_strU1 + s_str);
+        test("12-1000000", "" + s_strU1 + s_iM);
+        test("121000000", "" + s_strU1 + sf_I);
+        test("12null", "" + s_strU1 + f_oNtS);
+        test("12false", "" + s_strU1 + f_bl);
+        test("12null", "" + s_strU1 + sf_iAN);
+        test("12-2000000", "" + s_strU1 + sf_iM);
+        test("12-820130816", "" + s_strU1 + f_lM);
+        test("12null", "" + s_strU1 + sf_oAN);
+        test("1225000000", "" + s_strU1 + s_I);
+        test("C(87)-96.0", "" + sf_o + s_dM);
+        test("C(87)null", "" + sf_o + s_oNtS);
+        test("C(87)\u045176", "" + sf_o + f_strU);
+        test("C(87)92", "" + sf_o + sf_strU2);
+        test("C(87)51", "" + sf_o + sf_strU1);
+        test("C(87)null", "" + sf_o + s_iAN);
+        test("C(87)-54", "" + sf_o + f_bM);
+        test("C(87)-87.0", "" + sf_o + f_fM);
+        test("C(87)null", "" + sf_o + s_oAN);
+        test("C(87)19", "" + sf_o + f_str);
+        test("C(87)-41", "" + sf_o + sf_bM);
+        test("C(87)null", "" + sf_o + sf_IN);
+        test("C(87)T", "" + sf_o + s_c);
+        test("C(87)-42.0", "" + sf_o + sf_fM);
+        test("C(87)25", "" + sf_o + s_b);
+        test("C(87)null", "" + sf_o + f_oN);
+        test("C(87)-1410065408", "" + sf_o + s_lM);
+        test("C(87)8.0", "" + sf_o + s_d);
+        test("C(87)55.0", "" + sf_o + s_f);
+        test("C(87)97000000", "" + sf_o + s_i);
+        test("C(87)-9900", "" + sf_o + f_sM);
+        test("C(87)935228928", "" + sf_o + s_l);
+        test("C(87)-8400", "" + sf_o + sf_sM);
+        test("C(87)C(82)", "" + sf_o + s_o);
+        test("C(87)null", "" + sf_o + sf_oNtS);
+        test("C(87)true", "" + sf_o + s_bl);
+        test("C(87)3900", "" + sf_o + s_s);
+        test("C(87)null", "" + sf_o + sf_oN);
+        test("C(87)94000000", "" + sf_o + f_I);
+        test("C(87)null", "" + sf_o + f_IN);
+        test("C(87)true", "" + sf_o + sf_bl);
+        test("C(87)5500", "" + sf_o + sf_s);
+        test("C(87)-2900", "" + sf_o + s_sM);
+        test("C(87)-194313216", "" + sf_o + sf_l);
+        test("C(87)12", "" + sf_o + s_strU1);
+        test("C(87)C(87)", "" + sf_o + sf_o);
+        test("C(87)91", "" + sf_o + s_strU2);
+        test("C(87)21", "" + sf_o + f_strU1);
+        test("C(87)18", "" + sf_o + f_strU2);
+        test("C(87)null", "" + sf_o + f_iAN);
+        test("C(87)null", "" + sf_o + s_oN);
+        test("C(87)\u045180", "" + sf_o + s_strU);
+        test("C(87)C", "" + sf_o + sf_c);
+        test("C(87)75", "" + sf_o + sf_str);
+        test("C(87)-43", "" + sf_o + s_bM);
+        test("C(87)80", "" + sf_o + sf_b);
+        test("C(87)null", "" + sf_o + s_IN);
+        test("C(87)-52.0", "" + sf_o + s_fM);
+        test("C(87)75000000", "" + sf_o + sf_i);
+        test("C(87)44", "" + sf_o + f_b);
+        test("C(87)-1705032704", "" + sf_o + sf_lM);
+        test("C(87)null", "" + sf_o + f_oAN);
+        test("C(87)83.0", "" + sf_o + f_d);
+        test("C(87)I", "" + sf_o + f_c);
+        test("C(87)94.0", "" + sf_o + f_f);
+        test("C(87)12.0", "" + sf_o + sf_d);
+        test("C(87)-99.0", "" + sf_o + f_dM);
+        test("C(87)17.0", "" + sf_o + sf_f);
+        test("C(87)-84.0", "" + sf_o + sf_dM);
+        test("C(87)58000000", "" + sf_o + f_i);
+        test("C(87)-55000000", "" + sf_o + f_iM);
+        test("C(87)1460392448", "" + sf_o + f_l);
+        test("C(87)C(70)", "" + sf_o + f_o);
+        test("C(87)\u04511", "" + sf_o + sf_strU);
+        test("C(87)8000", "" + sf_o + f_s);
+        test("C(87)18", "" + sf_o + s_str);
+        test("C(87)-1000000", "" + sf_o + s_iM);
+        test("C(87)1000000", "" + sf_o + sf_I);
+        test("C(87)null", "" + sf_o + f_oNtS);
+        test("C(87)false", "" + sf_o + f_bl);
+        test("C(87)null", "" + sf_o + sf_iAN);
+        test("C(87)-2000000", "" + sf_o + sf_iM);
+        test("C(87)-820130816", "" + sf_o + f_lM);
+        test("C(87)null", "" + sf_o + sf_oAN);
+        test("C(87)25000000", "" + sf_o + s_I);
+        test("91-96.0", "" + s_strU2 + s_dM);
+        test("91null", "" + s_strU2 + s_oNtS);
+        test("91\u045176", "" + s_strU2 + f_strU);
+        test("9192", "" + s_strU2 + sf_strU2);
+        test("9151", "" + s_strU2 + sf_strU1);
+        test("91null", "" + s_strU2 + s_iAN);
+        test("91-54", "" + s_strU2 + f_bM);
+        test("91-87.0", "" + s_strU2 + f_fM);
+        test("91null", "" + s_strU2 + s_oAN);
+        test("9119", "" + s_strU2 + f_str);
+        test("91-41", "" + s_strU2 + sf_bM);
+        test("91null", "" + s_strU2 + sf_IN);
+        test("91T", "" + s_strU2 + s_c);
+        test("91-42.0", "" + s_strU2 + sf_fM);
+        test("9125", "" + s_strU2 + s_b);
+        test("91null", "" + s_strU2 + f_oN);
+        test("91-1410065408", "" + s_strU2 + s_lM);
+        test("918.0", "" + s_strU2 + s_d);
+        test("9155.0", "" + s_strU2 + s_f);
+        test("9197000000", "" + s_strU2 + s_i);
+        test("91-9900", "" + s_strU2 + f_sM);
+        test("91935228928", "" + s_strU2 + s_l);
+        test("91-8400", "" + s_strU2 + sf_sM);
+        test("91C(82)", "" + s_strU2 + s_o);
+        test("91null", "" + s_strU2 + sf_oNtS);
+        test("91true", "" + s_strU2 + s_bl);
+        test("913900", "" + s_strU2 + s_s);
+        test("91null", "" + s_strU2 + sf_oN);
+        test("9194000000", "" + s_strU2 + f_I);
+        test("91null", "" + s_strU2 + f_IN);
+        test("91true", "" + s_strU2 + sf_bl);
+        test("915500", "" + s_strU2 + sf_s);
+        test("91-2900", "" + s_strU2 + s_sM);
+        test("91-194313216", "" + s_strU2 + sf_l);
+        test("9112", "" + s_strU2 + s_strU1);
+        test("91C(87)", "" + s_strU2 + sf_o);
+        test("9191", "" + s_strU2 + s_strU2);
+        test("9121", "" + s_strU2 + f_strU1);
+        test("9118", "" + s_strU2 + f_strU2);
+        test("91null", "" + s_strU2 + f_iAN);
+        test("91null", "" + s_strU2 + s_oN);
+        test("91\u045180", "" + s_strU2 + s_strU);
+        test("91C", "" + s_strU2 + sf_c);
+        test("9175", "" + s_strU2 + sf_str);
+        test("91-43", "" + s_strU2 + s_bM);
+        test("9180", "" + s_strU2 + sf_b);
+        test("91null", "" + s_strU2 + s_IN);
+        test("91-52.0", "" + s_strU2 + s_fM);
+        test("9175000000", "" + s_strU2 + sf_i);
+        test("9144", "" + s_strU2 + f_b);
+        test("91-1705032704", "" + s_strU2 + sf_lM);
+        test("91null", "" + s_strU2 + f_oAN);
+        test("9183.0", "" + s_strU2 + f_d);
+        test("91I", "" + s_strU2 + f_c);
+        test("9194.0", "" + s_strU2 + f_f);
+        test("9112.0", "" + s_strU2 + sf_d);
+        test("91-99.0", "" + s_strU2 + f_dM);
+        test("9117.0", "" + s_strU2 + sf_f);
+        test("91-84.0", "" + s_strU2 + sf_dM);
+        test("9158000000", "" + s_strU2 + f_i);
+        test("91-55000000", "" + s_strU2 + f_iM);
+        test("911460392448", "" + s_strU2 + f_l);
+        test("91C(70)", "" + s_strU2 + f_o);
+        test("91\u04511", "" + s_strU2 + sf_strU);
+        test("918000", "" + s_strU2 + f_s);
+        test("9118", "" + s_strU2 + s_str);
+        test("91-1000000", "" + s_strU2 + s_iM);
+        test("911000000", "" + s_strU2 + sf_I);
+        test("91null", "" + s_strU2 + f_oNtS);
+        test("91false", "" + s_strU2 + f_bl);
+        test("91null", "" + s_strU2 + sf_iAN);
+        test("91-2000000", "" + s_strU2 + sf_iM);
+        test("91-820130816", "" + s_strU2 + f_lM);
+        test("91null", "" + s_strU2 + sf_oAN);
+        test("9125000000", "" + s_strU2 + s_I);
+        test("21-96.0", "" + f_strU1 + s_dM);
+        test("21null", "" + f_strU1 + s_oNtS);
+        test("21\u045176", "" + f_strU1 + f_strU);
+        test("2192", "" + f_strU1 + sf_strU2);
+        test("2151", "" + f_strU1 + sf_strU1);
+        test("21null", "" + f_strU1 + s_iAN);
+        test("21-54", "" + f_strU1 + f_bM);
+        test("21-87.0", "" + f_strU1 + f_fM);
+        test("21null", "" + f_strU1 + s_oAN);
+        test("2119", "" + f_strU1 + f_str);
+        test("21-41", "" + f_strU1 + sf_bM);
+        test("21null", "" + f_strU1 + sf_IN);
+        test("21T", "" + f_strU1 + s_c);
+        test("21-42.0", "" + f_strU1 + sf_fM);
+        test("2125", "" + f_strU1 + s_b);
+        test("21null", "" + f_strU1 + f_oN);
+        test("21-1410065408", "" + f_strU1 + s_lM);
+        test("218.0", "" + f_strU1 + s_d);
+        test("2155.0", "" + f_strU1 + s_f);
+        test("2197000000", "" + f_strU1 + s_i);
+        test("21-9900", "" + f_strU1 + f_sM);
+        test("21935228928", "" + f_strU1 + s_l);
+        test("21-8400", "" + f_strU1 + sf_sM);
+        test("21C(82)", "" + f_strU1 + s_o);
+        test("21null", "" + f_strU1 + sf_oNtS);
+        test("21true", "" + f_strU1 + s_bl);
+        test("213900", "" + f_strU1 + s_s);
+        test("21null", "" + f_strU1 + sf_oN);
+        test("2194000000", "" + f_strU1 + f_I);
+        test("21null", "" + f_strU1 + f_IN);
+        test("21true", "" + f_strU1 + sf_bl);
+        test("215500", "" + f_strU1 + sf_s);
+        test("21-2900", "" + f_strU1 + s_sM);
+        test("21-194313216", "" + f_strU1 + sf_l);
+        test("2112", "" + f_strU1 + s_strU1);
+        test("21C(87)", "" + f_strU1 + sf_o);
+        test("2191", "" + f_strU1 + s_strU2);
+        test("2121", "" + f_strU1 + f_strU1);
+        test("2118", "" + f_strU1 + f_strU2);
+        test("21null", "" + f_strU1 + f_iAN);
+        test("21null", "" + f_strU1 + s_oN);
+        test("21\u045180", "" + f_strU1 + s_strU);
+        test("21C", "" + f_strU1 + sf_c);
+        test("2175", "" + f_strU1 + sf_str);
+        test("21-43", "" + f_strU1 + s_bM);
+        test("2180", "" + f_strU1 + sf_b);
+        test("21null", "" + f_strU1 + s_IN);
+        test("21-52.0", "" + f_strU1 + s_fM);
+        test("2175000000", "" + f_strU1 + sf_i);
+        test("2144", "" + f_strU1 + f_b);
+        test("21-1705032704", "" + f_strU1 + sf_lM);
+        test("21null", "" + f_strU1 + f_oAN);
+        test("2183.0", "" + f_strU1 + f_d);
+        test("21I", "" + f_strU1 + f_c);
+        test("2194.0", "" + f_strU1 + f_f);
+        test("2112.0", "" + f_strU1 + sf_d);
+        test("21-99.0", "" + f_strU1 + f_dM);
+        test("2117.0", "" + f_strU1 + sf_f);
+        test("21-84.0", "" + f_strU1 + sf_dM);
+        test("2158000000", "" + f_strU1 + f_i);
+        test("21-55000000", "" + f_strU1 + f_iM);
+        test("211460392448", "" + f_strU1 + f_l);
+        test("21C(70)", "" + f_strU1 + f_o);
+        test("21\u04511", "" + f_strU1 + sf_strU);
+        test("218000", "" + f_strU1 + f_s);
+        test("2118", "" + f_strU1 + s_str);
+        test("21-1000000", "" + f_strU1 + s_iM);
+        test("211000000", "" + f_strU1 + sf_I);
+        test("21null", "" + f_strU1 + f_oNtS);
+        test("21false", "" + f_strU1 + f_bl);
+        test("21null", "" + f_strU1 + sf_iAN);
+        test("21-2000000", "" + f_strU1 + sf_iM);
+        test("21-820130816", "" + f_strU1 + f_lM);
+        test("21null", "" + f_strU1 + sf_oAN);
+        test("2125000000", "" + f_strU1 + s_I);
+        test("18-96.0", "" + f_strU2 + s_dM);
+        test("18null", "" + f_strU2 + s_oNtS);
+        test("18\u045176", "" + f_strU2 + f_strU);
+        test("1892", "" + f_strU2 + sf_strU2);
+        test("1851", "" + f_strU2 + sf_strU1);
+        test("18null", "" + f_strU2 + s_iAN);
+        test("18-54", "" + f_strU2 + f_bM);
+        test("18-87.0", "" + f_strU2 + f_fM);
+        test("18null", "" + f_strU2 + s_oAN);
+        test("1819", "" + f_strU2 + f_str);
+        test("18-41", "" + f_strU2 + sf_bM);
+        test("18null", "" + f_strU2 + sf_IN);
+        test("18T", "" + f_strU2 + s_c);
+        test("18-42.0", "" + f_strU2 + sf_fM);
+        test("1825", "" + f_strU2 + s_b);
+        test("18null", "" + f_strU2 + f_oN);
+        test("18-1410065408", "" + f_strU2 + s_lM);
+        test("188.0", "" + f_strU2 + s_d);
+        test("1855.0", "" + f_strU2 + s_f);
+        test("1897000000", "" + f_strU2 + s_i);
+        test("18-9900", "" + f_strU2 + f_sM);
+        test("18935228928", "" + f_strU2 + s_l);
+        test("18-8400", "" + f_strU2 + sf_sM);
+        test("18C(82)", "" + f_strU2 + s_o);
+        test("18null", "" + f_strU2 + sf_oNtS);
+        test("18true", "" + f_strU2 + s_bl);
+        test("183900", "" + f_strU2 + s_s);
+        test("18null", "" + f_strU2 + sf_oN);
+        test("1894000000", "" + f_strU2 + f_I);
+        test("18null", "" + f_strU2 + f_IN);
+        test("18true", "" + f_strU2 + sf_bl);
+        test("185500", "" + f_strU2 + sf_s);
+        test("18-2900", "" + f_strU2 + s_sM);
+        test("18-194313216", "" + f_strU2 + sf_l);
+        test("1812", "" + f_strU2 + s_strU1);
+        test("18C(87)", "" + f_strU2 + sf_o);
+        test("1891", "" + f_strU2 + s_strU2);
+        test("1821", "" + f_strU2 + f_strU1);
+        test("1818", "" + f_strU2 + f_strU2);
+        test("18null", "" + f_strU2 + f_iAN);
+        test("18null", "" + f_strU2 + s_oN);
+        test("18\u045180", "" + f_strU2 + s_strU);
+        test("18C", "" + f_strU2 + sf_c);
+        test("1875", "" + f_strU2 + sf_str);
+        test("18-43", "" + f_strU2 + s_bM);
+        test("1880", "" + f_strU2 + sf_b);
+        test("18null", "" + f_strU2 + s_IN);
+        test("18-52.0", "" + f_strU2 + s_fM);
+        test("1875000000", "" + f_strU2 + sf_i);
+        test("1844", "" + f_strU2 + f_b);
+        test("18-1705032704", "" + f_strU2 + sf_lM);
+        test("18null", "" + f_strU2 + f_oAN);
+        test("1883.0", "" + f_strU2 + f_d);
+        test("18I", "" + f_strU2 + f_c);
+        test("1894.0", "" + f_strU2 + f_f);
+        test("1812.0", "" + f_strU2 + sf_d);
+        test("18-99.0", "" + f_strU2 + f_dM);
+        test("1817.0", "" + f_strU2 + sf_f);
+        test("18-84.0", "" + f_strU2 + sf_dM);
+        test("1858000000", "" + f_strU2 + f_i);
+        test("18-55000000", "" + f_strU2 + f_iM);
+        test("181460392448", "" + f_strU2 + f_l);
+        test("18C(70)", "" + f_strU2 + f_o);
+        test("18\u04511", "" + f_strU2 + sf_strU);
+        test("188000", "" + f_strU2 + f_s);
+        test("1818", "" + f_strU2 + s_str);
+        test("18-1000000", "" + f_strU2 + s_iM);
+        test("181000000", "" + f_strU2 + sf_I);
+        test("18null", "" + f_strU2 + f_oNtS);
+        test("18false", "" + f_strU2 + f_bl);
+        test("18null", "" + f_strU2 + sf_iAN);
+        test("18-2000000", "" + f_strU2 + sf_iM);
+        test("18-820130816", "" + f_strU2 + f_lM);
+        test("18null", "" + f_strU2 + sf_oAN);
+        test("1825000000", "" + f_strU2 + s_I);
+    }
+
+    public void run3() {
+        test("null-96.0", "" + f_iAN + s_dM);
+        test("nullnull", "" + f_iAN + s_oNtS);
+        test("null\u045176", "" + f_iAN + f_strU);
+        test("null92", "" + f_iAN + sf_strU2);
+        test("null51", "" + f_iAN + sf_strU1);
+        test("nullnull", "" + f_iAN + s_iAN);
+        test("null-54", "" + f_iAN + f_bM);
+        test("null-87.0", "" + f_iAN + f_fM);
+        test("nullnull", "" + f_iAN + s_oAN);
+        test("null19", "" + f_iAN + f_str);
+        test("null-41", "" + f_iAN + sf_bM);
+        test("nullnull", "" + f_iAN + sf_IN);
+        test("nullT", "" + f_iAN + s_c);
+        test("null-42.0", "" + f_iAN + sf_fM);
+        test("null25", "" + f_iAN + s_b);
+        test("nullnull", "" + f_iAN + f_oN);
+        test("null-1410065408", "" + f_iAN + s_lM);
+        test("null8.0", "" + f_iAN + s_d);
+        test("null55.0", "" + f_iAN + s_f);
+        test("null97000000", "" + f_iAN + s_i);
+        test("null-9900", "" + f_iAN + f_sM);
+        test("null935228928", "" + f_iAN + s_l);
+        test("null-8400", "" + f_iAN + sf_sM);
+        test("nullC(82)", "" + f_iAN + s_o);
+        test("nullnull", "" + f_iAN + sf_oNtS);
+        test("nulltrue", "" + f_iAN + s_bl);
+        test("null3900", "" + f_iAN + s_s);
+        test("nullnull", "" + f_iAN + sf_oN);
+        test("null94000000", "" + f_iAN + f_I);
+        test("nullnull", "" + f_iAN + f_IN);
+        test("nulltrue", "" + f_iAN + sf_bl);
+        test("null5500", "" + f_iAN + sf_s);
+        test("null-2900", "" + f_iAN + s_sM);
+        test("null-194313216", "" + f_iAN + sf_l);
+        test("null12", "" + f_iAN + s_strU1);
+        test("nullC(87)", "" + f_iAN + sf_o);
+        test("null91", "" + f_iAN + s_strU2);
+        test("null21", "" + f_iAN + f_strU1);
+        test("null18", "" + f_iAN + f_strU2);
+        test("nullnull", "" + f_iAN + f_iAN);
+        test("nullnull", "" + f_iAN + s_oN);
+        test("null\u045180", "" + f_iAN + s_strU);
+        test("nullC", "" + f_iAN + sf_c);
+        test("null75", "" + f_iAN + sf_str);
+        test("null-43", "" + f_iAN + s_bM);
+        test("null80", "" + f_iAN + sf_b);
+        test("nullnull", "" + f_iAN + s_IN);
+        test("null-52.0", "" + f_iAN + s_fM);
+        test("null75000000", "" + f_iAN + sf_i);
+        test("null44", "" + f_iAN + f_b);
+        test("null-1705032704", "" + f_iAN + sf_lM);
+        test("nullnull", "" + f_iAN + f_oAN);
+        test("null83.0", "" + f_iAN + f_d);
+        test("nullI", "" + f_iAN + f_c);
+        test("null94.0", "" + f_iAN + f_f);
+        test("null12.0", "" + f_iAN + sf_d);
+        test("null-99.0", "" + f_iAN + f_dM);
+        test("null17.0", "" + f_iAN + sf_f);
+        test("null-84.0", "" + f_iAN + sf_dM);
+        test("null58000000", "" + f_iAN + f_i);
+        test("null-55000000", "" + f_iAN + f_iM);
+        test("null1460392448", "" + f_iAN + f_l);
+        test("nullC(70)", "" + f_iAN + f_o);
+        test("null\u04511", "" + f_iAN + sf_strU);
+        test("null8000", "" + f_iAN + f_s);
+        test("null18", "" + f_iAN + s_str);
+        test("null-1000000", "" + f_iAN + s_iM);
+        test("null1000000", "" + f_iAN + sf_I);
+        test("nullnull", "" + f_iAN + f_oNtS);
+        test("nullfalse", "" + f_iAN + f_bl);
+        test("nullnull", "" + f_iAN + sf_iAN);
+        test("null-2000000", "" + f_iAN + sf_iM);
+        test("null-820130816", "" + f_iAN + f_lM);
+        test("nullnull", "" + f_iAN + sf_oAN);
+        test("null25000000", "" + f_iAN + s_I);
+        test("null-96.0", "" + s_oN + s_dM);
+        test("nullnull", "" + s_oN + s_oNtS);
+        test("null\u045176", "" + s_oN + f_strU);
+        test("null92", "" + s_oN + sf_strU2);
+        test("null51", "" + s_oN + sf_strU1);
+        test("nullnull", "" + s_oN + s_iAN);
+        test("null-54", "" + s_oN + f_bM);
+        test("null-87.0", "" + s_oN + f_fM);
+        test("nullnull", "" + s_oN + s_oAN);
+        test("null19", "" + s_oN + f_str);
+        test("null-41", "" + s_oN + sf_bM);
+        test("nullnull", "" + s_oN + sf_IN);
+        test("nullT", "" + s_oN + s_c);
+        test("null-42.0", "" + s_oN + sf_fM);
+        test("null25", "" + s_oN + s_b);
+        test("nullnull", "" + s_oN + f_oN);
+        test("null-1410065408", "" + s_oN + s_lM);
+        test("null8.0", "" + s_oN + s_d);
+        test("null55.0", "" + s_oN + s_f);
+        test("null97000000", "" + s_oN + s_i);
+        test("null-9900", "" + s_oN + f_sM);
+        test("null935228928", "" + s_oN + s_l);
+        test("null-8400", "" + s_oN + sf_sM);
+        test("nullC(82)", "" + s_oN + s_o);
+        test("nullnull", "" + s_oN + sf_oNtS);
+        test("nulltrue", "" + s_oN + s_bl);
+        test("null3900", "" + s_oN + s_s);
+        test("nullnull", "" + s_oN + sf_oN);
+        test("null94000000", "" + s_oN + f_I);
+        test("nullnull", "" + s_oN + f_IN);
+        test("nulltrue", "" + s_oN + sf_bl);
+        test("null5500", "" + s_oN + sf_s);
+        test("null-2900", "" + s_oN + s_sM);
+        test("null-194313216", "" + s_oN + sf_l);
+        test("null12", "" + s_oN + s_strU1);
+        test("nullC(87)", "" + s_oN + sf_o);
+        test("null91", "" + s_oN + s_strU2);
+        test("null21", "" + s_oN + f_strU1);
+        test("null18", "" + s_oN + f_strU2);
+        test("nullnull", "" + s_oN + f_iAN);
+        test("nullnull", "" + s_oN + s_oN);
+        test("null\u045180", "" + s_oN + s_strU);
+        test("nullC", "" + s_oN + sf_c);
+        test("null75", "" + s_oN + sf_str);
+        test("null-43", "" + s_oN + s_bM);
+        test("null80", "" + s_oN + sf_b);
+        test("nullnull", "" + s_oN + s_IN);
+        test("null-52.0", "" + s_oN + s_fM);
+        test("null75000000", "" + s_oN + sf_i);
+        test("null44", "" + s_oN + f_b);
+        test("null-1705032704", "" + s_oN + sf_lM);
+        test("nullnull", "" + s_oN + f_oAN);
+        test("null83.0", "" + s_oN + f_d);
+        test("nullI", "" + s_oN + f_c);
+        test("null94.0", "" + s_oN + f_f);
+        test("null12.0", "" + s_oN + sf_d);
+        test("null-99.0", "" + s_oN + f_dM);
+        test("null17.0", "" + s_oN + sf_f);
+        test("null-84.0", "" + s_oN + sf_dM);
+        test("null58000000", "" + s_oN + f_i);
+        test("null-55000000", "" + s_oN + f_iM);
+        test("null1460392448", "" + s_oN + f_l);
+        test("nullC(70)", "" + s_oN + f_o);
+        test("null\u04511", "" + s_oN + sf_strU);
+        test("null8000", "" + s_oN + f_s);
+        test("null18", "" + s_oN + s_str);
+        test("null-1000000", "" + s_oN + s_iM);
+        test("null1000000", "" + s_oN + sf_I);
+        test("nullnull", "" + s_oN + f_oNtS);
+        test("nullfalse", "" + s_oN + f_bl);
+        test("nullnull", "" + s_oN + sf_iAN);
+        test("null-2000000", "" + s_oN + sf_iM);
+        test("null-820130816", "" + s_oN + f_lM);
+        test("nullnull", "" + s_oN + sf_oAN);
+        test("null25000000", "" + s_oN + s_I);
+        test("\u045180-96.0", "" + s_strU + s_dM);
+        test("\u045180null", "" + s_strU + s_oNtS);
+        test("\u045180\u045176", "" + s_strU + f_strU);
+        test("\u04518092", "" + s_strU + sf_strU2);
+        test("\u04518051", "" + s_strU + sf_strU1);
+        test("\u045180null", "" + s_strU + s_iAN);
+        test("\u045180-54", "" + s_strU + f_bM);
+        test("\u045180-87.0", "" + s_strU + f_fM);
+        test("\u045180null", "" + s_strU + s_oAN);
+        test("\u04518019", "" + s_strU + f_str);
+        test("\u045180-41", "" + s_strU + sf_bM);
+        test("\u045180null", "" + s_strU + sf_IN);
+        test("\u045180T", "" + s_strU + s_c);
+        test("\u045180-42.0", "" + s_strU + sf_fM);
+        test("\u04518025", "" + s_strU + s_b);
+        test("\u045180null", "" + s_strU + f_oN);
+        test("\u045180-1410065408", "" + s_strU + s_lM);
+        test("\u0451808.0", "" + s_strU + s_d);
+        test("\u04518055.0", "" + s_strU + s_f);
+        test("\u04518097000000", "" + s_strU + s_i);
+        test("\u045180-9900", "" + s_strU + f_sM);
+        test("\u045180935228928", "" + s_strU + s_l);
+        test("\u045180-8400", "" + s_strU + sf_sM);
+        test("\u045180C(82)", "" + s_strU + s_o);
+        test("\u045180null", "" + s_strU + sf_oNtS);
+        test("\u045180true", "" + s_strU + s_bl);
+        test("\u0451803900", "" + s_strU + s_s);
+        test("\u045180null", "" + s_strU + sf_oN);
+        test("\u04518094000000", "" + s_strU + f_I);
+        test("\u045180null", "" + s_strU + f_IN);
+        test("\u045180true", "" + s_strU + sf_bl);
+        test("\u0451805500", "" + s_strU + sf_s);
+        test("\u045180-2900", "" + s_strU + s_sM);
+        test("\u045180-194313216", "" + s_strU + sf_l);
+        test("\u04518012", "" + s_strU + s_strU1);
+        test("\u045180C(87)", "" + s_strU + sf_o);
+        test("\u04518091", "" + s_strU + s_strU2);
+        test("\u04518021", "" + s_strU + f_strU1);
+        test("\u04518018", "" + s_strU + f_strU2);
+        test("\u045180null", "" + s_strU + f_iAN);
+        test("\u045180null", "" + s_strU + s_oN);
+        test("\u045180\u045180", "" + s_strU + s_strU);
+        test("\u045180C", "" + s_strU + sf_c);
+        test("\u04518075", "" + s_strU + sf_str);
+        test("\u045180-43", "" + s_strU + s_bM);
+        test("\u04518080", "" + s_strU + sf_b);
+        test("\u045180null", "" + s_strU + s_IN);
+        test("\u045180-52.0", "" + s_strU + s_fM);
+        test("\u04518075000000", "" + s_strU + sf_i);
+        test("\u04518044", "" + s_strU + f_b);
+        test("\u045180-1705032704", "" + s_strU + sf_lM);
+        test("\u045180null", "" + s_strU + f_oAN);
+        test("\u04518083.0", "" + s_strU + f_d);
+        test("\u045180I", "" + s_strU + f_c);
+        test("\u04518094.0", "" + s_strU + f_f);
+        test("\u04518012.0", "" + s_strU + sf_d);
+        test("\u045180-99.0", "" + s_strU + f_dM);
+        test("\u04518017.0", "" + s_strU + sf_f);
+        test("\u045180-84.0", "" + s_strU + sf_dM);
+        test("\u04518058000000", "" + s_strU + f_i);
+        test("\u045180-55000000", "" + s_strU + f_iM);
+        test("\u0451801460392448", "" + s_strU + f_l);
+        test("\u045180C(70)", "" + s_strU + f_o);
+        test("\u045180\u04511", "" + s_strU + sf_strU);
+        test("\u0451808000", "" + s_strU + f_s);
+        test("\u04518018", "" + s_strU + s_str);
+        test("\u045180-1000000", "" + s_strU + s_iM);
+        test("\u0451801000000", "" + s_strU + sf_I);
+        test("\u045180null", "" + s_strU + f_oNtS);
+        test("\u045180false", "" + s_strU + f_bl);
+        test("\u045180null", "" + s_strU + sf_iAN);
+        test("\u045180-2000000", "" + s_strU + sf_iM);
+        test("\u045180-820130816", "" + s_strU + f_lM);
+        test("\u045180null", "" + s_strU + sf_oAN);
+        test("\u04518025000000", "" + s_strU + s_I);
+        test("C-96.0", "" + sf_c + s_dM);
+        test("Cnull", "" + sf_c + s_oNtS);
+        test("C\u045176", "" + sf_c + f_strU);
+        test("C92", "" + sf_c + sf_strU2);
+        test("C51", "" + sf_c + sf_strU1);
+        test("Cnull", "" + sf_c + s_iAN);
+        test("C-54", "" + sf_c + f_bM);
+        test("C-87.0", "" + sf_c + f_fM);
+        test("Cnull", "" + sf_c + s_oAN);
+        test("C19", "" + sf_c + f_str);
+        test("C-41", "" + sf_c + sf_bM);
+        test("Cnull", "" + sf_c + sf_IN);
+        test("CT", "" + sf_c + s_c);
+        test("C-42.0", "" + sf_c + sf_fM);
+        test("C25", "" + sf_c + s_b);
+        test("Cnull", "" + sf_c + f_oN);
+        test("C-1410065408", "" + sf_c + s_lM);
+        test("C8.0", "" + sf_c + s_d);
+        test("C55.0", "" + sf_c + s_f);
+        test("C97000000", "" + sf_c + s_i);
+        test("C-9900", "" + sf_c + f_sM);
+        test("C935228928", "" + sf_c + s_l);
+        test("C-8400", "" + sf_c + sf_sM);
+        test("CC(82)", "" + sf_c + s_o);
+        test("Cnull", "" + sf_c + sf_oNtS);
+        test("Ctrue", "" + sf_c + s_bl);
+        test("C3900", "" + sf_c + s_s);
+        test("Cnull", "" + sf_c + sf_oN);
+        test("C94000000", "" + sf_c + f_I);
+        test("Cnull", "" + sf_c + f_IN);
+        test("Ctrue", "" + sf_c + sf_bl);
+        test("C5500", "" + sf_c + sf_s);
+        test("C-2900", "" + sf_c + s_sM);
+        test("C-194313216", "" + sf_c + sf_l);
+        test("C12", "" + sf_c + s_strU1);
+        test("CC(87)", "" + sf_c + sf_o);
+        test("C91", "" + sf_c + s_strU2);
+        test("C21", "" + sf_c + f_strU1);
+        test("C18", "" + sf_c + f_strU2);
+        test("Cnull", "" + sf_c + f_iAN);
+        test("Cnull", "" + sf_c + s_oN);
+        test("C\u045180", "" + sf_c + s_strU);
+        test("CC", "" + sf_c + sf_c);
+        test("C75", "" + sf_c + sf_str);
+        test("C-43", "" + sf_c + s_bM);
+        test("C80", "" + sf_c + sf_b);
+        test("Cnull", "" + sf_c + s_IN);
+        test("C-52.0", "" + sf_c + s_fM);
+        test("C75000000", "" + sf_c + sf_i);
+        test("C44", "" + sf_c + f_b);
+        test("C-1705032704", "" + sf_c + sf_lM);
+        test("Cnull", "" + sf_c + f_oAN);
+        test("C83.0", "" + sf_c + f_d);
+        test("CI", "" + sf_c + f_c);
+        test("C94.0", "" + sf_c + f_f);
+        test("C12.0", "" + sf_c + sf_d);
+        test("C-99.0", "" + sf_c + f_dM);
+        test("C17.0", "" + sf_c + sf_f);
+        test("C-84.0", "" + sf_c + sf_dM);
+        test("C58000000", "" + sf_c + f_i);
+        test("C-55000000", "" + sf_c + f_iM);
+        test("C1460392448", "" + sf_c + f_l);
+        test("CC(70)", "" + sf_c + f_o);
+        test("C\u04511", "" + sf_c + sf_strU);
+        test("C8000", "" + sf_c + f_s);
+        test("C18", "" + sf_c + s_str);
+        test("C-1000000", "" + sf_c + s_iM);
+        test("C1000000", "" + sf_c + sf_I);
+        test("Cnull", "" + sf_c + f_oNtS);
+        test("Cfalse", "" + sf_c + f_bl);
+        test("Cnull", "" + sf_c + sf_iAN);
+        test("C-2000000", "" + sf_c + sf_iM);
+        test("C-820130816", "" + sf_c + f_lM);
+        test("Cnull", "" + sf_c + sf_oAN);
+        test("C25000000", "" + sf_c + s_I);
+        test("75-96.0", "" + sf_str + s_dM);
+        test("75null", "" + sf_str + s_oNtS);
+        test("75\u045176", "" + sf_str + f_strU);
+        test("7592", "" + sf_str + sf_strU2);
+        test("7551", "" + sf_str + sf_strU1);
+        test("75null", "" + sf_str + s_iAN);
+        test("75-54", "" + sf_str + f_bM);
+        test("75-87.0", "" + sf_str + f_fM);
+        test("75null", "" + sf_str + s_oAN);
+        test("7519", "" + sf_str + f_str);
+        test("75-41", "" + sf_str + sf_bM);
+        test("75null", "" + sf_str + sf_IN);
+        test("75T", "" + sf_str + s_c);
+        test("75-42.0", "" + sf_str + sf_fM);
+        test("7525", "" + sf_str + s_b);
+        test("75null", "" + sf_str + f_oN);
+        test("75-1410065408", "" + sf_str + s_lM);
+        test("758.0", "" + sf_str + s_d);
+        test("7555.0", "" + sf_str + s_f);
+        test("7597000000", "" + sf_str + s_i);
+        test("75-9900", "" + sf_str + f_sM);
+        test("75935228928", "" + sf_str + s_l);
+        test("75-8400", "" + sf_str + sf_sM);
+        test("75C(82)", "" + sf_str + s_o);
+        test("75null", "" + sf_str + sf_oNtS);
+        test("75true", "" + sf_str + s_bl);
+        test("753900", "" + sf_str + s_s);
+        test("75null", "" + sf_str + sf_oN);
+        test("7594000000", "" + sf_str + f_I);
+        test("75null", "" + sf_str + f_IN);
+        test("75true", "" + sf_str + sf_bl);
+        test("755500", "" + sf_str + sf_s);
+        test("75-2900", "" + sf_str + s_sM);
+        test("75-194313216", "" + sf_str + sf_l);
+        test("7512", "" + sf_str + s_strU1);
+        test("75C(87)", "" + sf_str + sf_o);
+        test("7591", "" + sf_str + s_strU2);
+        test("7521", "" + sf_str + f_strU1);
+        test("7518", "" + sf_str + f_strU2);
+        test("75null", "" + sf_str + f_iAN);
+        test("75null", "" + sf_str + s_oN);
+        test("75\u045180", "" + sf_str + s_strU);
+        test("75C", "" + sf_str + sf_c);
+        test("7575", "" + sf_str + sf_str);
+        test("75-43", "" + sf_str + s_bM);
+        test("7580", "" + sf_str + sf_b);
+        test("75null", "" + sf_str + s_IN);
+        test("75-52.0", "" + sf_str + s_fM);
+        test("7575000000", "" + sf_str + sf_i);
+        test("7544", "" + sf_str + f_b);
+        test("75-1705032704", "" + sf_str + sf_lM);
+        test("75null", "" + sf_str + f_oAN);
+        test("7583.0", "" + sf_str + f_d);
+        test("75I", "" + sf_str + f_c);
+        test("7594.0", "" + sf_str + f_f);
+        test("7512.0", "" + sf_str + sf_d);
+        test("75-99.0", "" + sf_str + f_dM);
+        test("7517.0", "" + sf_str + sf_f);
+        test("75-84.0", "" + sf_str + sf_dM);
+        test("7558000000", "" + sf_str + f_i);
+        test("75-55000000", "" + sf_str + f_iM);
+        test("751460392448", "" + sf_str + f_l);
+        test("75C(70)", "" + sf_str + f_o);
+        test("75\u04511", "" + sf_str + sf_strU);
+        test("758000", "" + sf_str + f_s);
+        test("7518", "" + sf_str + s_str);
+        test("75-1000000", "" + sf_str + s_iM);
+        test("751000000", "" + sf_str + sf_I);
+        test("75null", "" + sf_str + f_oNtS);
+        test("75false", "" + sf_str + f_bl);
+        test("75null", "" + sf_str + sf_iAN);
+        test("75-2000000", "" + sf_str + sf_iM);
+        test("75-820130816", "" + sf_str + f_lM);
+        test("75null", "" + sf_str + sf_oAN);
+        test("7525000000", "" + sf_str + s_I);
+        test("-43-96.0", "" + s_bM + s_dM);
+        test("-43null", "" + s_bM + s_oNtS);
+        test("-43\u045176", "" + s_bM + f_strU);
+        test("-4392", "" + s_bM + sf_strU2);
+        test("-4351", "" + s_bM + sf_strU1);
+        test("-43null", "" + s_bM + s_iAN);
+        test("-43-54", "" + s_bM + f_bM);
+        test("-43-87.0", "" + s_bM + f_fM);
+        test("-43null", "" + s_bM + s_oAN);
+        test("-4319", "" + s_bM + f_str);
+        test("-43-41", "" + s_bM + sf_bM);
+        test("-43null", "" + s_bM + sf_IN);
+        test("-43T", "" + s_bM + s_c);
+        test("-43-42.0", "" + s_bM + sf_fM);
+        test("-4325", "" + s_bM + s_b);
+        test("-43null", "" + s_bM + f_oN);
+        test("-43-1410065408", "" + s_bM + s_lM);
+        test("-438.0", "" + s_bM + s_d);
+        test("-4355.0", "" + s_bM + s_f);
+        test("-4397000000", "" + s_bM + s_i);
+        test("-43-9900", "" + s_bM + f_sM);
+        test("-43935228928", "" + s_bM + s_l);
+        test("-43-8400", "" + s_bM + sf_sM);
+        test("-43C(82)", "" + s_bM + s_o);
+        test("-43null", "" + s_bM + sf_oNtS);
+        test("-43true", "" + s_bM + s_bl);
+        test("-433900", "" + s_bM + s_s);
+        test("-43null", "" + s_bM + sf_oN);
+        test("-4394000000", "" + s_bM + f_I);
+        test("-43null", "" + s_bM + f_IN);
+        test("-43true", "" + s_bM + sf_bl);
+        test("-435500", "" + s_bM + sf_s);
+        test("-43-2900", "" + s_bM + s_sM);
+        test("-43-194313216", "" + s_bM + sf_l);
+        test("-4312", "" + s_bM + s_strU1);
+        test("-43C(87)", "" + s_bM + sf_o);
+        test("-4391", "" + s_bM + s_strU2);
+        test("-4321", "" + s_bM + f_strU1);
+        test("-4318", "" + s_bM + f_strU2);
+        test("-43null", "" + s_bM + f_iAN);
+        test("-43null", "" + s_bM + s_oN);
+        test("-43\u045180", "" + s_bM + s_strU);
+        test("-43C", "" + s_bM + sf_c);
+        test("-4375", "" + s_bM + sf_str);
+        test("-43-43", "" + s_bM + s_bM);
+        test("-4380", "" + s_bM + sf_b);
+        test("-43null", "" + s_bM + s_IN);
+        test("-43-52.0", "" + s_bM + s_fM);
+        test("-4375000000", "" + s_bM + sf_i);
+        test("-4344", "" + s_bM + f_b);
+        test("-43-1705032704", "" + s_bM + sf_lM);
+        test("-43null", "" + s_bM + f_oAN);
+        test("-4383.0", "" + s_bM + f_d);
+        test("-43I", "" + s_bM + f_c);
+        test("-4394.0", "" + s_bM + f_f);
+        test("-4312.0", "" + s_bM + sf_d);
+        test("-43-99.0", "" + s_bM + f_dM);
+        test("-4317.0", "" + s_bM + sf_f);
+        test("-43-84.0", "" + s_bM + sf_dM);
+        test("-4358000000", "" + s_bM + f_i);
+        test("-43-55000000", "" + s_bM + f_iM);
+        test("-431460392448", "" + s_bM + f_l);
+        test("-43C(70)", "" + s_bM + f_o);
+        test("-43\u04511", "" + s_bM + sf_strU);
+        test("-438000", "" + s_bM + f_s);
+        test("-4318", "" + s_bM + s_str);
+        test("-43-1000000", "" + s_bM + s_iM);
+        test("-431000000", "" + s_bM + sf_I);
+        test("-43null", "" + s_bM + f_oNtS);
+        test("-43false", "" + s_bM + f_bl);
+        test("-43null", "" + s_bM + sf_iAN);
+        test("-43-2000000", "" + s_bM + sf_iM);
+        test("-43-820130816", "" + s_bM + f_lM);
+        test("-43null", "" + s_bM + sf_oAN);
+        test("-4325000000", "" + s_bM + s_I);
+        test("80-96.0", "" + sf_b + s_dM);
+        test("80null", "" + sf_b + s_oNtS);
+        test("80\u045176", "" + sf_b + f_strU);
+        test("8092", "" + sf_b + sf_strU2);
+        test("8051", "" + sf_b + sf_strU1);
+        test("80null", "" + sf_b + s_iAN);
+        test("80-54", "" + sf_b + f_bM);
+        test("80-87.0", "" + sf_b + f_fM);
+        test("80null", "" + sf_b + s_oAN);
+        test("8019", "" + sf_b + f_str);
+        test("80-41", "" + sf_b + sf_bM);
+        test("80null", "" + sf_b + sf_IN);
+        test("80T", "" + sf_b + s_c);
+        test("80-42.0", "" + sf_b + sf_fM);
+        test("8025", "" + sf_b + s_b);
+        test("80null", "" + sf_b + f_oN);
+        test("80-1410065408", "" + sf_b + s_lM);
+        test("808.0", "" + sf_b + s_d);
+        test("8055.0", "" + sf_b + s_f);
+        test("8097000000", "" + sf_b + s_i);
+        test("80-9900", "" + sf_b + f_sM);
+        test("80935228928", "" + sf_b + s_l);
+        test("80-8400", "" + sf_b + sf_sM);
+        test("80C(82)", "" + sf_b + s_o);
+        test("80null", "" + sf_b + sf_oNtS);
+        test("80true", "" + sf_b + s_bl);
+        test("803900", "" + sf_b + s_s);
+        test("80null", "" + sf_b + sf_oN);
+        test("8094000000", "" + sf_b + f_I);
+        test("80null", "" + sf_b + f_IN);
+        test("80true", "" + sf_b + sf_bl);
+        test("805500", "" + sf_b + sf_s);
+        test("80-2900", "" + sf_b + s_sM);
+        test("80-194313216", "" + sf_b + sf_l);
+        test("8012", "" + sf_b + s_strU1);
+        test("80C(87)", "" + sf_b + sf_o);
+        test("8091", "" + sf_b + s_strU2);
+        test("8021", "" + sf_b + f_strU1);
+        test("8018", "" + sf_b + f_strU2);
+        test("80null", "" + sf_b + f_iAN);
+        test("80null", "" + sf_b + s_oN);
+        test("80\u045180", "" + sf_b + s_strU);
+        test("80C", "" + sf_b + sf_c);
+        test("8075", "" + sf_b + sf_str);
+        test("80-43", "" + sf_b + s_bM);
+        test("8080", "" + sf_b + sf_b);
+        test("80null", "" + sf_b + s_IN);
+        test("80-52.0", "" + sf_b + s_fM);
+        test("8075000000", "" + sf_b + sf_i);
+        test("8044", "" + sf_b + f_b);
+        test("80-1705032704", "" + sf_b + sf_lM);
+        test("80null", "" + sf_b + f_oAN);
+        test("8083.0", "" + sf_b + f_d);
+        test("80I", "" + sf_b + f_c);
+        test("8094.0", "" + sf_b + f_f);
+        test("8012.0", "" + sf_b + sf_d);
+        test("80-99.0", "" + sf_b + f_dM);
+        test("8017.0", "" + sf_b + sf_f);
+        test("80-84.0", "" + sf_b + sf_dM);
+        test("8058000000", "" + sf_b + f_i);
+        test("80-55000000", "" + sf_b + f_iM);
+        test("801460392448", "" + sf_b + f_l);
+        test("80C(70)", "" + sf_b + f_o);
+        test("80\u04511", "" + sf_b + sf_strU);
+        test("808000", "" + sf_b + f_s);
+        test("8018", "" + sf_b + s_str);
+        test("80-1000000", "" + sf_b + s_iM);
+        test("801000000", "" + sf_b + sf_I);
+        test("80null", "" + sf_b + f_oNtS);
+        test("80false", "" + sf_b + f_bl);
+        test("80null", "" + sf_b + sf_iAN);
+        test("80-2000000", "" + sf_b + sf_iM);
+        test("80-820130816", "" + sf_b + f_lM);
+        test("80null", "" + sf_b + sf_oAN);
+        test("8025000000", "" + sf_b + s_I);
+        test("null-96.0", "" + s_IN + s_dM);
+        test("nullnull", "" + s_IN + s_oNtS);
+        test("null\u045176", "" + s_IN + f_strU);
+        test("null92", "" + s_IN + sf_strU2);
+        test("null51", "" + s_IN + sf_strU1);
+        test("nullnull", "" + s_IN + s_iAN);
+        test("null-54", "" + s_IN + f_bM);
+        test("null-87.0", "" + s_IN + f_fM);
+        test("nullnull", "" + s_IN + s_oAN);
+        test("null19", "" + s_IN + f_str);
+        test("null-41", "" + s_IN + sf_bM);
+        test("nullnull", "" + s_IN + sf_IN);
+        test("nullT", "" + s_IN + s_c);
+        test("null-42.0", "" + s_IN + sf_fM);
+        test("null25", "" + s_IN + s_b);
+        test("nullnull", "" + s_IN + f_oN);
+        test("null-1410065408", "" + s_IN + s_lM);
+        test("null8.0", "" + s_IN + s_d);
+        test("null55.0", "" + s_IN + s_f);
+        test("null97000000", "" + s_IN + s_i);
+        test("null-9900", "" + s_IN + f_sM);
+        test("null935228928", "" + s_IN + s_l);
+        test("null-8400", "" + s_IN + sf_sM);
+        test("nullC(82)", "" + s_IN + s_o);
+        test("nullnull", "" + s_IN + sf_oNtS);
+        test("nulltrue", "" + s_IN + s_bl);
+        test("null3900", "" + s_IN + s_s);
+        test("nullnull", "" + s_IN + sf_oN);
+        test("null94000000", "" + s_IN + f_I);
+        test("nullnull", "" + s_IN + f_IN);
+        test("nulltrue", "" + s_IN + sf_bl);
+        test("null5500", "" + s_IN + sf_s);
+        test("null-2900", "" + s_IN + s_sM);
+        test("null-194313216", "" + s_IN + sf_l);
+        test("null12", "" + s_IN + s_strU1);
+        test("nullC(87)", "" + s_IN + sf_o);
+        test("null91", "" + s_IN + s_strU2);
+        test("null21", "" + s_IN + f_strU1);
+        test("null18", "" + s_IN + f_strU2);
+        test("nullnull", "" + s_IN + f_iAN);
+        test("nullnull", "" + s_IN + s_oN);
+        test("null\u045180", "" + s_IN + s_strU);
+        test("nullC", "" + s_IN + sf_c);
+        test("null75", "" + s_IN + sf_str);
+        test("null-43", "" + s_IN + s_bM);
+        test("null80", "" + s_IN + sf_b);
+        test("nullnull", "" + s_IN + s_IN);
+        test("null-52.0", "" + s_IN + s_fM);
+        test("null75000000", "" + s_IN + sf_i);
+        test("null44", "" + s_IN + f_b);
+        test("null-1705032704", "" + s_IN + sf_lM);
+        test("nullnull", "" + s_IN + f_oAN);
+        test("null83.0", "" + s_IN + f_d);
+        test("nullI", "" + s_IN + f_c);
+        test("null94.0", "" + s_IN + f_f);
+        test("null12.0", "" + s_IN + sf_d);
+        test("null-99.0", "" + s_IN + f_dM);
+        test("null17.0", "" + s_IN + sf_f);
+        test("null-84.0", "" + s_IN + sf_dM);
+        test("null58000000", "" + s_IN + f_i);
+        test("null-55000000", "" + s_IN + f_iM);
+        test("null1460392448", "" + s_IN + f_l);
+        test("nullC(70)", "" + s_IN + f_o);
+        test("null\u04511", "" + s_IN + sf_strU);
+        test("null8000", "" + s_IN + f_s);
+        test("null18", "" + s_IN + s_str);
+        test("null-1000000", "" + s_IN + s_iM);
+        test("null1000000", "" + s_IN + sf_I);
+        test("nullnull", "" + s_IN + f_oNtS);
+        test("nullfalse", "" + s_IN + f_bl);
+        test("nullnull", "" + s_IN + sf_iAN);
+        test("null-2000000", "" + s_IN + sf_iM);
+        test("null-820130816", "" + s_IN + f_lM);
+        test("nullnull", "" + s_IN + sf_oAN);
+        test("null25000000", "" + s_IN + s_I);
+        test("-52.0-96.0", "" + s_fM + s_dM);
+        test("-52.0null", "" + s_fM + s_oNtS);
+        test("-52.0\u045176", "" + s_fM + f_strU);
+        test("-52.092", "" + s_fM + sf_strU2);
+        test("-52.051", "" + s_fM + sf_strU1);
+        test("-52.0null", "" + s_fM + s_iAN);
+        test("-52.0-54", "" + s_fM + f_bM);
+        test("-52.0-87.0", "" + s_fM + f_fM);
+        test("-52.0null", "" + s_fM + s_oAN);
+        test("-52.019", "" + s_fM + f_str);
+        test("-52.0-41", "" + s_fM + sf_bM);
+        test("-52.0null", "" + s_fM + sf_IN);
+        test("-52.0T", "" + s_fM + s_c);
+        test("-52.0-42.0", "" + s_fM + sf_fM);
+        test("-52.025", "" + s_fM + s_b);
+        test("-52.0null", "" + s_fM + f_oN);
+        test("-52.0-1410065408", "" + s_fM + s_lM);
+        test("-52.08.0", "" + s_fM + s_d);
+        test("-52.055.0", "" + s_fM + s_f);
+        test("-52.097000000", "" + s_fM + s_i);
+        test("-52.0-9900", "" + s_fM + f_sM);
+        test("-52.0935228928", "" + s_fM + s_l);
+        test("-52.0-8400", "" + s_fM + sf_sM);
+        test("-52.0C(82)", "" + s_fM + s_o);
+        test("-52.0null", "" + s_fM + sf_oNtS);
+        test("-52.0true", "" + s_fM + s_bl);
+        test("-52.03900", "" + s_fM + s_s);
+        test("-52.0null", "" + s_fM + sf_oN);
+        test("-52.094000000", "" + s_fM + f_I);
+        test("-52.0null", "" + s_fM + f_IN);
+        test("-52.0true", "" + s_fM + sf_bl);
+        test("-52.05500", "" + s_fM + sf_s);
+        test("-52.0-2900", "" + s_fM + s_sM);
+        test("-52.0-194313216", "" + s_fM + sf_l);
+        test("-52.012", "" + s_fM + s_strU1);
+        test("-52.0C(87)", "" + s_fM + sf_o);
+        test("-52.091", "" + s_fM + s_strU2);
+        test("-52.021", "" + s_fM + f_strU1);
+        test("-52.018", "" + s_fM + f_strU2);
+        test("-52.0null", "" + s_fM + f_iAN);
+        test("-52.0null", "" + s_fM + s_oN);
+        test("-52.0\u045180", "" + s_fM + s_strU);
+        test("-52.0C", "" + s_fM + sf_c);
+        test("-52.075", "" + s_fM + sf_str);
+        test("-52.0-43", "" + s_fM + s_bM);
+        test("-52.080", "" + s_fM + sf_b);
+        test("-52.0null", "" + s_fM + s_IN);
+        test("-52.0-52.0", "" + s_fM + s_fM);
+        test("-52.075000000", "" + s_fM + sf_i);
+        test("-52.044", "" + s_fM + f_b);
+        test("-52.0-1705032704", "" + s_fM + sf_lM);
+        test("-52.0null", "" + s_fM + f_oAN);
+        test("-52.083.0", "" + s_fM + f_d);
+        test("-52.0I", "" + s_fM + f_c);
+        test("-52.094.0", "" + s_fM + f_f);
+        test("-52.012.0", "" + s_fM + sf_d);
+        test("-52.0-99.0", "" + s_fM + f_dM);
+        test("-52.017.0", "" + s_fM + sf_f);
+        test("-52.0-84.0", "" + s_fM + sf_dM);
+        test("-52.058000000", "" + s_fM + f_i);
+        test("-52.0-55000000", "" + s_fM + f_iM);
+        test("-52.01460392448", "" + s_fM + f_l);
+        test("-52.0C(70)", "" + s_fM + f_o);
+        test("-52.0\u04511", "" + s_fM + sf_strU);
+        test("-52.08000", "" + s_fM + f_s);
+        test("-52.018", "" + s_fM + s_str);
+        test("-52.0-1000000", "" + s_fM + s_iM);
+        test("-52.01000000", "" + s_fM + sf_I);
+        test("-52.0null", "" + s_fM + f_oNtS);
+        test("-52.0false", "" + s_fM + f_bl);
+        test("-52.0null", "" + s_fM + sf_iAN);
+        test("-52.0-2000000", "" + s_fM + sf_iM);
+        test("-52.0-820130816", "" + s_fM + f_lM);
+        test("-52.0null", "" + s_fM + sf_oAN);
+        test("-52.025000000", "" + s_fM + s_I);
+        test("75000000-96.0", "" + sf_i + s_dM);
+        test("75000000null", "" + sf_i + s_oNtS);
+        test("75000000\u045176", "" + sf_i + f_strU);
+        test("7500000092", "" + sf_i + sf_strU2);
+        test("7500000051", "" + sf_i + sf_strU1);
+        test("75000000null", "" + sf_i + s_iAN);
+        test("75000000-54", "" + sf_i + f_bM);
+        test("75000000-87.0", "" + sf_i + f_fM);
+        test("75000000null", "" + sf_i + s_oAN);
+        test("7500000019", "" + sf_i + f_str);
+        test("75000000-41", "" + sf_i + sf_bM);
+        test("75000000null", "" + sf_i + sf_IN);
+        test("75000000T", "" + sf_i + s_c);
+        test("75000000-42.0", "" + sf_i + sf_fM);
+        test("7500000025", "" + sf_i + s_b);
+        test("75000000null", "" + sf_i + f_oN);
+        test("75000000-1410065408", "" + sf_i + s_lM);
+        test("750000008.0", "" + sf_i + s_d);
+        test("7500000055.0", "" + sf_i + s_f);
+        test("7500000097000000", "" + sf_i + s_i);
+        test("75000000-9900", "" + sf_i + f_sM);
+        test("75000000935228928", "" + sf_i + s_l);
+        test("75000000-8400", "" + sf_i + sf_sM);
+        test("75000000C(82)", "" + sf_i + s_o);
+        test("75000000null", "" + sf_i + sf_oNtS);
+        test("75000000true", "" + sf_i + s_bl);
+        test("750000003900", "" + sf_i + s_s);
+        test("75000000null", "" + sf_i + sf_oN);
+        test("7500000094000000", "" + sf_i + f_I);
+        test("75000000null", "" + sf_i + f_IN);
+        test("75000000true", "" + sf_i + sf_bl);
+        test("750000005500", "" + sf_i + sf_s);
+        test("75000000-2900", "" + sf_i + s_sM);
+        test("75000000-194313216", "" + sf_i + sf_l);
+        test("7500000012", "" + sf_i + s_strU1);
+        test("75000000C(87)", "" + sf_i + sf_o);
+        test("7500000091", "" + sf_i + s_strU2);
+        test("7500000021", "" + sf_i + f_strU1);
+        test("7500000018", "" + sf_i + f_strU2);
+        test("75000000null", "" + sf_i + f_iAN);
+        test("75000000null", "" + sf_i + s_oN);
+        test("75000000\u045180", "" + sf_i + s_strU);
+        test("75000000C", "" + sf_i + sf_c);
+        test("7500000075", "" + sf_i + sf_str);
+        test("75000000-43", "" + sf_i + s_bM);
+        test("7500000080", "" + sf_i + sf_b);
+        test("75000000null", "" + sf_i + s_IN);
+        test("75000000-52.0", "" + sf_i + s_fM);
+        test("7500000075000000", "" + sf_i + sf_i);
+        test("7500000044", "" + sf_i + f_b);
+        test("75000000-1705032704", "" + sf_i + sf_lM);
+        test("75000000null", "" + sf_i + f_oAN);
+        test("7500000083.0", "" + sf_i + f_d);
+        test("75000000I", "" + sf_i + f_c);
+        test("7500000094.0", "" + sf_i + f_f);
+        test("7500000012.0", "" + sf_i + sf_d);
+        test("75000000-99.0", "" + sf_i + f_dM);
+        test("7500000017.0", "" + sf_i + sf_f);
+        test("75000000-84.0", "" + sf_i + sf_dM);
+        test("7500000058000000", "" + sf_i + f_i);
+        test("75000000-55000000", "" + sf_i + f_iM);
+        test("750000001460392448", "" + sf_i + f_l);
+        test("75000000C(70)", "" + sf_i + f_o);
+        test("75000000\u04511", "" + sf_i + sf_strU);
+        test("750000008000", "" + sf_i + f_s);
+        test("7500000018", "" + sf_i + s_str);
+        test("75000000-1000000", "" + sf_i + s_iM);
+        test("750000001000000", "" + sf_i + sf_I);
+        test("75000000null", "" + sf_i + f_oNtS);
+        test("75000000false", "" + sf_i + f_bl);
+        test("75000000null", "" + sf_i + sf_iAN);
+        test("75000000-2000000", "" + sf_i + sf_iM);
+        test("75000000-820130816", "" + sf_i + f_lM);
+        test("75000000null", "" + sf_i + sf_oAN);
+        test("7500000025000000", "" + sf_i + s_I);
+        test("44-96.0", "" + f_b + s_dM);
+        test("44null", "" + f_b + s_oNtS);
+        test("44\u045176", "" + f_b + f_strU);
+        test("4492", "" + f_b + sf_strU2);
+        test("4451", "" + f_b + sf_strU1);
+        test("44null", "" + f_b + s_iAN);
+        test("44-54", "" + f_b + f_bM);
+        test("44-87.0", "" + f_b + f_fM);
+        test("44null", "" + f_b + s_oAN);
+        test("4419", "" + f_b + f_str);
+        test("44-41", "" + f_b + sf_bM);
+        test("44null", "" + f_b + sf_IN);
+        test("44T", "" + f_b + s_c);
+        test("44-42.0", "" + f_b + sf_fM);
+        test("4425", "" + f_b + s_b);
+        test("44null", "" + f_b + f_oN);
+        test("44-1410065408", "" + f_b + s_lM);
+        test("448.0", "" + f_b + s_d);
+        test("4455.0", "" + f_b + s_f);
+        test("4497000000", "" + f_b + s_i);
+        test("44-9900", "" + f_b + f_sM);
+        test("44935228928", "" + f_b + s_l);
+        test("44-8400", "" + f_b + sf_sM);
+        test("44C(82)", "" + f_b + s_o);
+        test("44null", "" + f_b + sf_oNtS);
+        test("44true", "" + f_b + s_bl);
+        test("443900", "" + f_b + s_s);
+        test("44null", "" + f_b + sf_oN);
+        test("4494000000", "" + f_b + f_I);
+        test("44null", "" + f_b + f_IN);
+        test("44true", "" + f_b + sf_bl);
+        test("445500", "" + f_b + sf_s);
+        test("44-2900", "" + f_b + s_sM);
+        test("44-194313216", "" + f_b + sf_l);
+        test("4412", "" + f_b + s_strU1);
+        test("44C(87)", "" + f_b + sf_o);
+        test("4491", "" + f_b + s_strU2);
+        test("4421", "" + f_b + f_strU1);
+        test("4418", "" + f_b + f_strU2);
+        test("44null", "" + f_b + f_iAN);
+        test("44null", "" + f_b + s_oN);
+        test("44\u045180", "" + f_b + s_strU);
+        test("44C", "" + f_b + sf_c);
+        test("4475", "" + f_b + sf_str);
+        test("44-43", "" + f_b + s_bM);
+        test("4480", "" + f_b + sf_b);
+        test("44null", "" + f_b + s_IN);
+        test("44-52.0", "" + f_b + s_fM);
+        test("4475000000", "" + f_b + sf_i);
+        test("4444", "" + f_b + f_b);
+        test("44-1705032704", "" + f_b + sf_lM);
+        test("44null", "" + f_b + f_oAN);
+        test("4483.0", "" + f_b + f_d);
+        test("44I", "" + f_b + f_c);
+        test("4494.0", "" + f_b + f_f);
+        test("4412.0", "" + f_b + sf_d);
+        test("44-99.0", "" + f_b + f_dM);
+        test("4417.0", "" + f_b + sf_f);
+        test("44-84.0", "" + f_b + sf_dM);
+        test("4458000000", "" + f_b + f_i);
+        test("44-55000000", "" + f_b + f_iM);
+        test("441460392448", "" + f_b + f_l);
+        test("44C(70)", "" + f_b + f_o);
+        test("44\u04511", "" + f_b + sf_strU);
+        test("448000", "" + f_b + f_s);
+        test("4418", "" + f_b + s_str);
+        test("44-1000000", "" + f_b + s_iM);
+        test("441000000", "" + f_b + sf_I);
+        test("44null", "" + f_b + f_oNtS);
+        test("44false", "" + f_b + f_bl);
+        test("44null", "" + f_b + sf_iAN);
+        test("44-2000000", "" + f_b + sf_iM);
+        test("44-820130816", "" + f_b + f_lM);
+        test("44null", "" + f_b + sf_oAN);
+        test("4425000000", "" + f_b + s_I);
+        test("-1705032704-96.0", "" + sf_lM + s_dM);
+        test("-1705032704null", "" + sf_lM + s_oNtS);
+        test("-1705032704\u045176", "" + sf_lM + f_strU);
+        test("-170503270492", "" + sf_lM + sf_strU2);
+        test("-170503270451", "" + sf_lM + sf_strU1);
+        test("-1705032704null", "" + sf_lM + s_iAN);
+        test("-1705032704-54", "" + sf_lM + f_bM);
+        test("-1705032704-87.0", "" + sf_lM + f_fM);
+        test("-1705032704null", "" + sf_lM + s_oAN);
+        test("-170503270419", "" + sf_lM + f_str);
+        test("-1705032704-41", "" + sf_lM + sf_bM);
+        test("-1705032704null", "" + sf_lM + sf_IN);
+        test("-1705032704T", "" + sf_lM + s_c);
+        test("-1705032704-42.0", "" + sf_lM + sf_fM);
+        test("-170503270425", "" + sf_lM + s_b);
+        test("-1705032704null", "" + sf_lM + f_oN);
+        test("-1705032704-1410065408", "" + sf_lM + s_lM);
+        test("-17050327048.0", "" + sf_lM + s_d);
+        test("-170503270455.0", "" + sf_lM + s_f);
+        test("-170503270497000000", "" + sf_lM + s_i);
+        test("-1705032704-9900", "" + sf_lM + f_sM);
+        test("-1705032704935228928", "" + sf_lM + s_l);
+        test("-1705032704-8400", "" + sf_lM + sf_sM);
+        test("-1705032704C(82)", "" + sf_lM + s_o);
+        test("-1705032704null", "" + sf_lM + sf_oNtS);
+        test("-1705032704true", "" + sf_lM + s_bl);
+        test("-17050327043900", "" + sf_lM + s_s);
+        test("-1705032704null", "" + sf_lM + sf_oN);
+        test("-170503270494000000", "" + sf_lM + f_I);
+        test("-1705032704null", "" + sf_lM + f_IN);
+        test("-1705032704true", "" + sf_lM + sf_bl);
+        test("-17050327045500", "" + sf_lM + sf_s);
+        test("-1705032704-2900", "" + sf_lM + s_sM);
+        test("-1705032704-194313216", "" + sf_lM + sf_l);
+        test("-170503270412", "" + sf_lM + s_strU1);
+        test("-1705032704C(87)", "" + sf_lM + sf_o);
+        test("-170503270491", "" + sf_lM + s_strU2);
+        test("-170503270421", "" + sf_lM + f_strU1);
+        test("-170503270418", "" + sf_lM + f_strU2);
+        test("-1705032704null", "" + sf_lM + f_iAN);
+        test("-1705032704null", "" + sf_lM + s_oN);
+        test("-1705032704\u045180", "" + sf_lM + s_strU);
+        test("-1705032704C", "" + sf_lM + sf_c);
+        test("-170503270475", "" + sf_lM + sf_str);
+        test("-1705032704-43", "" + sf_lM + s_bM);
+        test("-170503270480", "" + sf_lM + sf_b);
+        test("-1705032704null", "" + sf_lM + s_IN);
+        test("-1705032704-52.0", "" + sf_lM + s_fM);
+        test("-170503270475000000", "" + sf_lM + sf_i);
+        test("-170503270444", "" + sf_lM + f_b);
+        test("-1705032704-1705032704", "" + sf_lM + sf_lM);
+        test("-1705032704null", "" + sf_lM + f_oAN);
+        test("-170503270483.0", "" + sf_lM + f_d);
+        test("-1705032704I", "" + sf_lM + f_c);
+        test("-170503270494.0", "" + sf_lM + f_f);
+        test("-170503270412.0", "" + sf_lM + sf_d);
+        test("-1705032704-99.0", "" + sf_lM + f_dM);
+        test("-170503270417.0", "" + sf_lM + sf_f);
+        test("-1705032704-84.0", "" + sf_lM + sf_dM);
+        test("-170503270458000000", "" + sf_lM + f_i);
+        test("-1705032704-55000000", "" + sf_lM + f_iM);
+        test("-17050327041460392448", "" + sf_lM + f_l);
+        test("-1705032704C(70)", "" + sf_lM + f_o);
+        test("-1705032704\u04511", "" + sf_lM + sf_strU);
+        test("-17050327048000", "" + sf_lM + f_s);
+        test("-170503270418", "" + sf_lM + s_str);
+        test("-1705032704-1000000", "" + sf_lM + s_iM);
+        test("-17050327041000000", "" + sf_lM + sf_I);
+        test("-1705032704null", "" + sf_lM + f_oNtS);
+        test("-1705032704false", "" + sf_lM + f_bl);
+        test("-1705032704null", "" + sf_lM + sf_iAN);
+        test("-1705032704-2000000", "" + sf_lM + sf_iM);
+        test("-1705032704-820130816", "" + sf_lM + f_lM);
+        test("-1705032704null", "" + sf_lM + sf_oAN);
+        test("-170503270425000000", "" + sf_lM + s_I);
+        test("null-96.0", "" + f_oAN + s_dM);
+        test("nullnull", "" + f_oAN + s_oNtS);
+        test("null\u045176", "" + f_oAN + f_strU);
+        test("null92", "" + f_oAN + sf_strU2);
+        test("null51", "" + f_oAN + sf_strU1);
+        test("nullnull", "" + f_oAN + s_iAN);
+        test("null-54", "" + f_oAN + f_bM);
+        test("null-87.0", "" + f_oAN + f_fM);
+        test("nullnull", "" + f_oAN + s_oAN);
+        test("null19", "" + f_oAN + f_str);
+        test("null-41", "" + f_oAN + sf_bM);
+        test("nullnull", "" + f_oAN + sf_IN);
+        test("nullT", "" + f_oAN + s_c);
+        test("null-42.0", "" + f_oAN + sf_fM);
+        test("null25", "" + f_oAN + s_b);
+        test("nullnull", "" + f_oAN + f_oN);
+        test("null-1410065408", "" + f_oAN + s_lM);
+        test("null8.0", "" + f_oAN + s_d);
+        test("null55.0", "" + f_oAN + s_f);
+        test("null97000000", "" + f_oAN + s_i);
+        test("null-9900", "" + f_oAN + f_sM);
+        test("null935228928", "" + f_oAN + s_l);
+        test("null-8400", "" + f_oAN + sf_sM);
+        test("nullC(82)", "" + f_oAN + s_o);
+        test("nullnull", "" + f_oAN + sf_oNtS);
+        test("nulltrue", "" + f_oAN + s_bl);
+        test("null3900", "" + f_oAN + s_s);
+        test("nullnull", "" + f_oAN + sf_oN);
+        test("null94000000", "" + f_oAN + f_I);
+        test("nullnull", "" + f_oAN + f_IN);
+        test("nulltrue", "" + f_oAN + sf_bl);
+        test("null5500", "" + f_oAN + sf_s);
+        test("null-2900", "" + f_oAN + s_sM);
+        test("null-194313216", "" + f_oAN + sf_l);
+        test("null12", "" + f_oAN + s_strU1);
+        test("nullC(87)", "" + f_oAN + sf_o);
+        test("null91", "" + f_oAN + s_strU2);
+        test("null21", "" + f_oAN + f_strU1);
+        test("null18", "" + f_oAN + f_strU2);
+        test("nullnull", "" + f_oAN + f_iAN);
+        test("nullnull", "" + f_oAN + s_oN);
+        test("null\u045180", "" + f_oAN + s_strU);
+        test("nullC", "" + f_oAN + sf_c);
+        test("null75", "" + f_oAN + sf_str);
+        test("null-43", "" + f_oAN + s_bM);
+        test("null80", "" + f_oAN + sf_b);
+        test("nullnull", "" + f_oAN + s_IN);
+        test("null-52.0", "" + f_oAN + s_fM);
+        test("null75000000", "" + f_oAN + sf_i);
+        test("null44", "" + f_oAN + f_b);
+        test("null-1705032704", "" + f_oAN + sf_lM);
+        test("nullnull", "" + f_oAN + f_oAN);
+        test("null83.0", "" + f_oAN + f_d);
+        test("nullI", "" + f_oAN + f_c);
+        test("null94.0", "" + f_oAN + f_f);
+        test("null12.0", "" + f_oAN + sf_d);
+        test("null-99.0", "" + f_oAN + f_dM);
+        test("null17.0", "" + f_oAN + sf_f);
+        test("null-84.0", "" + f_oAN + sf_dM);
+        test("null58000000", "" + f_oAN + f_i);
+        test("null-55000000", "" + f_oAN + f_iM);
+        test("null1460392448", "" + f_oAN + f_l);
+        test("nullC(70)", "" + f_oAN + f_o);
+        test("null\u04511", "" + f_oAN + sf_strU);
+        test("null8000", "" + f_oAN + f_s);
+        test("null18", "" + f_oAN + s_str);
+        test("null-1000000", "" + f_oAN + s_iM);
+        test("null1000000", "" + f_oAN + sf_I);
+        test("nullnull", "" + f_oAN + f_oNtS);
+        test("nullfalse", "" + f_oAN + f_bl);
+        test("nullnull", "" + f_oAN + sf_iAN);
+        test("null-2000000", "" + f_oAN + sf_iM);
+        test("null-820130816", "" + f_oAN + f_lM);
+        test("nullnull", "" + f_oAN + sf_oAN);
+        test("null25000000", "" + f_oAN + s_I);
+        test("83.0-96.0", "" + f_d + s_dM);
+        test("83.0null", "" + f_d + s_oNtS);
+        test("83.0\u045176", "" + f_d + f_strU);
+        test("83.092", "" + f_d + sf_strU2);
+        test("83.051", "" + f_d + sf_strU1);
+        test("83.0null", "" + f_d + s_iAN);
+        test("83.0-54", "" + f_d + f_bM);
+        test("83.0-87.0", "" + f_d + f_fM);
+        test("83.0null", "" + f_d + s_oAN);
+        test("83.019", "" + f_d + f_str);
+        test("83.0-41", "" + f_d + sf_bM);
+        test("83.0null", "" + f_d + sf_IN);
+        test("83.0T", "" + f_d + s_c);
+        test("83.0-42.0", "" + f_d + sf_fM);
+        test("83.025", "" + f_d + s_b);
+        test("83.0null", "" + f_d + f_oN);
+        test("83.0-1410065408", "" + f_d + s_lM);
+        test("83.08.0", "" + f_d + s_d);
+        test("83.055.0", "" + f_d + s_f);
+        test("83.097000000", "" + f_d + s_i);
+        test("83.0-9900", "" + f_d + f_sM);
+        test("83.0935228928", "" + f_d + s_l);
+        test("83.0-8400", "" + f_d + sf_sM);
+        test("83.0C(82)", "" + f_d + s_o);
+        test("83.0null", "" + f_d + sf_oNtS);
+    }
+
+    public void run4() {
+        test("83.0true", "" + f_d + s_bl);
+        test("83.03900", "" + f_d + s_s);
+        test("83.0null", "" + f_d + sf_oN);
+        test("83.094000000", "" + f_d + f_I);
+        test("83.0null", "" + f_d + f_IN);
+        test("83.0true", "" + f_d + sf_bl);
+        test("83.05500", "" + f_d + sf_s);
+        test("83.0-2900", "" + f_d + s_sM);
+        test("83.0-194313216", "" + f_d + sf_l);
+        test("83.012", "" + f_d + s_strU1);
+        test("83.0C(87)", "" + f_d + sf_o);
+        test("83.091", "" + f_d + s_strU2);
+        test("83.021", "" + f_d + f_strU1);
+        test("83.018", "" + f_d + f_strU2);
+        test("83.0null", "" + f_d + f_iAN);
+        test("83.0null", "" + f_d + s_oN);
+        test("83.0\u045180", "" + f_d + s_strU);
+        test("83.0C", "" + f_d + sf_c);
+        test("83.075", "" + f_d + sf_str);
+        test("83.0-43", "" + f_d + s_bM);
+        test("83.080", "" + f_d + sf_b);
+        test("83.0null", "" + f_d + s_IN);
+        test("83.0-52.0", "" + f_d + s_fM);
+        test("83.075000000", "" + f_d + sf_i);
+        test("83.044", "" + f_d + f_b);
+        test("83.0-1705032704", "" + f_d + sf_lM);
+        test("83.0null", "" + f_d + f_oAN);
+        test("83.083.0", "" + f_d + f_d);
+        test("83.0I", "" + f_d + f_c);
+        test("83.094.0", "" + f_d + f_f);
+        test("83.012.0", "" + f_d + sf_d);
+        test("83.0-99.0", "" + f_d + f_dM);
+        test("83.017.0", "" + f_d + sf_f);
+        test("83.0-84.0", "" + f_d + sf_dM);
+        test("83.058000000", "" + f_d + f_i);
+        test("83.0-55000000", "" + f_d + f_iM);
+        test("83.01460392448", "" + f_d + f_l);
+        test("83.0C(70)", "" + f_d + f_o);
+        test("83.0\u04511", "" + f_d + sf_strU);
+        test("83.08000", "" + f_d + f_s);
+        test("83.018", "" + f_d + s_str);
+        test("83.0-1000000", "" + f_d + s_iM);
+        test("83.01000000", "" + f_d + sf_I);
+        test("83.0null", "" + f_d + f_oNtS);
+        test("83.0false", "" + f_d + f_bl);
+        test("83.0null", "" + f_d + sf_iAN);
+        test("83.0-2000000", "" + f_d + sf_iM);
+        test("83.0-820130816", "" + f_d + f_lM);
+        test("83.0null", "" + f_d + sf_oAN);
+        test("83.025000000", "" + f_d + s_I);
+        test("I-96.0", "" + f_c + s_dM);
+        test("Inull", "" + f_c + s_oNtS);
+        test("I\u045176", "" + f_c + f_strU);
+        test("I92", "" + f_c + sf_strU2);
+        test("I51", "" + f_c + sf_strU1);
+        test("Inull", "" + f_c + s_iAN);
+        test("I-54", "" + f_c + f_bM);
+        test("I-87.0", "" + f_c + f_fM);
+        test("Inull", "" + f_c + s_oAN);
+        test("I19", "" + f_c + f_str);
+        test("I-41", "" + f_c + sf_bM);
+        test("Inull", "" + f_c + sf_IN);
+        test("IT", "" + f_c + s_c);
+        test("I-42.0", "" + f_c + sf_fM);
+        test("I25", "" + f_c + s_b);
+        test("Inull", "" + f_c + f_oN);
+        test("I-1410065408", "" + f_c + s_lM);
+        test("I8.0", "" + f_c + s_d);
+        test("I55.0", "" + f_c + s_f);
+        test("I97000000", "" + f_c + s_i);
+        test("I-9900", "" + f_c + f_sM);
+        test("I935228928", "" + f_c + s_l);
+        test("I-8400", "" + f_c + sf_sM);
+        test("IC(82)", "" + f_c + s_o);
+        test("Inull", "" + f_c + sf_oNtS);
+        test("Itrue", "" + f_c + s_bl);
+        test("I3900", "" + f_c + s_s);
+        test("Inull", "" + f_c + sf_oN);
+        test("I94000000", "" + f_c + f_I);
+        test("Inull", "" + f_c + f_IN);
+        test("Itrue", "" + f_c + sf_bl);
+        test("I5500", "" + f_c + sf_s);
+        test("I-2900", "" + f_c + s_sM);
+        test("I-194313216", "" + f_c + sf_l);
+        test("I12", "" + f_c + s_strU1);
+        test("IC(87)", "" + f_c + sf_o);
+        test("I91", "" + f_c + s_strU2);
+        test("I21", "" + f_c + f_strU1);
+        test("I18", "" + f_c + f_strU2);
+        test("Inull", "" + f_c + f_iAN);
+        test("Inull", "" + f_c + s_oN);
+        test("I\u045180", "" + f_c + s_strU);
+        test("IC", "" + f_c + sf_c);
+        test("I75", "" + f_c + sf_str);
+        test("I-43", "" + f_c + s_bM);
+        test("I80", "" + f_c + sf_b);
+        test("Inull", "" + f_c + s_IN);
+        test("I-52.0", "" + f_c + s_fM);
+        test("I75000000", "" + f_c + sf_i);
+        test("I44", "" + f_c + f_b);
+        test("I-1705032704", "" + f_c + sf_lM);
+        test("Inull", "" + f_c + f_oAN);
+        test("I83.0", "" + f_c + f_d);
+        test("II", "" + f_c + f_c);
+        test("I94.0", "" + f_c + f_f);
+        test("I12.0", "" + f_c + sf_d);
+        test("I-99.0", "" + f_c + f_dM);
+        test("I17.0", "" + f_c + sf_f);
+        test("I-84.0", "" + f_c + sf_dM);
+        test("I58000000", "" + f_c + f_i);
+        test("I-55000000", "" + f_c + f_iM);
+        test("I1460392448", "" + f_c + f_l);
+        test("IC(70)", "" + f_c + f_o);
+        test("I\u04511", "" + f_c + sf_strU);
+        test("I8000", "" + f_c + f_s);
+        test("I18", "" + f_c + s_str);
+        test("I-1000000", "" + f_c + s_iM);
+        test("I1000000", "" + f_c + sf_I);
+        test("Inull", "" + f_c + f_oNtS);
+        test("Ifalse", "" + f_c + f_bl);
+        test("Inull", "" + f_c + sf_iAN);
+        test("I-2000000", "" + f_c + sf_iM);
+        test("I-820130816", "" + f_c + f_lM);
+        test("Inull", "" + f_c + sf_oAN);
+        test("I25000000", "" + f_c + s_I);
+        test("94.0-96.0", "" + f_f + s_dM);
+        test("94.0null", "" + f_f + s_oNtS);
+        test("94.0\u045176", "" + f_f + f_strU);
+        test("94.092", "" + f_f + sf_strU2);
+        test("94.051", "" + f_f + sf_strU1);
+        test("94.0null", "" + f_f + s_iAN);
+        test("94.0-54", "" + f_f + f_bM);
+        test("94.0-87.0", "" + f_f + f_fM);
+        test("94.0null", "" + f_f + s_oAN);
+        test("94.019", "" + f_f + f_str);
+        test("94.0-41", "" + f_f + sf_bM);
+        test("94.0null", "" + f_f + sf_IN);
+        test("94.0T", "" + f_f + s_c);
+        test("94.0-42.0", "" + f_f + sf_fM);
+        test("94.025", "" + f_f + s_b);
+        test("94.0null", "" + f_f + f_oN);
+        test("94.0-1410065408", "" + f_f + s_lM);
+        test("94.08.0", "" + f_f + s_d);
+        test("94.055.0", "" + f_f + s_f);
+        test("94.097000000", "" + f_f + s_i);
+        test("94.0-9900", "" + f_f + f_sM);
+        test("94.0935228928", "" + f_f + s_l);
+        test("94.0-8400", "" + f_f + sf_sM);
+        test("94.0C(82)", "" + f_f + s_o);
+        test("94.0null", "" + f_f + sf_oNtS);
+        test("94.0true", "" + f_f + s_bl);
+        test("94.03900", "" + f_f + s_s);
+        test("94.0null", "" + f_f + sf_oN);
+        test("94.094000000", "" + f_f + f_I);
+        test("94.0null", "" + f_f + f_IN);
+        test("94.0true", "" + f_f + sf_bl);
+        test("94.05500", "" + f_f + sf_s);
+        test("94.0-2900", "" + f_f + s_sM);
+        test("94.0-194313216", "" + f_f + sf_l);
+        test("94.012", "" + f_f + s_strU1);
+        test("94.0C(87)", "" + f_f + sf_o);
+        test("94.091", "" + f_f + s_strU2);
+        test("94.021", "" + f_f + f_strU1);
+        test("94.018", "" + f_f + f_strU2);
+        test("94.0null", "" + f_f + f_iAN);
+        test("94.0null", "" + f_f + s_oN);
+        test("94.0\u045180", "" + f_f + s_strU);
+        test("94.0C", "" + f_f + sf_c);
+        test("94.075", "" + f_f + sf_str);
+        test("94.0-43", "" + f_f + s_bM);
+        test("94.080", "" + f_f + sf_b);
+        test("94.0null", "" + f_f + s_IN);
+        test("94.0-52.0", "" + f_f + s_fM);
+        test("94.075000000", "" + f_f + sf_i);
+        test("94.044", "" + f_f + f_b);
+        test("94.0-1705032704", "" + f_f + sf_lM);
+        test("94.0null", "" + f_f + f_oAN);
+        test("94.083.0", "" + f_f + f_d);
+        test("94.0I", "" + f_f + f_c);
+        test("94.094.0", "" + f_f + f_f);
+        test("94.012.0", "" + f_f + sf_d);
+        test("94.0-99.0", "" + f_f + f_dM);
+        test("94.017.0", "" + f_f + sf_f);
+        test("94.0-84.0", "" + f_f + sf_dM);
+        test("94.058000000", "" + f_f + f_i);
+        test("94.0-55000000", "" + f_f + f_iM);
+        test("94.01460392448", "" + f_f + f_l);
+        test("94.0C(70)", "" + f_f + f_o);
+        test("94.0\u04511", "" + f_f + sf_strU);
+        test("94.08000", "" + f_f + f_s);
+        test("94.018", "" + f_f + s_str);
+        test("94.0-1000000", "" + f_f + s_iM);
+        test("94.01000000", "" + f_f + sf_I);
+        test("94.0null", "" + f_f + f_oNtS);
+        test("94.0false", "" + f_f + f_bl);
+        test("94.0null", "" + f_f + sf_iAN);
+        test("94.0-2000000", "" + f_f + sf_iM);
+        test("94.0-820130816", "" + f_f + f_lM);
+        test("94.0null", "" + f_f + sf_oAN);
+        test("94.025000000", "" + f_f + s_I);
+        test("12.0-96.0", "" + sf_d + s_dM);
+        test("12.0null", "" + sf_d + s_oNtS);
+        test("12.0\u045176", "" + sf_d + f_strU);
+        test("12.092", "" + sf_d + sf_strU2);
+        test("12.051", "" + sf_d + sf_strU1);
+        test("12.0null", "" + sf_d + s_iAN);
+        test("12.0-54", "" + sf_d + f_bM);
+        test("12.0-87.0", "" + sf_d + f_fM);
+        test("12.0null", "" + sf_d + s_oAN);
+        test("12.019", "" + sf_d + f_str);
+        test("12.0-41", "" + sf_d + sf_bM);
+        test("12.0null", "" + sf_d + sf_IN);
+        test("12.0T", "" + sf_d + s_c);
+        test("12.0-42.0", "" + sf_d + sf_fM);
+        test("12.025", "" + sf_d + s_b);
+        test("12.0null", "" + sf_d + f_oN);
+        test("12.0-1410065408", "" + sf_d + s_lM);
+        test("12.08.0", "" + sf_d + s_d);
+        test("12.055.0", "" + sf_d + s_f);
+        test("12.097000000", "" + sf_d + s_i);
+        test("12.0-9900", "" + sf_d + f_sM);
+        test("12.0935228928", "" + sf_d + s_l);
+        test("12.0-8400", "" + sf_d + sf_sM);
+        test("12.0C(82)", "" + sf_d + s_o);
+        test("12.0null", "" + sf_d + sf_oNtS);
+        test("12.0true", "" + sf_d + s_bl);
+        test("12.03900", "" + sf_d + s_s);
+        test("12.0null", "" + sf_d + sf_oN);
+        test("12.094000000", "" + sf_d + f_I);
+        test("12.0null", "" + sf_d + f_IN);
+        test("12.0true", "" + sf_d + sf_bl);
+        test("12.05500", "" + sf_d + sf_s);
+        test("12.0-2900", "" + sf_d + s_sM);
+        test("12.0-194313216", "" + sf_d + sf_l);
+        test("12.012", "" + sf_d + s_strU1);
+        test("12.0C(87)", "" + sf_d + sf_o);
+        test("12.091", "" + sf_d + s_strU2);
+        test("12.021", "" + sf_d + f_strU1);
+        test("12.018", "" + sf_d + f_strU2);
+        test("12.0null", "" + sf_d + f_iAN);
+        test("12.0null", "" + sf_d + s_oN);
+        test("12.0\u045180", "" + sf_d + s_strU);
+        test("12.0C", "" + sf_d + sf_c);
+        test("12.075", "" + sf_d + sf_str);
+        test("12.0-43", "" + sf_d + s_bM);
+        test("12.080", "" + sf_d + sf_b);
+        test("12.0null", "" + sf_d + s_IN);
+        test("12.0-52.0", "" + sf_d + s_fM);
+        test("12.075000000", "" + sf_d + sf_i);
+        test("12.044", "" + sf_d + f_b);
+        test("12.0-1705032704", "" + sf_d + sf_lM);
+        test("12.0null", "" + sf_d + f_oAN);
+        test("12.083.0", "" + sf_d + f_d);
+        test("12.0I", "" + sf_d + f_c);
+        test("12.094.0", "" + sf_d + f_f);
+        test("12.012.0", "" + sf_d + sf_d);
+        test("12.0-99.0", "" + sf_d + f_dM);
+        test("12.017.0", "" + sf_d + sf_f);
+        test("12.0-84.0", "" + sf_d + sf_dM);
+        test("12.058000000", "" + sf_d + f_i);
+        test("12.0-55000000", "" + sf_d + f_iM);
+        test("12.01460392448", "" + sf_d + f_l);
+        test("12.0C(70)", "" + sf_d + f_o);
+        test("12.0\u04511", "" + sf_d + sf_strU);
+        test("12.08000", "" + sf_d + f_s);
+        test("12.018", "" + sf_d + s_str);
+        test("12.0-1000000", "" + sf_d + s_iM);
+        test("12.01000000", "" + sf_d + sf_I);
+        test("12.0null", "" + sf_d + f_oNtS);
+        test("12.0false", "" + sf_d + f_bl);
+        test("12.0null", "" + sf_d + sf_iAN);
+        test("12.0-2000000", "" + sf_d + sf_iM);
+        test("12.0-820130816", "" + sf_d + f_lM);
+        test("12.0null", "" + sf_d + sf_oAN);
+        test("12.025000000", "" + sf_d + s_I);
+        test("-99.0-96.0", "" + f_dM + s_dM);
+        test("-99.0null", "" + f_dM + s_oNtS);
+        test("-99.0\u045176", "" + f_dM + f_strU);
+        test("-99.092", "" + f_dM + sf_strU2);
+        test("-99.051", "" + f_dM + sf_strU1);
+        test("-99.0null", "" + f_dM + s_iAN);
+        test("-99.0-54", "" + f_dM + f_bM);
+        test("-99.0-87.0", "" + f_dM + f_fM);
+        test("-99.0null", "" + f_dM + s_oAN);
+        test("-99.019", "" + f_dM + f_str);
+        test("-99.0-41", "" + f_dM + sf_bM);
+        test("-99.0null", "" + f_dM + sf_IN);
+        test("-99.0T", "" + f_dM + s_c);
+        test("-99.0-42.0", "" + f_dM + sf_fM);
+        test("-99.025", "" + f_dM + s_b);
+        test("-99.0null", "" + f_dM + f_oN);
+        test("-99.0-1410065408", "" + f_dM + s_lM);
+        test("-99.08.0", "" + f_dM + s_d);
+        test("-99.055.0", "" + f_dM + s_f);
+        test("-99.097000000", "" + f_dM + s_i);
+        test("-99.0-9900", "" + f_dM + f_sM);
+        test("-99.0935228928", "" + f_dM + s_l);
+        test("-99.0-8400", "" + f_dM + sf_sM);
+        test("-99.0C(82)", "" + f_dM + s_o);
+        test("-99.0null", "" + f_dM + sf_oNtS);
+        test("-99.0true", "" + f_dM + s_bl);
+        test("-99.03900", "" + f_dM + s_s);
+        test("-99.0null", "" + f_dM + sf_oN);
+        test("-99.094000000", "" + f_dM + f_I);
+        test("-99.0null", "" + f_dM + f_IN);
+        test("-99.0true", "" + f_dM + sf_bl);
+        test("-99.05500", "" + f_dM + sf_s);
+        test("-99.0-2900", "" + f_dM + s_sM);
+        test("-99.0-194313216", "" + f_dM + sf_l);
+        test("-99.012", "" + f_dM + s_strU1);
+        test("-99.0C(87)", "" + f_dM + sf_o);
+        test("-99.091", "" + f_dM + s_strU2);
+        test("-99.021", "" + f_dM + f_strU1);
+        test("-99.018", "" + f_dM + f_strU2);
+        test("-99.0null", "" + f_dM + f_iAN);
+        test("-99.0null", "" + f_dM + s_oN);
+        test("-99.0\u045180", "" + f_dM + s_strU);
+        test("-99.0C", "" + f_dM + sf_c);
+        test("-99.075", "" + f_dM + sf_str);
+        test("-99.0-43", "" + f_dM + s_bM);
+        test("-99.080", "" + f_dM + sf_b);
+        test("-99.0null", "" + f_dM + s_IN);
+        test("-99.0-52.0", "" + f_dM + s_fM);
+        test("-99.075000000", "" + f_dM + sf_i);
+        test("-99.044", "" + f_dM + f_b);
+        test("-99.0-1705032704", "" + f_dM + sf_lM);
+        test("-99.0null", "" + f_dM + f_oAN);
+        test("-99.083.0", "" + f_dM + f_d);
+        test("-99.0I", "" + f_dM + f_c);
+        test("-99.094.0", "" + f_dM + f_f);
+        test("-99.012.0", "" + f_dM + sf_d);
+        test("-99.0-99.0", "" + f_dM + f_dM);
+        test("-99.017.0", "" + f_dM + sf_f);
+        test("-99.0-84.0", "" + f_dM + sf_dM);
+        test("-99.058000000", "" + f_dM + f_i);
+        test("-99.0-55000000", "" + f_dM + f_iM);
+        test("-99.01460392448", "" + f_dM + f_l);
+        test("-99.0C(70)", "" + f_dM + f_o);
+        test("-99.0\u04511", "" + f_dM + sf_strU);
+        test("-99.08000", "" + f_dM + f_s);
+        test("-99.018", "" + f_dM + s_str);
+        test("-99.0-1000000", "" + f_dM + s_iM);
+        test("-99.01000000", "" + f_dM + sf_I);
+        test("-99.0null", "" + f_dM + f_oNtS);
+        test("-99.0false", "" + f_dM + f_bl);
+        test("-99.0null", "" + f_dM + sf_iAN);
+        test("-99.0-2000000", "" + f_dM + sf_iM);
+        test("-99.0-820130816", "" + f_dM + f_lM);
+        test("-99.0null", "" + f_dM + sf_oAN);
+        test("-99.025000000", "" + f_dM + s_I);
+        test("17.0-96.0", "" + sf_f + s_dM);
+        test("17.0null", "" + sf_f + s_oNtS);
+        test("17.0\u045176", "" + sf_f + f_strU);
+        test("17.092", "" + sf_f + sf_strU2);
+        test("17.051", "" + sf_f + sf_strU1);
+        test("17.0null", "" + sf_f + s_iAN);
+        test("17.0-54", "" + sf_f + f_bM);
+        test("17.0-87.0", "" + sf_f + f_fM);
+        test("17.0null", "" + sf_f + s_oAN);
+        test("17.019", "" + sf_f + f_str);
+        test("17.0-41", "" + sf_f + sf_bM);
+        test("17.0null", "" + sf_f + sf_IN);
+        test("17.0T", "" + sf_f + s_c);
+        test("17.0-42.0", "" + sf_f + sf_fM);
+        test("17.025", "" + sf_f + s_b);
+        test("17.0null", "" + sf_f + f_oN);
+        test("17.0-1410065408", "" + sf_f + s_lM);
+        test("17.08.0", "" + sf_f + s_d);
+        test("17.055.0", "" + sf_f + s_f);
+        test("17.097000000", "" + sf_f + s_i);
+        test("17.0-9900", "" + sf_f + f_sM);
+        test("17.0935228928", "" + sf_f + s_l);
+        test("17.0-8400", "" + sf_f + sf_sM);
+        test("17.0C(82)", "" + sf_f + s_o);
+        test("17.0null", "" + sf_f + sf_oNtS);
+        test("17.0true", "" + sf_f + s_bl);
+        test("17.03900", "" + sf_f + s_s);
+        test("17.0null", "" + sf_f + sf_oN);
+        test("17.094000000", "" + sf_f + f_I);
+        test("17.0null", "" + sf_f + f_IN);
+        test("17.0true", "" + sf_f + sf_bl);
+        test("17.05500", "" + sf_f + sf_s);
+        test("17.0-2900", "" + sf_f + s_sM);
+        test("17.0-194313216", "" + sf_f + sf_l);
+        test("17.012", "" + sf_f + s_strU1);
+        test("17.0C(87)", "" + sf_f + sf_o);
+        test("17.091", "" + sf_f + s_strU2);
+        test("17.021", "" + sf_f + f_strU1);
+        test("17.018", "" + sf_f + f_strU2);
+        test("17.0null", "" + sf_f + f_iAN);
+        test("17.0null", "" + sf_f + s_oN);
+        test("17.0\u045180", "" + sf_f + s_strU);
+        test("17.0C", "" + sf_f + sf_c);
+        test("17.075", "" + sf_f + sf_str);
+        test("17.0-43", "" + sf_f + s_bM);
+        test("17.080", "" + sf_f + sf_b);
+        test("17.0null", "" + sf_f + s_IN);
+        test("17.0-52.0", "" + sf_f + s_fM);
+        test("17.075000000", "" + sf_f + sf_i);
+        test("17.044", "" + sf_f + f_b);
+        test("17.0-1705032704", "" + sf_f + sf_lM);
+        test("17.0null", "" + sf_f + f_oAN);
+        test("17.083.0", "" + sf_f + f_d);
+        test("17.0I", "" + sf_f + f_c);
+        test("17.094.0", "" + sf_f + f_f);
+        test("17.012.0", "" + sf_f + sf_d);
+        test("17.0-99.0", "" + sf_f + f_dM);
+        test("17.017.0", "" + sf_f + sf_f);
+        test("17.0-84.0", "" + sf_f + sf_dM);
+        test("17.058000000", "" + sf_f + f_i);
+        test("17.0-55000000", "" + sf_f + f_iM);
+        test("17.01460392448", "" + sf_f + f_l);
+        test("17.0C(70)", "" + sf_f + f_o);
+        test("17.0\u04511", "" + sf_f + sf_strU);
+        test("17.08000", "" + sf_f + f_s);
+        test("17.018", "" + sf_f + s_str);
+        test("17.0-1000000", "" + sf_f + s_iM);
+        test("17.01000000", "" + sf_f + sf_I);
+        test("17.0null", "" + sf_f + f_oNtS);
+        test("17.0false", "" + sf_f + f_bl);
+        test("17.0null", "" + sf_f + sf_iAN);
+        test("17.0-2000000", "" + sf_f + sf_iM);
+        test("17.0-820130816", "" + sf_f + f_lM);
+        test("17.0null", "" + sf_f + sf_oAN);
+        test("17.025000000", "" + sf_f + s_I);
+        test("-84.0-96.0", "" + sf_dM + s_dM);
+        test("-84.0null", "" + sf_dM + s_oNtS);
+        test("-84.0\u045176", "" + sf_dM + f_strU);
+        test("-84.092", "" + sf_dM + sf_strU2);
+        test("-84.051", "" + sf_dM + sf_strU1);
+        test("-84.0null", "" + sf_dM + s_iAN);
+        test("-84.0-54", "" + sf_dM + f_bM);
+        test("-84.0-87.0", "" + sf_dM + f_fM);
+        test("-84.0null", "" + sf_dM + s_oAN);
+        test("-84.019", "" + sf_dM + f_str);
+        test("-84.0-41", "" + sf_dM + sf_bM);
+        test("-84.0null", "" + sf_dM + sf_IN);
+        test("-84.0T", "" + sf_dM + s_c);
+        test("-84.0-42.0", "" + sf_dM + sf_fM);
+        test("-84.025", "" + sf_dM + s_b);
+        test("-84.0null", "" + sf_dM + f_oN);
+        test("-84.0-1410065408", "" + sf_dM + s_lM);
+        test("-84.08.0", "" + sf_dM + s_d);
+        test("-84.055.0", "" + sf_dM + s_f);
+        test("-84.097000000", "" + sf_dM + s_i);
+        test("-84.0-9900", "" + sf_dM + f_sM);
+        test("-84.0935228928", "" + sf_dM + s_l);
+        test("-84.0-8400", "" + sf_dM + sf_sM);
+        test("-84.0C(82)", "" + sf_dM + s_o);
+        test("-84.0null", "" + sf_dM + sf_oNtS);
+        test("-84.0true", "" + sf_dM + s_bl);
+        test("-84.03900", "" + sf_dM + s_s);
+        test("-84.0null", "" + sf_dM + sf_oN);
+        test("-84.094000000", "" + sf_dM + f_I);
+        test("-84.0null", "" + sf_dM + f_IN);
+        test("-84.0true", "" + sf_dM + sf_bl);
+        test("-84.05500", "" + sf_dM + sf_s);
+        test("-84.0-2900", "" + sf_dM + s_sM);
+        test("-84.0-194313216", "" + sf_dM + sf_l);
+        test("-84.012", "" + sf_dM + s_strU1);
+        test("-84.0C(87)", "" + sf_dM + sf_o);
+        test("-84.091", "" + sf_dM + s_strU2);
+        test("-84.021", "" + sf_dM + f_strU1);
+        test("-84.018", "" + sf_dM + f_strU2);
+        test("-84.0null", "" + sf_dM + f_iAN);
+        test("-84.0null", "" + sf_dM + s_oN);
+        test("-84.0\u045180", "" + sf_dM + s_strU);
+        test("-84.0C", "" + sf_dM + sf_c);
+        test("-84.075", "" + sf_dM + sf_str);
+        test("-84.0-43", "" + sf_dM + s_bM);
+        test("-84.080", "" + sf_dM + sf_b);
+        test("-84.0null", "" + sf_dM + s_IN);
+        test("-84.0-52.0", "" + sf_dM + s_fM);
+        test("-84.075000000", "" + sf_dM + sf_i);
+        test("-84.044", "" + sf_dM + f_b);
+        test("-84.0-1705032704", "" + sf_dM + sf_lM);
+        test("-84.0null", "" + sf_dM + f_oAN);
+        test("-84.083.0", "" + sf_dM + f_d);
+        test("-84.0I", "" + sf_dM + f_c);
+        test("-84.094.0", "" + sf_dM + f_f);
+        test("-84.012.0", "" + sf_dM + sf_d);
+        test("-84.0-99.0", "" + sf_dM + f_dM);
+        test("-84.017.0", "" + sf_dM + sf_f);
+        test("-84.0-84.0", "" + sf_dM + sf_dM);
+        test("-84.058000000", "" + sf_dM + f_i);
+        test("-84.0-55000000", "" + sf_dM + f_iM);
+        test("-84.01460392448", "" + sf_dM + f_l);
+        test("-84.0C(70)", "" + sf_dM + f_o);
+        test("-84.0\u04511", "" + sf_dM + sf_strU);
+        test("-84.08000", "" + sf_dM + f_s);
+        test("-84.018", "" + sf_dM + s_str);
+        test("-84.0-1000000", "" + sf_dM + s_iM);
+        test("-84.01000000", "" + sf_dM + sf_I);
+        test("-84.0null", "" + sf_dM + f_oNtS);
+        test("-84.0false", "" + sf_dM + f_bl);
+        test("-84.0null", "" + sf_dM + sf_iAN);
+        test("-84.0-2000000", "" + sf_dM + sf_iM);
+        test("-84.0-820130816", "" + sf_dM + f_lM);
+        test("-84.0null", "" + sf_dM + sf_oAN);
+        test("-84.025000000", "" + sf_dM + s_I);
+        test("58000000-96.0", "" + f_i + s_dM);
+        test("58000000null", "" + f_i + s_oNtS);
+        test("58000000\u045176", "" + f_i + f_strU);
+        test("5800000092", "" + f_i + sf_strU2);
+        test("5800000051", "" + f_i + sf_strU1);
+        test("58000000null", "" + f_i + s_iAN);
+        test("58000000-54", "" + f_i + f_bM);
+        test("58000000-87.0", "" + f_i + f_fM);
+        test("58000000null", "" + f_i + s_oAN);
+        test("5800000019", "" + f_i + f_str);
+        test("58000000-41", "" + f_i + sf_bM);
+        test("58000000null", "" + f_i + sf_IN);
+        test("58000000T", "" + f_i + s_c);
+        test("58000000-42.0", "" + f_i + sf_fM);
+        test("5800000025", "" + f_i + s_b);
+        test("58000000null", "" + f_i + f_oN);
+        test("58000000-1410065408", "" + f_i + s_lM);
+        test("580000008.0", "" + f_i + s_d);
+        test("5800000055.0", "" + f_i + s_f);
+        test("5800000097000000", "" + f_i + s_i);
+        test("58000000-9900", "" + f_i + f_sM);
+        test("58000000935228928", "" + f_i + s_l);
+        test("58000000-8400", "" + f_i + sf_sM);
+        test("58000000C(82)", "" + f_i + s_o);
+        test("58000000null", "" + f_i + sf_oNtS);
+        test("58000000true", "" + f_i + s_bl);
+        test("580000003900", "" + f_i + s_s);
+        test("58000000null", "" + f_i + sf_oN);
+        test("5800000094000000", "" + f_i + f_I);
+        test("58000000null", "" + f_i + f_IN);
+        test("58000000true", "" + f_i + sf_bl);
+        test("580000005500", "" + f_i + sf_s);
+        test("58000000-2900", "" + f_i + s_sM);
+        test("58000000-194313216", "" + f_i + sf_l);
+        test("5800000012", "" + f_i + s_strU1);
+        test("58000000C(87)", "" + f_i + sf_o);
+        test("5800000091", "" + f_i + s_strU2);
+        test("5800000021", "" + f_i + f_strU1);
+        test("5800000018", "" + f_i + f_strU2);
+        test("58000000null", "" + f_i + f_iAN);
+        test("58000000null", "" + f_i + s_oN);
+        test("58000000\u045180", "" + f_i + s_strU);
+        test("58000000C", "" + f_i + sf_c);
+        test("5800000075", "" + f_i + sf_str);
+        test("58000000-43", "" + f_i + s_bM);
+        test("5800000080", "" + f_i + sf_b);
+        test("58000000null", "" + f_i + s_IN);
+        test("58000000-52.0", "" + f_i + s_fM);
+        test("5800000075000000", "" + f_i + sf_i);
+        test("5800000044", "" + f_i + f_b);
+        test("58000000-1705032704", "" + f_i + sf_lM);
+        test("58000000null", "" + f_i + f_oAN);
+        test("5800000083.0", "" + f_i + f_d);
+        test("58000000I", "" + f_i + f_c);
+        test("5800000094.0", "" + f_i + f_f);
+        test("5800000012.0", "" + f_i + sf_d);
+        test("58000000-99.0", "" + f_i + f_dM);
+        test("5800000017.0", "" + f_i + sf_f);
+        test("58000000-84.0", "" + f_i + sf_dM);
+        test("5800000058000000", "" + f_i + f_i);
+        test("58000000-55000000", "" + f_i + f_iM);
+        test("580000001460392448", "" + f_i + f_l);
+        test("58000000C(70)", "" + f_i + f_o);
+        test("58000000\u04511", "" + f_i + sf_strU);
+        test("580000008000", "" + f_i + f_s);
+        test("5800000018", "" + f_i + s_str);
+        test("58000000-1000000", "" + f_i + s_iM);
+        test("580000001000000", "" + f_i + sf_I);
+        test("58000000null", "" + f_i + f_oNtS);
+        test("58000000false", "" + f_i + f_bl);
+        test("58000000null", "" + f_i + sf_iAN);
+        test("58000000-2000000", "" + f_i + sf_iM);
+        test("58000000-820130816", "" + f_i + f_lM);
+        test("58000000null", "" + f_i + sf_oAN);
+        test("5800000025000000", "" + f_i + s_I);
+        test("-55000000-96.0", "" + f_iM + s_dM);
+        test("-55000000null", "" + f_iM + s_oNtS);
+        test("-55000000\u045176", "" + f_iM + f_strU);
+        test("-5500000092", "" + f_iM + sf_strU2);
+        test("-5500000051", "" + f_iM + sf_strU1);
+        test("-55000000null", "" + f_iM + s_iAN);
+        test("-55000000-54", "" + f_iM + f_bM);
+        test("-55000000-87.0", "" + f_iM + f_fM);
+        test("-55000000null", "" + f_iM + s_oAN);
+        test("-5500000019", "" + f_iM + f_str);
+        test("-55000000-41", "" + f_iM + sf_bM);
+        test("-55000000null", "" + f_iM + sf_IN);
+        test("-55000000T", "" + f_iM + s_c);
+        test("-55000000-42.0", "" + f_iM + sf_fM);
+        test("-5500000025", "" + f_iM + s_b);
+        test("-55000000null", "" + f_iM + f_oN);
+        test("-55000000-1410065408", "" + f_iM + s_lM);
+        test("-550000008.0", "" + f_iM + s_d);
+        test("-5500000055.0", "" + f_iM + s_f);
+        test("-5500000097000000", "" + f_iM + s_i);
+        test("-55000000-9900", "" + f_iM + f_sM);
+        test("-55000000935228928", "" + f_iM + s_l);
+        test("-55000000-8400", "" + f_iM + sf_sM);
+        test("-55000000C(82)", "" + f_iM + s_o);
+        test("-55000000null", "" + f_iM + sf_oNtS);
+        test("-55000000true", "" + f_iM + s_bl);
+        test("-550000003900", "" + f_iM + s_s);
+        test("-55000000null", "" + f_iM + sf_oN);
+        test("-5500000094000000", "" + f_iM + f_I);
+        test("-55000000null", "" + f_iM + f_IN);
+        test("-55000000true", "" + f_iM + sf_bl);
+        test("-550000005500", "" + f_iM + sf_s);
+        test("-55000000-2900", "" + f_iM + s_sM);
+        test("-55000000-194313216", "" + f_iM + sf_l);
+        test("-5500000012", "" + f_iM + s_strU1);
+        test("-55000000C(87)", "" + f_iM + sf_o);
+        test("-5500000091", "" + f_iM + s_strU2);
+        test("-5500000021", "" + f_iM + f_strU1);
+        test("-5500000018", "" + f_iM + f_strU2);
+        test("-55000000null", "" + f_iM + f_iAN);
+        test("-55000000null", "" + f_iM + s_oN);
+        test("-55000000\u045180", "" + f_iM + s_strU);
+        test("-55000000C", "" + f_iM + sf_c);
+        test("-5500000075", "" + f_iM + sf_str);
+        test("-55000000-43", "" + f_iM + s_bM);
+        test("-5500000080", "" + f_iM + sf_b);
+        test("-55000000null", "" + f_iM + s_IN);
+        test("-55000000-52.0", "" + f_iM + s_fM);
+        test("-5500000075000000", "" + f_iM + sf_i);
+        test("-5500000044", "" + f_iM + f_b);
+        test("-55000000-1705032704", "" + f_iM + sf_lM);
+        test("-55000000null", "" + f_iM + f_oAN);
+        test("-5500000083.0", "" + f_iM + f_d);
+        test("-55000000I", "" + f_iM + f_c);
+        test("-5500000094.0", "" + f_iM + f_f);
+        test("-5500000012.0", "" + f_iM + sf_d);
+        test("-55000000-99.0", "" + f_iM + f_dM);
+        test("-5500000017.0", "" + f_iM + sf_f);
+        test("-55000000-84.0", "" + f_iM + sf_dM);
+        test("-5500000058000000", "" + f_iM + f_i);
+        test("-55000000-55000000", "" + f_iM + f_iM);
+        test("-550000001460392448", "" + f_iM + f_l);
+        test("-55000000C(70)", "" + f_iM + f_o);
+        test("-55000000\u04511", "" + f_iM + sf_strU);
+        test("-550000008000", "" + f_iM + f_s);
+        test("-5500000018", "" + f_iM + s_str);
+        test("-55000000-1000000", "" + f_iM + s_iM);
+        test("-550000001000000", "" + f_iM + sf_I);
+        test("-55000000null", "" + f_iM + f_oNtS);
+        test("-55000000false", "" + f_iM + f_bl);
+        test("-55000000null", "" + f_iM + sf_iAN);
+        test("-55000000-2000000", "" + f_iM + sf_iM);
+        test("-55000000-820130816", "" + f_iM + f_lM);
+        test("-55000000null", "" + f_iM + sf_oAN);
+        test("-5500000025000000", "" + f_iM + s_I);
+        test("1460392448-96.0", "" + f_l + s_dM);
+        test("1460392448null", "" + f_l + s_oNtS);
+        test("1460392448\u045176", "" + f_l + f_strU);
+        test("146039244892", "" + f_l + sf_strU2);
+        test("146039244851", "" + f_l + sf_strU1);
+        test("1460392448null", "" + f_l + s_iAN);
+        test("1460392448-54", "" + f_l + f_bM);
+        test("1460392448-87.0", "" + f_l + f_fM);
+        test("1460392448null", "" + f_l + s_oAN);
+        test("146039244819", "" + f_l + f_str);
+        test("1460392448-41", "" + f_l + sf_bM);
+        test("1460392448null", "" + f_l + sf_IN);
+        test("1460392448T", "" + f_l + s_c);
+        test("1460392448-42.0", "" + f_l + sf_fM);
+        test("146039244825", "" + f_l + s_b);
+        test("1460392448null", "" + f_l + f_oN);
+        test("1460392448-1410065408", "" + f_l + s_lM);
+        test("14603924488.0", "" + f_l + s_d);
+        test("146039244855.0", "" + f_l + s_f);
+        test("146039244897000000", "" + f_l + s_i);
+        test("1460392448-9900", "" + f_l + f_sM);
+        test("1460392448935228928", "" + f_l + s_l);
+        test("1460392448-8400", "" + f_l + sf_sM);
+        test("1460392448C(82)", "" + f_l + s_o);
+        test("1460392448null", "" + f_l + sf_oNtS);
+        test("1460392448true", "" + f_l + s_bl);
+        test("14603924483900", "" + f_l + s_s);
+        test("1460392448null", "" + f_l + sf_oN);
+        test("146039244894000000", "" + f_l + f_I);
+        test("1460392448null", "" + f_l + f_IN);
+        test("1460392448true", "" + f_l + sf_bl);
+        test("14603924485500", "" + f_l + sf_s);
+        test("1460392448-2900", "" + f_l + s_sM);
+        test("1460392448-194313216", "" + f_l + sf_l);
+        test("146039244812", "" + f_l + s_strU1);
+        test("1460392448C(87)", "" + f_l + sf_o);
+        test("146039244891", "" + f_l + s_strU2);
+        test("146039244821", "" + f_l + f_strU1);
+        test("146039244818", "" + f_l + f_strU2);
+        test("1460392448null", "" + f_l + f_iAN);
+        test("1460392448null", "" + f_l + s_oN);
+        test("1460392448\u045180", "" + f_l + s_strU);
+        test("1460392448C", "" + f_l + sf_c);
+        test("146039244875", "" + f_l + sf_str);
+        test("1460392448-43", "" + f_l + s_bM);
+        test("146039244880", "" + f_l + sf_b);
+        test("1460392448null", "" + f_l + s_IN);
+        test("1460392448-52.0", "" + f_l + s_fM);
+        test("146039244875000000", "" + f_l + sf_i);
+        test("146039244844", "" + f_l + f_b);
+        test("1460392448-1705032704", "" + f_l + sf_lM);
+        test("1460392448null", "" + f_l + f_oAN);
+        test("146039244883.0", "" + f_l + f_d);
+        test("1460392448I", "" + f_l + f_c);
+        test("146039244894.0", "" + f_l + f_f);
+        test("146039244812.0", "" + f_l + sf_d);
+        test("1460392448-99.0", "" + f_l + f_dM);
+        test("146039244817.0", "" + f_l + sf_f);
+        test("1460392448-84.0", "" + f_l + sf_dM);
+        test("146039244858000000", "" + f_l + f_i);
+        test("1460392448-55000000", "" + f_l + f_iM);
+        test("14603924481460392448", "" + f_l + f_l);
+        test("1460392448C(70)", "" + f_l + f_o);
+        test("1460392448\u04511", "" + f_l + sf_strU);
+        test("14603924488000", "" + f_l + f_s);
+        test("146039244818", "" + f_l + s_str);
+        test("1460392448-1000000", "" + f_l + s_iM);
+        test("14603924481000000", "" + f_l + sf_I);
+        test("1460392448null", "" + f_l + f_oNtS);
+        test("1460392448false", "" + f_l + f_bl);
+        test("1460392448null", "" + f_l + sf_iAN);
+        test("1460392448-2000000", "" + f_l + sf_iM);
+        test("1460392448-820130816", "" + f_l + f_lM);
+        test("1460392448null", "" + f_l + sf_oAN);
+        test("146039244825000000", "" + f_l + s_I);
+        test("C(70)-96.0", "" + f_o + s_dM);
+        test("C(70)null", "" + f_o + s_oNtS);
+        test("C(70)\u045176", "" + f_o + f_strU);
+        test("C(70)92", "" + f_o + sf_strU2);
+        test("C(70)51", "" + f_o + sf_strU1);
+        test("C(70)null", "" + f_o + s_iAN);
+        test("C(70)-54", "" + f_o + f_bM);
+        test("C(70)-87.0", "" + f_o + f_fM);
+        test("C(70)null", "" + f_o + s_oAN);
+        test("C(70)19", "" + f_o + f_str);
+        test("C(70)-41", "" + f_o + sf_bM);
+        test("C(70)null", "" + f_o + sf_IN);
+        test("C(70)T", "" + f_o + s_c);
+        test("C(70)-42.0", "" + f_o + sf_fM);
+        test("C(70)25", "" + f_o + s_b);
+        test("C(70)null", "" + f_o + f_oN);
+        test("C(70)-1410065408", "" + f_o + s_lM);
+        test("C(70)8.0", "" + f_o + s_d);
+        test("C(70)55.0", "" + f_o + s_f);
+        test("C(70)97000000", "" + f_o + s_i);
+        test("C(70)-9900", "" + f_o + f_sM);
+        test("C(70)935228928", "" + f_o + s_l);
+        test("C(70)-8400", "" + f_o + sf_sM);
+        test("C(70)C(82)", "" + f_o + s_o);
+        test("C(70)null", "" + f_o + sf_oNtS);
+        test("C(70)true", "" + f_o + s_bl);
+        test("C(70)3900", "" + f_o + s_s);
+        test("C(70)null", "" + f_o + sf_oN);
+        test("C(70)94000000", "" + f_o + f_I);
+        test("C(70)null", "" + f_o + f_IN);
+        test("C(70)true", "" + f_o + sf_bl);
+        test("C(70)5500", "" + f_o + sf_s);
+        test("C(70)-2900", "" + f_o + s_sM);
+        test("C(70)-194313216", "" + f_o + sf_l);
+        test("C(70)12", "" + f_o + s_strU1);
+        test("C(70)C(87)", "" + f_o + sf_o);
+        test("C(70)91", "" + f_o + s_strU2);
+        test("C(70)21", "" + f_o + f_strU1);
+        test("C(70)18", "" + f_o + f_strU2);
+        test("C(70)null", "" + f_o + f_iAN);
+        test("C(70)null", "" + f_o + s_oN);
+        test("C(70)\u045180", "" + f_o + s_strU);
+        test("C(70)C", "" + f_o + sf_c);
+        test("C(70)75", "" + f_o + sf_str);
+        test("C(70)-43", "" + f_o + s_bM);
+        test("C(70)80", "" + f_o + sf_b);
+        test("C(70)null", "" + f_o + s_IN);
+        test("C(70)-52.0", "" + f_o + s_fM);
+        test("C(70)75000000", "" + f_o + sf_i);
+        test("C(70)44", "" + f_o + f_b);
+        test("C(70)-1705032704", "" + f_o + sf_lM);
+        test("C(70)null", "" + f_o + f_oAN);
+        test("C(70)83.0", "" + f_o + f_d);
+        test("C(70)I", "" + f_o + f_c);
+        test("C(70)94.0", "" + f_o + f_f);
+        test("C(70)12.0", "" + f_o + sf_d);
+        test("C(70)-99.0", "" + f_o + f_dM);
+        test("C(70)17.0", "" + f_o + sf_f);
+        test("C(70)-84.0", "" + f_o + sf_dM);
+        test("C(70)58000000", "" + f_o + f_i);
+        test("C(70)-55000000", "" + f_o + f_iM);
+        test("C(70)1460392448", "" + f_o + f_l);
+        test("C(70)C(70)", "" + f_o + f_o);
+        test("C(70)\u04511", "" + f_o + sf_strU);
+        test("C(70)8000", "" + f_o + f_s);
+        test("C(70)18", "" + f_o + s_str);
+        test("C(70)-1000000", "" + f_o + s_iM);
+        test("C(70)1000000", "" + f_o + sf_I);
+        test("C(70)null", "" + f_o + f_oNtS);
+        test("C(70)false", "" + f_o + f_bl);
+        test("C(70)null", "" + f_o + sf_iAN);
+        test("C(70)-2000000", "" + f_o + sf_iM);
+        test("C(70)-820130816", "" + f_o + f_lM);
+        test("C(70)null", "" + f_o + sf_oAN);
+        test("C(70)25000000", "" + f_o + s_I);
+        test("\u04511-96.0", "" + sf_strU + s_dM);
+        test("\u04511null", "" + sf_strU + s_oNtS);
+        test("\u04511\u045176", "" + sf_strU + f_strU);
+        test("\u0451192", "" + sf_strU + sf_strU2);
+        test("\u0451151", "" + sf_strU + sf_strU1);
+        test("\u04511null", "" + sf_strU + s_iAN);
+        test("\u04511-54", "" + sf_strU + f_bM);
+        test("\u04511-87.0", "" + sf_strU + f_fM);
+        test("\u04511null", "" + sf_strU + s_oAN);
+        test("\u0451119", "" + sf_strU + f_str);
+        test("\u04511-41", "" + sf_strU + sf_bM);
+        test("\u04511null", "" + sf_strU + sf_IN);
+        test("\u04511T", "" + sf_strU + s_c);
+        test("\u04511-42.0", "" + sf_strU + sf_fM);
+        test("\u0451125", "" + sf_strU + s_b);
+        test("\u04511null", "" + sf_strU + f_oN);
+        test("\u04511-1410065408", "" + sf_strU + s_lM);
+        test("\u045118.0", "" + sf_strU + s_d);
+        test("\u0451155.0", "" + sf_strU + s_f);
+        test("\u0451197000000", "" + sf_strU + s_i);
+        test("\u04511-9900", "" + sf_strU + f_sM);
+        test("\u04511935228928", "" + sf_strU + s_l);
+        test("\u04511-8400", "" + sf_strU + sf_sM);
+        test("\u04511C(82)", "" + sf_strU + s_o);
+        test("\u04511null", "" + sf_strU + sf_oNtS);
+        test("\u04511true", "" + sf_strU + s_bl);
+        test("\u045113900", "" + sf_strU + s_s);
+        test("\u04511null", "" + sf_strU + sf_oN);
+        test("\u0451194000000", "" + sf_strU + f_I);
+        test("\u04511null", "" + sf_strU + f_IN);
+        test("\u04511true", "" + sf_strU + sf_bl);
+        test("\u045115500", "" + sf_strU + sf_s);
+        test("\u04511-2900", "" + sf_strU + s_sM);
+        test("\u04511-194313216", "" + sf_strU + sf_l);
+        test("\u0451112", "" + sf_strU + s_strU1);
+        test("\u04511C(87)", "" + sf_strU + sf_o);
+        test("\u0451191", "" + sf_strU + s_strU2);
+        test("\u0451121", "" + sf_strU + f_strU1);
+        test("\u0451118", "" + sf_strU + f_strU2);
+        test("\u04511null", "" + sf_strU + f_iAN);
+        test("\u04511null", "" + sf_strU + s_oN);
+        test("\u04511\u045180", "" + sf_strU + s_strU);
+        test("\u04511C", "" + sf_strU + sf_c);
+        test("\u0451175", "" + sf_strU + sf_str);
+        test("\u04511-43", "" + sf_strU + s_bM);
+        test("\u0451180", "" + sf_strU + sf_b);
+        test("\u04511null", "" + sf_strU + s_IN);
+        test("\u04511-52.0", "" + sf_strU + s_fM);
+        test("\u0451175000000", "" + sf_strU + sf_i);
+        test("\u0451144", "" + sf_strU + f_b);
+        test("\u04511-1705032704", "" + sf_strU + sf_lM);
+        test("\u04511null", "" + sf_strU + f_oAN);
+        test("\u0451183.0", "" + sf_strU + f_d);
+        test("\u04511I", "" + sf_strU + f_c);
+        test("\u0451194.0", "" + sf_strU + f_f);
+        test("\u0451112.0", "" + sf_strU + sf_d);
+        test("\u04511-99.0", "" + sf_strU + f_dM);
+        test("\u0451117.0", "" + sf_strU + sf_f);
+        test("\u04511-84.0", "" + sf_strU + sf_dM);
+        test("\u0451158000000", "" + sf_strU + f_i);
+        test("\u04511-55000000", "" + sf_strU + f_iM);
+        test("\u045111460392448", "" + sf_strU + f_l);
+        test("\u04511C(70)", "" + sf_strU + f_o);
+        test("\u04511\u04511", "" + sf_strU + sf_strU);
+        test("\u045118000", "" + sf_strU + f_s);
+        test("\u0451118", "" + sf_strU + s_str);
+        test("\u04511-1000000", "" + sf_strU + s_iM);
+        test("\u045111000000", "" + sf_strU + sf_I);
+        test("\u04511null", "" + sf_strU + f_oNtS);
+        test("\u04511false", "" + sf_strU + f_bl);
+        test("\u04511null", "" + sf_strU + sf_iAN);
+        test("\u04511-2000000", "" + sf_strU + sf_iM);
+        test("\u04511-820130816", "" + sf_strU + f_lM);
+        test("\u04511null", "" + sf_strU + sf_oAN);
+        test("\u0451125000000", "" + sf_strU + s_I);
+        test("8000-96.0", "" + f_s + s_dM);
+        test("8000null", "" + f_s + s_oNtS);
+        test("8000\u045176", "" + f_s + f_strU);
+        test("800092", "" + f_s + sf_strU2);
+        test("800051", "" + f_s + sf_strU1);
+        test("8000null", "" + f_s + s_iAN);
+        test("8000-54", "" + f_s + f_bM);
+        test("8000-87.0", "" + f_s + f_fM);
+        test("8000null", "" + f_s + s_oAN);
+        test("800019", "" + f_s + f_str);
+        test("8000-41", "" + f_s + sf_bM);
+        test("8000null", "" + f_s + sf_IN);
+        test("8000T", "" + f_s + s_c);
+        test("8000-42.0", "" + f_s + sf_fM);
+        test("800025", "" + f_s + s_b);
+        test("8000null", "" + f_s + f_oN);
+        test("8000-1410065408", "" + f_s + s_lM);
+        test("80008.0", "" + f_s + s_d);
+        test("800055.0", "" + f_s + s_f);
+        test("800097000000", "" + f_s + s_i);
+        test("8000-9900", "" + f_s + f_sM);
+        test("8000935228928", "" + f_s + s_l);
+        test("8000-8400", "" + f_s + sf_sM);
+        test("8000C(82)", "" + f_s + s_o);
+        test("8000null", "" + f_s + sf_oNtS);
+        test("8000true", "" + f_s + s_bl);
+        test("80003900", "" + f_s + s_s);
+        test("8000null", "" + f_s + sf_oN);
+        test("800094000000", "" + f_s + f_I);
+        test("8000null", "" + f_s + f_IN);
+        test("8000true", "" + f_s + sf_bl);
+        test("80005500", "" + f_s + sf_s);
+        test("8000-2900", "" + f_s + s_sM);
+        test("8000-194313216", "" + f_s + sf_l);
+        test("800012", "" + f_s + s_strU1);
+        test("8000C(87)", "" + f_s + sf_o);
+        test("800091", "" + f_s + s_strU2);
+        test("800021", "" + f_s + f_strU1);
+        test("800018", "" + f_s + f_strU2);
+        test("8000null", "" + f_s + f_iAN);
+        test("8000null", "" + f_s + s_oN);
+        test("8000\u045180", "" + f_s + s_strU);
+        test("8000C", "" + f_s + sf_c);
+        test("800075", "" + f_s + sf_str);
+        test("8000-43", "" + f_s + s_bM);
+        test("800080", "" + f_s + sf_b);
+        test("8000null", "" + f_s + s_IN);
+        test("8000-52.0", "" + f_s + s_fM);
+        test("800075000000", "" + f_s + sf_i);
+        test("800044", "" + f_s + f_b);
+        test("8000-1705032704", "" + f_s + sf_lM);
+        test("8000null", "" + f_s + f_oAN);
+        test("800083.0", "" + f_s + f_d);
+        test("8000I", "" + f_s + f_c);
+        test("800094.0", "" + f_s + f_f);
+        test("800012.0", "" + f_s + sf_d);
+        test("8000-99.0", "" + f_s + f_dM);
+        test("800017.0", "" + f_s + sf_f);
+        test("8000-84.0", "" + f_s + sf_dM);
+        test("800058000000", "" + f_s + f_i);
+        test("8000-55000000", "" + f_s + f_iM);
+        test("80001460392448", "" + f_s + f_l);
+        test("8000C(70)", "" + f_s + f_o);
+        test("8000\u04511", "" + f_s + sf_strU);
+        test("80008000", "" + f_s + f_s);
+        test("800018", "" + f_s + s_str);
+        test("8000-1000000", "" + f_s + s_iM);
+        test("80001000000", "" + f_s + sf_I);
+        test("8000null", "" + f_s + f_oNtS);
+        test("8000false", "" + f_s + f_bl);
+        test("8000null", "" + f_s + sf_iAN);
+        test("8000-2000000", "" + f_s + sf_iM);
+        test("8000-820130816", "" + f_s + f_lM);
+        test("8000null", "" + f_s + sf_oAN);
+        test("800025000000", "" + f_s + s_I);
+        test("18-96.0", "" + s_str + s_dM);
+        test("18null", "" + s_str + s_oNtS);
+        test("18\u045176", "" + s_str + f_strU);
+        test("1892", "" + s_str + sf_strU2);
+        test("1851", "" + s_str + sf_strU1);
+        test("18null", "" + s_str + s_iAN);
+        test("18-54", "" + s_str + f_bM);
+        test("18-87.0", "" + s_str + f_fM);
+        test("18null", "" + s_str + s_oAN);
+        test("1819", "" + s_str + f_str);
+        test("18-41", "" + s_str + sf_bM);
+        test("18null", "" + s_str + sf_IN);
+        test("18T", "" + s_str + s_c);
+        test("18-42.0", "" + s_str + sf_fM);
+        test("1825", "" + s_str + s_b);
+        test("18null", "" + s_str + f_oN);
+        test("18-1410065408", "" + s_str + s_lM);
+        test("188.0", "" + s_str + s_d);
+        test("1855.0", "" + s_str + s_f);
+        test("1897000000", "" + s_str + s_i);
+        test("18-9900", "" + s_str + f_sM);
+        test("18935228928", "" + s_str + s_l);
+        test("18-8400", "" + s_str + sf_sM);
+        test("18C(82)", "" + s_str + s_o);
+        test("18null", "" + s_str + sf_oNtS);
+        test("18true", "" + s_str + s_bl);
+        test("183900", "" + s_str + s_s);
+        test("18null", "" + s_str + sf_oN);
+        test("1894000000", "" + s_str + f_I);
+        test("18null", "" + s_str + f_IN);
+        test("18true", "" + s_str + sf_bl);
+        test("185500", "" + s_str + sf_s);
+        test("18-2900", "" + s_str + s_sM);
+        test("18-194313216", "" + s_str + sf_l);
+        test("1812", "" + s_str + s_strU1);
+        test("18C(87)", "" + s_str + sf_o);
+        test("1891", "" + s_str + s_strU2);
+        test("1821", "" + s_str + f_strU1);
+        test("1818", "" + s_str + f_strU2);
+        test("18null", "" + s_str + f_iAN);
+        test("18null", "" + s_str + s_oN);
+        test("18\u045180", "" + s_str + s_strU);
+        test("18C", "" + s_str + sf_c);
+        test("1875", "" + s_str + sf_str);
+        test("18-43", "" + s_str + s_bM);
+        test("1880", "" + s_str + sf_b);
+        test("18null", "" + s_str + s_IN);
+        test("18-52.0", "" + s_str + s_fM);
+        test("1875000000", "" + s_str + sf_i);
+        test("1844", "" + s_str + f_b);
+    }
+
+    public void run5() {
+        test("18-1705032704", "" + s_str + sf_lM);
+        test("18null", "" + s_str + f_oAN);
+        test("1883.0", "" + s_str + f_d);
+        test("18I", "" + s_str + f_c);
+        test("1894.0", "" + s_str + f_f);
+        test("1812.0", "" + s_str + sf_d);
+        test("18-99.0", "" + s_str + f_dM);
+        test("1817.0", "" + s_str + sf_f);
+        test("18-84.0", "" + s_str + sf_dM);
+        test("1858000000", "" + s_str + f_i);
+        test("18-55000000", "" + s_str + f_iM);
+        test("181460392448", "" + s_str + f_l);
+        test("18C(70)", "" + s_str + f_o);
+        test("18\u04511", "" + s_str + sf_strU);
+        test("188000", "" + s_str + f_s);
+        test("1818", "" + s_str + s_str);
+        test("18-1000000", "" + s_str + s_iM);
+        test("181000000", "" + s_str + sf_I);
+        test("18null", "" + s_str + f_oNtS);
+        test("18false", "" + s_str + f_bl);
+        test("18null", "" + s_str + sf_iAN);
+        test("18-2000000", "" + s_str + sf_iM);
+        test("18-820130816", "" + s_str + f_lM);
+        test("18null", "" + s_str + sf_oAN);
+        test("1825000000", "" + s_str + s_I);
+        test("-1000000-96.0", "" + s_iM + s_dM);
+        test("-1000000null", "" + s_iM + s_oNtS);
+        test("-1000000\u045176", "" + s_iM + f_strU);
+        test("-100000092", "" + s_iM + sf_strU2);
+        test("-100000051", "" + s_iM + sf_strU1);
+        test("-1000000null", "" + s_iM + s_iAN);
+        test("-1000000-54", "" + s_iM + f_bM);
+        test("-1000000-87.0", "" + s_iM + f_fM);
+        test("-1000000null", "" + s_iM + s_oAN);
+        test("-100000019", "" + s_iM + f_str);
+        test("-1000000-41", "" + s_iM + sf_bM);
+        test("-1000000null", "" + s_iM + sf_IN);
+        test("-1000000T", "" + s_iM + s_c);
+        test("-1000000-42.0", "" + s_iM + sf_fM);
+        test("-100000025", "" + s_iM + s_b);
+        test("-1000000null", "" + s_iM + f_oN);
+        test("-1000000-1410065408", "" + s_iM + s_lM);
+        test("-10000008.0", "" + s_iM + s_d);
+        test("-100000055.0", "" + s_iM + s_f);
+        test("-100000097000000", "" + s_iM + s_i);
+        test("-1000000-9900", "" + s_iM + f_sM);
+        test("-1000000935228928", "" + s_iM + s_l);
+        test("-1000000-8400", "" + s_iM + sf_sM);
+        test("-1000000C(82)", "" + s_iM + s_o);
+        test("-1000000null", "" + s_iM + sf_oNtS);
+        test("-1000000true", "" + s_iM + s_bl);
+        test("-10000003900", "" + s_iM + s_s);
+        test("-1000000null", "" + s_iM + sf_oN);
+        test("-100000094000000", "" + s_iM + f_I);
+        test("-1000000null", "" + s_iM + f_IN);
+        test("-1000000true", "" + s_iM + sf_bl);
+        test("-10000005500", "" + s_iM + sf_s);
+        test("-1000000-2900", "" + s_iM + s_sM);
+        test("-1000000-194313216", "" + s_iM + sf_l);
+        test("-100000012", "" + s_iM + s_strU1);
+        test("-1000000C(87)", "" + s_iM + sf_o);
+        test("-100000091", "" + s_iM + s_strU2);
+        test("-100000021", "" + s_iM + f_strU1);
+        test("-100000018", "" + s_iM + f_strU2);
+        test("-1000000null", "" + s_iM + f_iAN);
+        test("-1000000null", "" + s_iM + s_oN);
+        test("-1000000\u045180", "" + s_iM + s_strU);
+        test("-1000000C", "" + s_iM + sf_c);
+        test("-100000075", "" + s_iM + sf_str);
+        test("-1000000-43", "" + s_iM + s_bM);
+        test("-100000080", "" + s_iM + sf_b);
+        test("-1000000null", "" + s_iM + s_IN);
+        test("-1000000-52.0", "" + s_iM + s_fM);
+        test("-100000075000000", "" + s_iM + sf_i);
+        test("-100000044", "" + s_iM + f_b);
+        test("-1000000-1705032704", "" + s_iM + sf_lM);
+        test("-1000000null", "" + s_iM + f_oAN);
+        test("-100000083.0", "" + s_iM + f_d);
+        test("-1000000I", "" + s_iM + f_c);
+        test("-100000094.0", "" + s_iM + f_f);
+        test("-100000012.0", "" + s_iM + sf_d);
+        test("-1000000-99.0", "" + s_iM + f_dM);
+        test("-100000017.0", "" + s_iM + sf_f);
+        test("-1000000-84.0", "" + s_iM + sf_dM);
+        test("-100000058000000", "" + s_iM + f_i);
+        test("-1000000-55000000", "" + s_iM + f_iM);
+        test("-10000001460392448", "" + s_iM + f_l);
+        test("-1000000C(70)", "" + s_iM + f_o);
+        test("-1000000\u04511", "" + s_iM + sf_strU);
+        test("-10000008000", "" + s_iM + f_s);
+        test("-100000018", "" + s_iM + s_str);
+        test("-1000000-1000000", "" + s_iM + s_iM);
+        test("-10000001000000", "" + s_iM + sf_I);
+        test("-1000000null", "" + s_iM + f_oNtS);
+        test("-1000000false", "" + s_iM + f_bl);
+        test("-1000000null", "" + s_iM + sf_iAN);
+        test("-1000000-2000000", "" + s_iM + sf_iM);
+        test("-1000000-820130816", "" + s_iM + f_lM);
+        test("-1000000null", "" + s_iM + sf_oAN);
+        test("-100000025000000", "" + s_iM + s_I);
+        test("1000000-96.0", "" + sf_I + s_dM);
+        test("1000000null", "" + sf_I + s_oNtS);
+        test("1000000\u045176", "" + sf_I + f_strU);
+        test("100000092", "" + sf_I + sf_strU2);
+        test("100000051", "" + sf_I + sf_strU1);
+        test("1000000null", "" + sf_I + s_iAN);
+        test("1000000-54", "" + sf_I + f_bM);
+        test("1000000-87.0", "" + sf_I + f_fM);
+        test("1000000null", "" + sf_I + s_oAN);
+        test("100000019", "" + sf_I + f_str);
+        test("1000000-41", "" + sf_I + sf_bM);
+        test("1000000null", "" + sf_I + sf_IN);
+        test("1000000T", "" + sf_I + s_c);
+        test("1000000-42.0", "" + sf_I + sf_fM);
+        test("100000025", "" + sf_I + s_b);
+        test("1000000null", "" + sf_I + f_oN);
+        test("1000000-1410065408", "" + sf_I + s_lM);
+        test("10000008.0", "" + sf_I + s_d);
+        test("100000055.0", "" + sf_I + s_f);
+        test("100000097000000", "" + sf_I + s_i);
+        test("1000000-9900", "" + sf_I + f_sM);
+        test("1000000935228928", "" + sf_I + s_l);
+        test("1000000-8400", "" + sf_I + sf_sM);
+        test("1000000C(82)", "" + sf_I + s_o);
+        test("1000000null", "" + sf_I + sf_oNtS);
+        test("1000000true", "" + sf_I + s_bl);
+        test("10000003900", "" + sf_I + s_s);
+        test("1000000null", "" + sf_I + sf_oN);
+        test("100000094000000", "" + sf_I + f_I);
+        test("1000000null", "" + sf_I + f_IN);
+        test("1000000true", "" + sf_I + sf_bl);
+        test("10000005500", "" + sf_I + sf_s);
+        test("1000000-2900", "" + sf_I + s_sM);
+        test("1000000-194313216", "" + sf_I + sf_l);
+        test("100000012", "" + sf_I + s_strU1);
+        test("1000000C(87)", "" + sf_I + sf_o);
+        test("100000091", "" + sf_I + s_strU2);
+        test("100000021", "" + sf_I + f_strU1);
+        test("100000018", "" + sf_I + f_strU2);
+        test("1000000null", "" + sf_I + f_iAN);
+        test("1000000null", "" + sf_I + s_oN);
+        test("1000000\u045180", "" + sf_I + s_strU);
+        test("1000000C", "" + sf_I + sf_c);
+        test("100000075", "" + sf_I + sf_str);
+        test("1000000-43", "" + sf_I + s_bM);
+        test("100000080", "" + sf_I + sf_b);
+        test("1000000null", "" + sf_I + s_IN);
+        test("1000000-52.0", "" + sf_I + s_fM);
+        test("100000075000000", "" + sf_I + sf_i);
+        test("100000044", "" + sf_I + f_b);
+        test("1000000-1705032704", "" + sf_I + sf_lM);
+        test("1000000null", "" + sf_I + f_oAN);
+        test("100000083.0", "" + sf_I + f_d);
+        test("1000000I", "" + sf_I + f_c);
+        test("100000094.0", "" + sf_I + f_f);
+        test("100000012.0", "" + sf_I + sf_d);
+        test("1000000-99.0", "" + sf_I + f_dM);
+        test("100000017.0", "" + sf_I + sf_f);
+        test("1000000-84.0", "" + sf_I + sf_dM);
+        test("100000058000000", "" + sf_I + f_i);
+        test("1000000-55000000", "" + sf_I + f_iM);
+        test("10000001460392448", "" + sf_I + f_l);
+        test("1000000C(70)", "" + sf_I + f_o);
+        test("1000000\u04511", "" + sf_I + sf_strU);
+        test("10000008000", "" + sf_I + f_s);
+        test("100000018", "" + sf_I + s_str);
+        test("1000000-1000000", "" + sf_I + s_iM);
+        test("10000001000000", "" + sf_I + sf_I);
+        test("1000000null", "" + sf_I + f_oNtS);
+        test("1000000false", "" + sf_I + f_bl);
+        test("1000000null", "" + sf_I + sf_iAN);
+        test("1000000-2000000", "" + sf_I + sf_iM);
+        test("1000000-820130816", "" + sf_I + f_lM);
+        test("1000000null", "" + sf_I + sf_oAN);
+        test("100000025000000", "" + sf_I + s_I);
+        test("null-96.0", "" + f_oNtS + s_dM);
+        test("nullnull", "" + f_oNtS + s_oNtS);
+        test("null\u045176", "" + f_oNtS + f_strU);
+        test("null92", "" + f_oNtS + sf_strU2);
+        test("null51", "" + f_oNtS + sf_strU1);
+        test("nullnull", "" + f_oNtS + s_iAN);
+        test("null-54", "" + f_oNtS + f_bM);
+        test("null-87.0", "" + f_oNtS + f_fM);
+        test("nullnull", "" + f_oNtS + s_oAN);
+        test("null19", "" + f_oNtS + f_str);
+        test("null-41", "" + f_oNtS + sf_bM);
+        test("nullnull", "" + f_oNtS + sf_IN);
+        test("nullT", "" + f_oNtS + s_c);
+        test("null-42.0", "" + f_oNtS + sf_fM);
+        test("null25", "" + f_oNtS + s_b);
+        test("nullnull", "" + f_oNtS + f_oN);
+        test("null-1410065408", "" + f_oNtS + s_lM);
+        test("null8.0", "" + f_oNtS + s_d);
+        test("null55.0", "" + f_oNtS + s_f);
+        test("null97000000", "" + f_oNtS + s_i);
+        test("null-9900", "" + f_oNtS + f_sM);
+        test("null935228928", "" + f_oNtS + s_l);
+        test("null-8400", "" + f_oNtS + sf_sM);
+        test("nullC(82)", "" + f_oNtS + s_o);
+        test("nullnull", "" + f_oNtS + sf_oNtS);
+        test("nulltrue", "" + f_oNtS + s_bl);
+        test("null3900", "" + f_oNtS + s_s);
+        test("nullnull", "" + f_oNtS + sf_oN);
+        test("null94000000", "" + f_oNtS + f_I);
+        test("nullnull", "" + f_oNtS + f_IN);
+        test("nulltrue", "" + f_oNtS + sf_bl);
+        test("null5500", "" + f_oNtS + sf_s);
+        test("null-2900", "" + f_oNtS + s_sM);
+        test("null-194313216", "" + f_oNtS + sf_l);
+        test("null12", "" + f_oNtS + s_strU1);
+        test("nullC(87)", "" + f_oNtS + sf_o);
+        test("null91", "" + f_oNtS + s_strU2);
+        test("null21", "" + f_oNtS + f_strU1);
+        test("null18", "" + f_oNtS + f_strU2);
+        test("nullnull", "" + f_oNtS + f_iAN);
+        test("nullnull", "" + f_oNtS + s_oN);
+        test("null\u045180", "" + f_oNtS + s_strU);
+        test("nullC", "" + f_oNtS + sf_c);
+        test("null75", "" + f_oNtS + sf_str);
+        test("null-43", "" + f_oNtS + s_bM);
+        test("null80", "" + f_oNtS + sf_b);
+        test("nullnull", "" + f_oNtS + s_IN);
+        test("null-52.0", "" + f_oNtS + s_fM);
+        test("null75000000", "" + f_oNtS + sf_i);
+        test("null44", "" + f_oNtS + f_b);
+        test("null-1705032704", "" + f_oNtS + sf_lM);
+        test("nullnull", "" + f_oNtS + f_oAN);
+        test("null83.0", "" + f_oNtS + f_d);
+        test("nullI", "" + f_oNtS + f_c);
+        test("null94.0", "" + f_oNtS + f_f);
+        test("null12.0", "" + f_oNtS + sf_d);
+        test("null-99.0", "" + f_oNtS + f_dM);
+        test("null17.0", "" + f_oNtS + sf_f);
+        test("null-84.0", "" + f_oNtS + sf_dM);
+        test("null58000000", "" + f_oNtS + f_i);
+        test("null-55000000", "" + f_oNtS + f_iM);
+        test("null1460392448", "" + f_oNtS + f_l);
+        test("nullC(70)", "" + f_oNtS + f_o);
+        test("null\u04511", "" + f_oNtS + sf_strU);
+        test("null8000", "" + f_oNtS + f_s);
+        test("null18", "" + f_oNtS + s_str);
+        test("null-1000000", "" + f_oNtS + s_iM);
+        test("null1000000", "" + f_oNtS + sf_I);
+        test("nullnull", "" + f_oNtS + f_oNtS);
+        test("nullfalse", "" + f_oNtS + f_bl);
+        test("nullnull", "" + f_oNtS + sf_iAN);
+        test("null-2000000", "" + f_oNtS + sf_iM);
+        test("null-820130816", "" + f_oNtS + f_lM);
+        test("nullnull", "" + f_oNtS + sf_oAN);
+        test("null25000000", "" + f_oNtS + s_I);
+        test("false-96.0", "" + f_bl + s_dM);
+        test("falsenull", "" + f_bl + s_oNtS);
+        test("false\u045176", "" + f_bl + f_strU);
+        test("false92", "" + f_bl + sf_strU2);
+        test("false51", "" + f_bl + sf_strU1);
+        test("falsenull", "" + f_bl + s_iAN);
+        test("false-54", "" + f_bl + f_bM);
+        test("false-87.0", "" + f_bl + f_fM);
+        test("falsenull", "" + f_bl + s_oAN);
+        test("false19", "" + f_bl + f_str);
+        test("false-41", "" + f_bl + sf_bM);
+        test("falsenull", "" + f_bl + sf_IN);
+        test("falseT", "" + f_bl + s_c);
+        test("false-42.0", "" + f_bl + sf_fM);
+        test("false25", "" + f_bl + s_b);
+        test("falsenull", "" + f_bl + f_oN);
+        test("false-1410065408", "" + f_bl + s_lM);
+        test("false8.0", "" + f_bl + s_d);
+        test("false55.0", "" + f_bl + s_f);
+        test("false97000000", "" + f_bl + s_i);
+        test("false-9900", "" + f_bl + f_sM);
+        test("false935228928", "" + f_bl + s_l);
+        test("false-8400", "" + f_bl + sf_sM);
+        test("falseC(82)", "" + f_bl + s_o);
+        test("falsenull", "" + f_bl + sf_oNtS);
+        test("falsetrue", "" + f_bl + s_bl);
+        test("false3900", "" + f_bl + s_s);
+        test("falsenull", "" + f_bl + sf_oN);
+        test("false94000000", "" + f_bl + f_I);
+        test("falsenull", "" + f_bl + f_IN);
+        test("falsetrue", "" + f_bl + sf_bl);
+        test("false5500", "" + f_bl + sf_s);
+        test("false-2900", "" + f_bl + s_sM);
+        test("false-194313216", "" + f_bl + sf_l);
+        test("false12", "" + f_bl + s_strU1);
+        test("falseC(87)", "" + f_bl + sf_o);
+        test("false91", "" + f_bl + s_strU2);
+        test("false21", "" + f_bl + f_strU1);
+        test("false18", "" + f_bl + f_strU2);
+        test("falsenull", "" + f_bl + f_iAN);
+        test("falsenull", "" + f_bl + s_oN);
+        test("false\u045180", "" + f_bl + s_strU);
+        test("falseC", "" + f_bl + sf_c);
+        test("false75", "" + f_bl + sf_str);
+        test("false-43", "" + f_bl + s_bM);
+        test("false80", "" + f_bl + sf_b);
+        test("falsenull", "" + f_bl + s_IN);
+        test("false-52.0", "" + f_bl + s_fM);
+        test("false75000000", "" + f_bl + sf_i);
+        test("false44", "" + f_bl + f_b);
+        test("false-1705032704", "" + f_bl + sf_lM);
+        test("falsenull", "" + f_bl + f_oAN);
+        test("false83.0", "" + f_bl + f_d);
+        test("falseI", "" + f_bl + f_c);
+        test("false94.0", "" + f_bl + f_f);
+        test("false12.0", "" + f_bl + sf_d);
+        test("false-99.0", "" + f_bl + f_dM);
+        test("false17.0", "" + f_bl + sf_f);
+        test("false-84.0", "" + f_bl + sf_dM);
+        test("false58000000", "" + f_bl + f_i);
+        test("false-55000000", "" + f_bl + f_iM);
+        test("false1460392448", "" + f_bl + f_l);
+        test("falseC(70)", "" + f_bl + f_o);
+        test("false\u04511", "" + f_bl + sf_strU);
+        test("false8000", "" + f_bl + f_s);
+        test("false18", "" + f_bl + s_str);
+        test("false-1000000", "" + f_bl + s_iM);
+        test("false1000000", "" + f_bl + sf_I);
+        test("falsenull", "" + f_bl + f_oNtS);
+        test("falsefalse", "" + f_bl + f_bl);
+        test("falsenull", "" + f_bl + sf_iAN);
+        test("false-2000000", "" + f_bl + sf_iM);
+        test("false-820130816", "" + f_bl + f_lM);
+        test("falsenull", "" + f_bl + sf_oAN);
+        test("false25000000", "" + f_bl + s_I);
+        test("null-96.0", "" + sf_iAN + s_dM);
+        test("nullnull", "" + sf_iAN + s_oNtS);
+        test("null\u045176", "" + sf_iAN + f_strU);
+        test("null92", "" + sf_iAN + sf_strU2);
+        test("null51", "" + sf_iAN + sf_strU1);
+        test("nullnull", "" + sf_iAN + s_iAN);
+        test("null-54", "" + sf_iAN + f_bM);
+        test("null-87.0", "" + sf_iAN + f_fM);
+        test("nullnull", "" + sf_iAN + s_oAN);
+        test("null19", "" + sf_iAN + f_str);
+        test("null-41", "" + sf_iAN + sf_bM);
+        test("nullnull", "" + sf_iAN + sf_IN);
+        test("nullT", "" + sf_iAN + s_c);
+        test("null-42.0", "" + sf_iAN + sf_fM);
+        test("null25", "" + sf_iAN + s_b);
+        test("nullnull", "" + sf_iAN + f_oN);
+        test("null-1410065408", "" + sf_iAN + s_lM);
+        test("null8.0", "" + sf_iAN + s_d);
+        test("null55.0", "" + sf_iAN + s_f);
+        test("null97000000", "" + sf_iAN + s_i);
+        test("null-9900", "" + sf_iAN + f_sM);
+        test("null935228928", "" + sf_iAN + s_l);
+        test("null-8400", "" + sf_iAN + sf_sM);
+        test("nullC(82)", "" + sf_iAN + s_o);
+        test("nullnull", "" + sf_iAN + sf_oNtS);
+        test("nulltrue", "" + sf_iAN + s_bl);
+        test("null3900", "" + sf_iAN + s_s);
+        test("nullnull", "" + sf_iAN + sf_oN);
+        test("null94000000", "" + sf_iAN + f_I);
+        test("nullnull", "" + sf_iAN + f_IN);
+        test("nulltrue", "" + sf_iAN + sf_bl);
+        test("null5500", "" + sf_iAN + sf_s);
+        test("null-2900", "" + sf_iAN + s_sM);
+        test("null-194313216", "" + sf_iAN + sf_l);
+        test("null12", "" + sf_iAN + s_strU1);
+        test("nullC(87)", "" + sf_iAN + sf_o);
+        test("null91", "" + sf_iAN + s_strU2);
+        test("null21", "" + sf_iAN + f_strU1);
+        test("null18", "" + sf_iAN + f_strU2);
+        test("nullnull", "" + sf_iAN + f_iAN);
+        test("nullnull", "" + sf_iAN + s_oN);
+        test("null\u045180", "" + sf_iAN + s_strU);
+        test("nullC", "" + sf_iAN + sf_c);
+        test("null75", "" + sf_iAN + sf_str);
+        test("null-43", "" + sf_iAN + s_bM);
+        test("null80", "" + sf_iAN + sf_b);
+        test("nullnull", "" + sf_iAN + s_IN);
+        test("null-52.0", "" + sf_iAN + s_fM);
+        test("null75000000", "" + sf_iAN + sf_i);
+        test("null44", "" + sf_iAN + f_b);
+        test("null-1705032704", "" + sf_iAN + sf_lM);
+        test("nullnull", "" + sf_iAN + f_oAN);
+        test("null83.0", "" + sf_iAN + f_d);
+        test("nullI", "" + sf_iAN + f_c);
+        test("null94.0", "" + sf_iAN + f_f);
+        test("null12.0", "" + sf_iAN + sf_d);
+        test("null-99.0", "" + sf_iAN + f_dM);
+        test("null17.0", "" + sf_iAN + sf_f);
+        test("null-84.0", "" + sf_iAN + sf_dM);
+        test("null58000000", "" + sf_iAN + f_i);
+        test("null-55000000", "" + sf_iAN + f_iM);
+        test("null1460392448", "" + sf_iAN + f_l);
+        test("nullC(70)", "" + sf_iAN + f_o);
+        test("null\u04511", "" + sf_iAN + sf_strU);
+        test("null8000", "" + sf_iAN + f_s);
+        test("null18", "" + sf_iAN + s_str);
+        test("null-1000000", "" + sf_iAN + s_iM);
+        test("null1000000", "" + sf_iAN + sf_I);
+        test("nullnull", "" + sf_iAN + f_oNtS);
+        test("nullfalse", "" + sf_iAN + f_bl);
+        test("nullnull", "" + sf_iAN + sf_iAN);
+        test("null-2000000", "" + sf_iAN + sf_iM);
+        test("null-820130816", "" + sf_iAN + f_lM);
+        test("nullnull", "" + sf_iAN + sf_oAN);
+        test("null25000000", "" + sf_iAN + s_I);
+        test("-2000000-96.0", "" + sf_iM + s_dM);
+        test("-2000000null", "" + sf_iM + s_oNtS);
+        test("-2000000\u045176", "" + sf_iM + f_strU);
+        test("-200000092", "" + sf_iM + sf_strU2);
+        test("-200000051", "" + sf_iM + sf_strU1);
+        test("-2000000null", "" + sf_iM + s_iAN);
+        test("-2000000-54", "" + sf_iM + f_bM);
+        test("-2000000-87.0", "" + sf_iM + f_fM);
+        test("-2000000null", "" + sf_iM + s_oAN);
+        test("-200000019", "" + sf_iM + f_str);
+        test("-2000000-41", "" + sf_iM + sf_bM);
+        test("-2000000null", "" + sf_iM + sf_IN);
+        test("-2000000T", "" + sf_iM + s_c);
+        test("-2000000-42.0", "" + sf_iM + sf_fM);
+        test("-200000025", "" + sf_iM + s_b);
+        test("-2000000null", "" + sf_iM + f_oN);
+        test("-2000000-1410065408", "" + sf_iM + s_lM);
+        test("-20000008.0", "" + sf_iM + s_d);
+        test("-200000055.0", "" + sf_iM + s_f);
+        test("-200000097000000", "" + sf_iM + s_i);
+        test("-2000000-9900", "" + sf_iM + f_sM);
+        test("-2000000935228928", "" + sf_iM + s_l);
+        test("-2000000-8400", "" + sf_iM + sf_sM);
+        test("-2000000C(82)", "" + sf_iM + s_o);
+        test("-2000000null", "" + sf_iM + sf_oNtS);
+        test("-2000000true", "" + sf_iM + s_bl);
+        test("-20000003900", "" + sf_iM + s_s);
+        test("-2000000null", "" + sf_iM + sf_oN);
+        test("-200000094000000", "" + sf_iM + f_I);
+        test("-2000000null", "" + sf_iM + f_IN);
+        test("-2000000true", "" + sf_iM + sf_bl);
+        test("-20000005500", "" + sf_iM + sf_s);
+        test("-2000000-2900", "" + sf_iM + s_sM);
+        test("-2000000-194313216", "" + sf_iM + sf_l);
+        test("-200000012", "" + sf_iM + s_strU1);
+        test("-2000000C(87)", "" + sf_iM + sf_o);
+        test("-200000091", "" + sf_iM + s_strU2);
+        test("-200000021", "" + sf_iM + f_strU1);
+        test("-200000018", "" + sf_iM + f_strU2);
+        test("-2000000null", "" + sf_iM + f_iAN);
+        test("-2000000null", "" + sf_iM + s_oN);
+        test("-2000000\u045180", "" + sf_iM + s_strU);
+        test("-2000000C", "" + sf_iM + sf_c);
+        test("-200000075", "" + sf_iM + sf_str);
+        test("-2000000-43", "" + sf_iM + s_bM);
+        test("-200000080", "" + sf_iM + sf_b);
+        test("-2000000null", "" + sf_iM + s_IN);
+        test("-2000000-52.0", "" + sf_iM + s_fM);
+        test("-200000075000000", "" + sf_iM + sf_i);
+        test("-200000044", "" + sf_iM + f_b);
+        test("-2000000-1705032704", "" + sf_iM + sf_lM);
+        test("-2000000null", "" + sf_iM + f_oAN);
+        test("-200000083.0", "" + sf_iM + f_d);
+        test("-2000000I", "" + sf_iM + f_c);
+        test("-200000094.0", "" + sf_iM + f_f);
+        test("-200000012.0", "" + sf_iM + sf_d);
+        test("-2000000-99.0", "" + sf_iM + f_dM);
+        test("-200000017.0", "" + sf_iM + sf_f);
+        test("-2000000-84.0", "" + sf_iM + sf_dM);
+        test("-200000058000000", "" + sf_iM + f_i);
+        test("-2000000-55000000", "" + sf_iM + f_iM);
+        test("-20000001460392448", "" + sf_iM + f_l);
+        test("-2000000C(70)", "" + sf_iM + f_o);
+        test("-2000000\u04511", "" + sf_iM + sf_strU);
+        test("-20000008000", "" + sf_iM + f_s);
+        test("-200000018", "" + sf_iM + s_str);
+        test("-2000000-1000000", "" + sf_iM + s_iM);
+        test("-20000001000000", "" + sf_iM + sf_I);
+        test("-2000000null", "" + sf_iM + f_oNtS);
+        test("-2000000false", "" + sf_iM + f_bl);
+        test("-2000000null", "" + sf_iM + sf_iAN);
+        test("-2000000-2000000", "" + sf_iM + sf_iM);
+        test("-2000000-820130816", "" + sf_iM + f_lM);
+        test("-2000000null", "" + sf_iM + sf_oAN);
+        test("-200000025000000", "" + sf_iM + s_I);
+        test("-820130816-96.0", "" + f_lM + s_dM);
+        test("-820130816null", "" + f_lM + s_oNtS);
+        test("-820130816\u045176", "" + f_lM + f_strU);
+        test("-82013081692", "" + f_lM + sf_strU2);
+        test("-82013081651", "" + f_lM + sf_strU1);
+        test("-820130816null", "" + f_lM + s_iAN);
+        test("-820130816-54", "" + f_lM + f_bM);
+        test("-820130816-87.0", "" + f_lM + f_fM);
+        test("-820130816null", "" + f_lM + s_oAN);
+        test("-82013081619", "" + f_lM + f_str);
+        test("-820130816-41", "" + f_lM + sf_bM);
+        test("-820130816null", "" + f_lM + sf_IN);
+        test("-820130816T", "" + f_lM + s_c);
+        test("-820130816-42.0", "" + f_lM + sf_fM);
+        test("-82013081625", "" + f_lM + s_b);
+        test("-820130816null", "" + f_lM + f_oN);
+        test("-820130816-1410065408", "" + f_lM + s_lM);
+        test("-8201308168.0", "" + f_lM + s_d);
+        test("-82013081655.0", "" + f_lM + s_f);
+        test("-82013081697000000", "" + f_lM + s_i);
+        test("-820130816-9900", "" + f_lM + f_sM);
+        test("-820130816935228928", "" + f_lM + s_l);
+        test("-820130816-8400", "" + f_lM + sf_sM);
+        test("-820130816C(82)", "" + f_lM + s_o);
+        test("-820130816null", "" + f_lM + sf_oNtS);
+        test("-820130816true", "" + f_lM + s_bl);
+        test("-8201308163900", "" + f_lM + s_s);
+        test("-820130816null", "" + f_lM + sf_oN);
+        test("-82013081694000000", "" + f_lM + f_I);
+        test("-820130816null", "" + f_lM + f_IN);
+        test("-820130816true", "" + f_lM + sf_bl);
+        test("-8201308165500", "" + f_lM + sf_s);
+        test("-820130816-2900", "" + f_lM + s_sM);
+        test("-820130816-194313216", "" + f_lM + sf_l);
+        test("-82013081612", "" + f_lM + s_strU1);
+        test("-820130816C(87)", "" + f_lM + sf_o);
+        test("-82013081691", "" + f_lM + s_strU2);
+        test("-82013081621", "" + f_lM + f_strU1);
+        test("-82013081618", "" + f_lM + f_strU2);
+        test("-820130816null", "" + f_lM + f_iAN);
+        test("-820130816null", "" + f_lM + s_oN);
+        test("-820130816\u045180", "" + f_lM + s_strU);
+        test("-820130816C", "" + f_lM + sf_c);
+        test("-82013081675", "" + f_lM + sf_str);
+        test("-820130816-43", "" + f_lM + s_bM);
+        test("-82013081680", "" + f_lM + sf_b);
+        test("-820130816null", "" + f_lM + s_IN);
+        test("-820130816-52.0", "" + f_lM + s_fM);
+        test("-82013081675000000", "" + f_lM + sf_i);
+        test("-82013081644", "" + f_lM + f_b);
+        test("-820130816-1705032704", "" + f_lM + sf_lM);
+        test("-820130816null", "" + f_lM + f_oAN);
+        test("-82013081683.0", "" + f_lM + f_d);
+        test("-820130816I", "" + f_lM + f_c);
+        test("-82013081694.0", "" + f_lM + f_f);
+        test("-82013081612.0", "" + f_lM + sf_d);
+        test("-820130816-99.0", "" + f_lM + f_dM);
+        test("-82013081617.0", "" + f_lM + sf_f);
+        test("-820130816-84.0", "" + f_lM + sf_dM);
+        test("-82013081658000000", "" + f_lM + f_i);
+        test("-820130816-55000000", "" + f_lM + f_iM);
+        test("-8201308161460392448", "" + f_lM + f_l);
+        test("-820130816C(70)", "" + f_lM + f_o);
+        test("-820130816\u04511", "" + f_lM + sf_strU);
+        test("-8201308168000", "" + f_lM + f_s);
+        test("-82013081618", "" + f_lM + s_str);
+        test("-820130816-1000000", "" + f_lM + s_iM);
+        test("-8201308161000000", "" + f_lM + sf_I);
+        test("-820130816null", "" + f_lM + f_oNtS);
+        test("-820130816false", "" + f_lM + f_bl);
+        test("-820130816null", "" + f_lM + sf_iAN);
+        test("-820130816-2000000", "" + f_lM + sf_iM);
+        test("-820130816-820130816", "" + f_lM + f_lM);
+        test("-820130816null", "" + f_lM + sf_oAN);
+        test("-82013081625000000", "" + f_lM + s_I);
+        test("null-96.0", "" + sf_oAN + s_dM);
+        test("nullnull", "" + sf_oAN + s_oNtS);
+        test("null\u045176", "" + sf_oAN + f_strU);
+        test("null92", "" + sf_oAN + sf_strU2);
+        test("null51", "" + sf_oAN + sf_strU1);
+        test("nullnull", "" + sf_oAN + s_iAN);
+        test("null-54", "" + sf_oAN + f_bM);
+        test("null-87.0", "" + sf_oAN + f_fM);
+        test("nullnull", "" + sf_oAN + s_oAN);
+        test("null19", "" + sf_oAN + f_str);
+        test("null-41", "" + sf_oAN + sf_bM);
+        test("nullnull", "" + sf_oAN + sf_IN);
+        test("nullT", "" + sf_oAN + s_c);
+        test("null-42.0", "" + sf_oAN + sf_fM);
+        test("null25", "" + sf_oAN + s_b);
+        test("nullnull", "" + sf_oAN + f_oN);
+        test("null-1410065408", "" + sf_oAN + s_lM);
+        test("null8.0", "" + sf_oAN + s_d);
+        test("null55.0", "" + sf_oAN + s_f);
+        test("null97000000", "" + sf_oAN + s_i);
+        test("null-9900", "" + sf_oAN + f_sM);
+        test("null935228928", "" + sf_oAN + s_l);
+        test("null-8400", "" + sf_oAN + sf_sM);
+        test("nullC(82)", "" + sf_oAN + s_o);
+        test("nullnull", "" + sf_oAN + sf_oNtS);
+        test("nulltrue", "" + sf_oAN + s_bl);
+        test("null3900", "" + sf_oAN + s_s);
+        test("nullnull", "" + sf_oAN + sf_oN);
+        test("null94000000", "" + sf_oAN + f_I);
+        test("nullnull", "" + sf_oAN + f_IN);
+        test("nulltrue", "" + sf_oAN + sf_bl);
+        test("null5500", "" + sf_oAN + sf_s);
+        test("null-2900", "" + sf_oAN + s_sM);
+        test("null-194313216", "" + sf_oAN + sf_l);
+        test("null12", "" + sf_oAN + s_strU1);
+        test("nullC(87)", "" + sf_oAN + sf_o);
+        test("null91", "" + sf_oAN + s_strU2);
+        test("null21", "" + sf_oAN + f_strU1);
+        test("null18", "" + sf_oAN + f_strU2);
+        test("nullnull", "" + sf_oAN + f_iAN);
+        test("nullnull", "" + sf_oAN + s_oN);
+        test("null\u045180", "" + sf_oAN + s_strU);
+        test("nullC", "" + sf_oAN + sf_c);
+        test("null75", "" + sf_oAN + sf_str);
+        test("null-43", "" + sf_oAN + s_bM);
+        test("null80", "" + sf_oAN + sf_b);
+        test("nullnull", "" + sf_oAN + s_IN);
+        test("null-52.0", "" + sf_oAN + s_fM);
+        test("null75000000", "" + sf_oAN + sf_i);
+        test("null44", "" + sf_oAN + f_b);
+        test("null-1705032704", "" + sf_oAN + sf_lM);
+        test("nullnull", "" + sf_oAN + f_oAN);
+        test("null83.0", "" + sf_oAN + f_d);
+        test("nullI", "" + sf_oAN + f_c);
+        test("null94.0", "" + sf_oAN + f_f);
+        test("null12.0", "" + sf_oAN + sf_d);
+        test("null-99.0", "" + sf_oAN + f_dM);
+        test("null17.0", "" + sf_oAN + sf_f);
+        test("null-84.0", "" + sf_oAN + sf_dM);
+        test("null58000000", "" + sf_oAN + f_i);
+        test("null-55000000", "" + sf_oAN + f_iM);
+        test("null1460392448", "" + sf_oAN + f_l);
+        test("nullC(70)", "" + sf_oAN + f_o);
+        test("null\u04511", "" + sf_oAN + sf_strU);
+        test("null8000", "" + sf_oAN + f_s);
+        test("null18", "" + sf_oAN + s_str);
+        test("null-1000000", "" + sf_oAN + s_iM);
+        test("null1000000", "" + sf_oAN + sf_I);
+        test("nullnull", "" + sf_oAN + f_oNtS);
+        test("nullfalse", "" + sf_oAN + f_bl);
+        test("nullnull", "" + sf_oAN + sf_iAN);
+        test("null-2000000", "" + sf_oAN + sf_iM);
+        test("null-820130816", "" + sf_oAN + f_lM);
+        test("nullnull", "" + sf_oAN + sf_oAN);
+        test("null25000000", "" + sf_oAN + s_I);
+        test("25000000-96.0", "" + s_I + s_dM);
+        test("25000000null", "" + s_I + s_oNtS);
+        test("25000000\u045176", "" + s_I + f_strU);
+        test("2500000092", "" + s_I + sf_strU2);
+        test("2500000051", "" + s_I + sf_strU1);
+        test("25000000null", "" + s_I + s_iAN);
+        test("25000000-54", "" + s_I + f_bM);
+        test("25000000-87.0", "" + s_I + f_fM);
+        test("25000000null", "" + s_I + s_oAN);
+        test("2500000019", "" + s_I + f_str);
+        test("25000000-41", "" + s_I + sf_bM);
+        test("25000000null", "" + s_I + sf_IN);
+        test("25000000T", "" + s_I + s_c);
+        test("25000000-42.0", "" + s_I + sf_fM);
+        test("2500000025", "" + s_I + s_b);
+        test("25000000null", "" + s_I + f_oN);
+        test("25000000-1410065408", "" + s_I + s_lM);
+        test("250000008.0", "" + s_I + s_d);
+        test("2500000055.0", "" + s_I + s_f);
+        test("2500000097000000", "" + s_I + s_i);
+        test("25000000-9900", "" + s_I + f_sM);
+        test("25000000935228928", "" + s_I + s_l);
+        test("25000000-8400", "" + s_I + sf_sM);
+        test("25000000C(82)", "" + s_I + s_o);
+        test("25000000null", "" + s_I + sf_oNtS);
+        test("25000000true", "" + s_I + s_bl);
+        test("250000003900", "" + s_I + s_s);
+        test("25000000null", "" + s_I + sf_oN);
+        test("2500000094000000", "" + s_I + f_I);
+        test("25000000null", "" + s_I + f_IN);
+        test("25000000true", "" + s_I + sf_bl);
+        test("250000005500", "" + s_I + sf_s);
+        test("25000000-2900", "" + s_I + s_sM);
+        test("25000000-194313216", "" + s_I + sf_l);
+        test("2500000012", "" + s_I + s_strU1);
+        test("25000000C(87)", "" + s_I + sf_o);
+        test("2500000091", "" + s_I + s_strU2);
+        test("2500000021", "" + s_I + f_strU1);
+        test("2500000018", "" + s_I + f_strU2);
+        test("25000000null", "" + s_I + f_iAN);
+        test("25000000null", "" + s_I + s_oN);
+        test("25000000\u045180", "" + s_I + s_strU);
+        test("25000000C", "" + s_I + sf_c);
+        test("2500000075", "" + s_I + sf_str);
+        test("25000000-43", "" + s_I + s_bM);
+        test("2500000080", "" + s_I + sf_b);
+        test("25000000null", "" + s_I + s_IN);
+        test("25000000-52.0", "" + s_I + s_fM);
+        test("2500000075000000", "" + s_I + sf_i);
+        test("2500000044", "" + s_I + f_b);
+        test("25000000-1705032704", "" + s_I + sf_lM);
+        test("25000000null", "" + s_I + f_oAN);
+        test("2500000083.0", "" + s_I + f_d);
+        test("25000000I", "" + s_I + f_c);
+        test("2500000094.0", "" + s_I + f_f);
+        test("2500000012.0", "" + s_I + sf_d);
+        test("25000000-99.0", "" + s_I + f_dM);
+        test("2500000017.0", "" + s_I + sf_f);
+        test("25000000-84.0", "" + s_I + sf_dM);
+        test("2500000058000000", "" + s_I + f_i);
+        test("25000000-55000000", "" + s_I + f_iM);
+        test("250000001460392448", "" + s_I + f_l);
+        test("25000000C(70)", "" + s_I + f_o);
+        test("25000000\u04511", "" + s_I + sf_strU);
+        test("250000008000", "" + s_I + f_s);
+        test("2500000018", "" + s_I + s_str);
+        test("25000000-1000000", "" + s_I + s_iM);
+        test("250000001000000", "" + s_I + sf_I);
+        test("25000000null", "" + s_I + f_oNtS);
+        test("25000000false", "" + s_I + f_bl);
+        test("25000000null", "" + s_I + sf_iAN);
+        test("25000000-2000000", "" + s_I + sf_iM);
+        test("25000000-820130816", "" + s_I + f_lM);
+        test("25000000null", "" + s_I + sf_oAN);
+        test("2500000025000000", "" + s_I + s_I);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/ImplicitStringConcatShapesTestGen.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.*;
+
+public class ImplicitStringConcatShapesTestGen {
+    public static String escapeToUnicode(String str) {
+        StringBuilder b = new StringBuilder();
+        for (char c : str.toCharArray()) {
+            if (c < 128) {
+                b.append(c);
+            } else {
+                b.append("\\u").append(String.format("%04X", (int) c));
+            }
+        }
+        return b.toString();
+    }
+
+    public static void main(String... args) throws IOException {
+        PrintWriter pw = new PrintWriter(System.out);
+
+        String[] types = {
+                "boolean",
+                "byte",
+                "byteMinus",
+                "char",
+                "short",
+                "shortMinus",
+                "int",
+                "intMinus",
+                "integer",
+                "integerNull",
+                "float",
+                "floatMinus",
+                "long",
+                "longMinus",
+                "double",
+                "doubleMinus",
+                "object",
+                "objectNull",
+                "objectNullToString",
+                "String",
+                "StringUTF16",
+                "StringU1",
+                "StringU2",
+                "intArrayNull",
+                "objectArrayNull",
+        };
+
+        for (String t : Files.readAllLines(Paths.get("ImplicitStringConcatShapes-head.template"))) {
+            pw.println(t);
+        }
+
+        Map<String, String> values = new HashMap<>();
+
+        Random current = new Random(12345);
+        for (int mode = 0; mode <= 2; mode++) {
+            for (String type : types) {
+                int i = current.nextInt(100);
+                boolean isStatic = (mode | 1) == 1;
+                boolean isFinal = (mode | 2) == 2;
+                String fieldName = (isStatic ? "s" : "") + (isFinal ? "f" : "") + "_" + typeSig(type);
+                String value = initValue(type, i);
+                String stringValue = stringValue(type, i);
+                values.put(fieldName, stringValue);
+                pw.printf("    %s %s %s %s = %s;%n", isStatic ? "static" : "", isFinal ? "final" : "", typeValue(type, i), fieldName, value);
+            }
+        }
+
+        pw.println();
+
+        List<String> lines = new ArrayList<>();
+        List<String> l = new ArrayList<>(values.keySet());
+
+        for (String l1 : l) {
+            lines.add(String.format("test(\"%s\", \"\" + %s);",
+                    escapeToUnicode(values.get(l1)),
+                    l1
+            ));
+        }
+
+        for (String l1 : l) {
+            for (String l2 : l) {
+                lines.add(String.format("test(\"%s\", \"\" + %s + %s);",
+                        escapeToUnicode(values.get(l1) + values.get(l2)),
+                        l1, l2
+                ));
+            }
+        }
+
+        final int STRIDE = 1000;
+        int strides = lines.size() / STRIDE + 1;
+
+        pw.println("    public void run() {");
+        for (int c = 0; c < strides; c++) {
+            pw.println("        run" + c + "();");
+        }
+        pw.println("    }");
+        pw.println();
+
+        for (int c = 0; c < strides; c++) {
+            pw.println("    public void run" + c + "() {");
+            for (String line : lines.subList(c * STRIDE, Math.min(lines.size(), (c+1) * STRIDE))) {
+                pw.println("        " + line);
+            }
+            pw.println("    }");
+            pw.println();
+        }
+
+        pw.println("}");
+
+        pw.flush();
+        pw.close();
+    }
+
+    private static String typeSig(String type) {
+        switch (type) {
+            case "boolean":             return "bl";
+            case "byte":                return "b";
+            case "byteMinus":           return "bM";
+            case "short":               return "s";
+            case "shortMinus":          return "sM";
+            case "char":                return "c";
+            case "int":                 return "i";
+            case "intMinus":            return "iM";
+            case "integer":             return "I";
+            case "integerNull":         return "IN";
+            case "float":               return "f";
+            case "floatMinus":          return "fM";
+            case "long":                return "l";
+            case "longMinus":           return "lM";
+            case "double":              return "d";
+            case "doubleMinus":         return "dM";
+            case "String":              return "str";
+            case "StringUTF16":         return "strU";
+            case "StringU1":            return "strU1";
+            case "StringU2":            return "strU2";
+            case "object":              return "o";
+            case "objectNull":          return "oN";
+            case "objectNullToString":  return "oNtS";
+            case "intArrayNull":        return "iAN";
+            case "objectArrayNull":     return "oAN";
+            default:
+                throw new IllegalStateException();
+        }
+    }
+
+    private static String typeValue(String type, int i) {
+        switch (type) {
+            case "boolean":
+            case "byte":
+            case "byteMinus":
+            case "char":
+            case "short":
+            case "shortMinus":
+            case "int":
+            case "intMinus":
+            case "float":
+            case "floatMinus":
+            case "long":
+            case "longMinus":
+            case "double":
+            case "doubleMinus":
+                return type.replace("Minus", "");
+            case "String":
+            case "StringUTF16":
+            case "StringU1":
+            case "StringU2":
+                return "String";
+            case "object":
+            case "objectNull":
+            case "objectNullToString":
+                return "Object";
+            case "integer":
+            case "integerNull":
+                return "Integer";
+            case "intArrayNull":
+                return "int[]";
+            case "objectArrayNull":
+                return "Object[]";
+            default:
+                throw new IllegalStateException();
+        }
+    }
+
+    private static String initValue(String type, int i) {
+        switch (type) {
+            case "boolean":
+                return String.valueOf((i & 1) == 1);
+            case "byte":
+                return String.valueOf(i);
+            case "byteMinus":
+                return String.valueOf(-i);
+            case "short":
+                return String.valueOf(i*100);
+            case "shortMinus":
+                return String.valueOf(-i*100);
+            case "intMinus":
+                return String.valueOf(-i*1_000_000);
+            case "int":
+            case "integer":
+                return String.valueOf(i*1_000_000);
+            case "long":
+                return String.valueOf(i*1_000_000_000) + "L";
+            case "longMinus":
+                return String.valueOf(-i*1_000_000_000) + "L";
+            case "char":
+                return "'" + (char)(i % 26 + 65) + "'";
+            case "double":
+                return String.valueOf(i) + ".0d";
+            case "doubleMinus":
+                return "-" + String.valueOf(i) + ".0d";
+            case "float":
+                return String.valueOf(i) + ".0f";
+            case "floatMinus":
+                return "-" + String.valueOf(i) + ".0f";
+            case "object":
+                return "new MyClass(" + i + ")";
+            case "objectNullToString":
+                return "new MyClassNullToString()";
+            case "integerNull":
+            case "objectNull":
+            case "intArrayNull":
+            case "objectArrayNull":
+                return "null";
+            case "String":
+                return "\"" + i + "\"";
+            case "StringUTF16":
+                return "\"\\u0451" + i + "\"";
+            case "StringU1":
+                return "\"\\u0001" + i + "\"";
+            case "StringU2":
+                return "\"\\u0002" + i + "\"";
+            default:
+                throw new IllegalStateException();
+        }
+    }
+
+    private static String stringValue(String type, int i) {
+        switch (type) {
+            case "boolean":
+                return String.valueOf((i & 1) == 1);
+            case "byte":
+                return String.valueOf(i);
+            case "byteMinus":
+                return String.valueOf(-i);
+            case "short":
+                return String.valueOf(i*100);
+            case "shortMinus":
+                return String.valueOf(-i*100);
+            case "intMinus":
+                return String.valueOf(-i*1_000_000);
+            case "int":
+            case "integer":
+                return String.valueOf(i*1_000_000);
+            case "long":
+                return String.valueOf(i*1_000_000_000);
+            case "longMinus":
+                return String.valueOf(-i*1_000_000_000);
+            case "char":
+                return String.valueOf((char) (i % 26 + 65));
+            case "double":
+            case "float":
+                return String.valueOf(i) + ".0";
+            case "doubleMinus":
+            case "floatMinus":
+                return "-" + String.valueOf(i) + ".0";
+            case "object":
+                return "C(" + i + ")";
+            case "integerNull":
+            case "objectNull":
+            case "objectNullToString":
+            case "intArrayNull":
+            case "objectArrayNull":
+                return "null";
+            case "String":
+                return "" + i;
+            case "StringUTF16":
+                return "\u0451" + i;
+            case "StringU1":
+                return "\u0001" + i;
+            case "StringU2":
+                return "\u0002" + i;
+            default:
+                throw new IllegalStateException();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/StringConcatFactoryInvariants.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ *
+ * 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.
+ */
+
+import java.io.Serializable;
+import java.lang.invoke.*;
+import java.util.concurrent.Callable;
+
+/**
+ * @test
+ * @summary Test input invariants for StringConcatFactory
+ *
+ * @compile StringConcatFactoryInvariants.java
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                                                                          StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                                                                    StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                                                                    StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                                                              StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                                                              StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                                                                          StringConcatFactoryInvariants
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true                                              StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true                                              StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true                                              StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true                                              StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true                                              StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true                                              StringConcatFactoryInvariants
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                                                              -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED                                                        -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT                                                  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT                                              -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ *
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB                  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED            -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ * @run main/othervm -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  -Djava.lang.invoke.stringConcat.debug=true  -Djava.lang.invoke.stringConcat.cache=true  StringConcatFactoryInvariants
+ *
+*/
+public class StringConcatFactoryInvariants {
+
+    private static final char TAG_ARG   = '\u0001';
+    private static final char TAG_CONST = '\u0002';
+
+    public static void main(String[] args) throws Throwable {
+        MethodHandles.Lookup lookup = MethodHandles.publicLookup();
+        String methodName = "foo";
+        MethodType mt = MethodType.methodType(String.class, String.class, int.class);
+        String recipe = "" + TAG_ARG + TAG_ARG + TAG_CONST;
+        String[] constants = new String[]{"bar"};
+
+        final int LIMIT = 200;
+
+        // Simple factory: check for dynamic arguments overflow
+        Class<?>[] underThreshold = new Class<?>[LIMIT - 1];
+        Class<?>[] threshold      = new Class<?>[LIMIT];
+        Class<?>[] overThreshold  = new Class<?>[LIMIT + 1];
+
+        StringBuilder sbUnderThreshold = new StringBuilder();
+        sbUnderThreshold.append(TAG_CONST);
+        for (int c = 0; c < LIMIT - 1; c++) {
+            underThreshold[c] = int.class;
+            threshold[c] = int.class;
+            overThreshold[c] = int.class;
+            sbUnderThreshold.append(TAG_ARG);
+        }
+        threshold[LIMIT - 1] = int.class;
+        overThreshold[LIMIT - 1] = int.class;
+        overThreshold[LIMIT] = int.class;
+
+        String recipeEmpty = "";
+        String recipeUnderThreshold = sbUnderThreshold.toString();
+        String recipeThreshold = sbUnderThreshold.append(TAG_ARG).toString();
+        String recipeOverThreshold = sbUnderThreshold.append(TAG_ARG).toString();
+
+        MethodType mtEmpty = MethodType.methodType(String.class);
+        MethodType mtUnderThreshold = MethodType.methodType(String.class, underThreshold);
+        MethodType mtThreshold = MethodType.methodType(String.class, threshold);
+        MethodType mtOverThreshold = MethodType.methodType(String.class, overThreshold);
+
+
+        // Check the basic functionality is working
+        {
+            CallSite cs = StringConcatFactory.makeConcat(lookup, methodName, mt);
+            test("foo42", (String) cs.getTarget().invokeExact("foo", 42));
+        }
+
+        {
+            CallSite cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, constants);
+            test("foo42bar", (String) cs.getTarget().invokeExact("foo", 42));
+        }
+
+        // Simple factory, check for nulls:
+        failNPE("Lookup is null",
+                () -> StringConcatFactory.makeConcat(null, methodName, mt));
+
+        failNPE("Method name is null",
+                () -> StringConcatFactory.makeConcat(lookup, null, mt));
+
+        failNPE("MethodType is null",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, null));
+
+        // Advanced factory, check for nulls:
+        failNPE("Lookup is null",
+                () -> StringConcatFactory.makeConcatWithConstants(null, methodName, mt, recipe, constants));
+
+        failNPE("Method name is null",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, null, mt, recipe, constants));
+
+        failNPE("MethodType is null",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, null, recipe, constants));
+
+        failNPE("Recipe is null",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, null, constants));
+
+        failNPE("Constants vararg is null",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, null));
+
+        // Simple factory, check for return type
+        fail("Return type: void",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(void.class, String.class, int.class)));
+
+        fail("Return type: int",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(int.class, String.class, int.class)));
+
+        fail("Return type: StringBuilder",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(StringBuilder.class, String.class, int.class)));
+
+        ok("Return type: Object",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(Object.class, String.class, int.class)));
+
+        ok("Return type: CharSequence",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(CharSequence.class, String.class, int.class)));
+
+        ok("Return type: Serializable",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(Serializable.class, String.class, int.class)));
+
+        // Advanced factory, check for return types
+        fail("Return type: void",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(void.class, String.class, int.class), recipe, constants));
+
+        fail("Return type: int",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(int.class, String.class, int.class), recipe, constants));
+
+        fail("Return type: StringBuilder",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(StringBuilder.class, String.class, int.class), recipe, constants));
+
+        ok("Return type: Object",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(Object.class, String.class, int.class), recipe, constants));
+
+        ok("Return type: CharSequence",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(CharSequence.class, String.class, int.class), recipe, constants));
+
+        ok("Return type: Serializable",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(Serializable.class, String.class, int.class), recipe, constants));
+
+        // Simple factory: check for dynamic arguments overflow
+        ok("Dynamic arguments is under limit",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, mtUnderThreshold));
+
+        ok("Dynamic arguments is at the limit",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, mtThreshold));
+
+        fail("Dynamic arguments is over the limit",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, mtOverThreshold));
+
+        // Advanced factory: check for dynamic arguments overflow
+        ok("Dynamic arguments is under limit",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtUnderThreshold, recipeUnderThreshold, constants));
+
+        ok("Dynamic arguments is at the limit",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, constants));
+
+        fail("Dynamic arguments is over the limit",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtOverThreshold, recipeOverThreshold, constants));
+
+        // Advanced factory: check for mismatched recipe and Constants
+        ok("Static arguments and recipe match",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar"));
+
+        fail("Static arguments and recipe mismatch",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar", "baz"));
+
+        // Advanced factory: check for mismatched recipe and dynamic arguments
+        fail("Dynamic arguments and recipe mismatch",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeUnderThreshold, constants));
+
+        ok("Dynamic arguments and recipe match",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, constants));
+
+        fail("Dynamic arguments and recipe mismatch",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeOverThreshold, constants));
+
+        // Test passing array as constant
+        {
+            String[] arg = {"boo", "bar"};
+
+            CallSite cs1 = StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST + TAG_CONST, arg);
+            test("42boobar", (String) cs1.getTarget().invokeExact(42));
+        }
+
+        // Test passing null constant
+        ok("Can pass regular constants",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST, "foo"));
+
+        failNPE("Cannot pass null constants",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST, new String[]{null}));
+
+        // Simple factory: test empty arguments
+        ok("Ok to pass empty arguments",
+                () -> StringConcatFactory.makeConcat(lookup, methodName, mtEmpty));
+
+        // Advanced factory: test empty arguments
+        ok("Ok to pass empty arguments",
+                () -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtEmpty, recipeEmpty));
+    }
+
+    public static void ok(String msg, Callable runnable) {
+        try {
+            runnable.call();
+        } catch (Throwable e) {
+            e.printStackTrace();
+            throw new IllegalStateException(msg + ", should have passed", e);
+        }
+    }
+
+    public static void fail(String msg, Callable runnable) {
+        boolean expected = false;
+        try {
+            runnable.call();
+        } catch (StringConcatException e) {
+            expected = true;
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+
+        if (!expected) {
+            throw new IllegalStateException(msg + ", should have failed with StringConcatException");
+        }
+    }
+
+
+    public static void failNPE(String msg, Callable runnable) {
+        boolean expected = false;
+        try {
+            runnable.call();
+        } catch (NullPointerException e) {
+            expected = true;
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+
+        if (!expected) {
+            throw new IllegalStateException(msg + ", should have failed with NullPointerException");
+        }
+    }
+
+    public static void test(String expected, String actual) {
+       // Fingers crossed: String concat should work.
+       if (!expected.equals(actual)) {
+           StringBuilder sb = new StringBuilder();
+           sb.append("Expected = ");
+           sb.append(expected);
+           sb.append(", actual = ");
+           sb.append(actual);
+           throw new IllegalStateException(sb.toString());
+       }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/update-tests.sh	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,26 @@
+# Copyright (c) 2015, 2016, 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.
+#
+# 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.
+
+#!/bin/bash
+
+javac ImplicitStringConcatShapesTestGen.java
+java ImplicitStringConcatShapesTestGen > ImplicitStringConcatShapes.java
+rm ImplicitStringConcatShapesTestGen.class
--- a/jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java	Thu Jan 28 15:43:15 2016 -0800
@@ -28,7 +28,7 @@
  * @compile InvokeDynamicPrintArgs.java
  * @run main/othervm
  *      indify.Indify
- *      --verify-specifier-count=3
+ *      --verify-specifier-count=8
  *      --expand-properties --classpath ${test.classes}
  *      --java test.java.lang.invoke.InvokeDynamicPrintArgs --check-output
  * @run main/othervm
--- a/jdk/test/java/lang/invoke/MethodHandleConstants.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/java/lang/invoke/MethodHandleConstants.java	Thu Jan 28 15:43:15 2016 -0800
@@ -28,7 +28,7 @@
  * @compile MethodHandleConstants.java
  * @run main/othervm
  *      indify.Indify
- *      --verify-specifier-count=0
+ *      --verify-specifier-count=4
  *      --expand-properties --classpath ${test.classes}
  *      --java test.java.lang.invoke.MethodHandleConstants --check-output
  * @run main/othervm
--- a/jdk/test/java/net/SocketPermission/SocketPermissionTest.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/java/net/SocketPermission/SocketPermissionTest.java	Thu Jan 28 15:43:15 2016 -0800
@@ -25,8 +25,7 @@
  * @test
  * @bug 8047031
  * @summary SocketPermission tests for legacy socket types
- * @library ../../../lib/testlibrary
- * @run testng/othervm/policy=policy SocketPermissionTest
+ * @run testng/othervm SocketPermissionTest
  * @key intermittent
  */
 import java.io.IOException;
@@ -39,186 +38,279 @@
 import java.net.SocketPermission;
 import java.security.AccessControlContext;
 import java.security.AccessController;
+import java.security.CodeSource;
 import java.security.Permission;
+import java.security.PermissionCollection;
 import java.security.Permissions;
-import java.security.PrivilegedAction;
+import java.security.Policy;
+import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
-import java.util.Arrays;
-import java.util.function.Function;
-import java.util.function.IntConsumer;
-import static jdk.testlibrary.Utils.getFreePort;
+
 import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
 
 public class SocketPermissionTest {
-    private int freePort = -1;
-
-    //positive tests
-    @Test(dataProvider = "positiveProvider")
-    public void testPositive(Function<String, AccessControlContext> genAcc, IntConsumer func) {
-        String addr = "localhost:" + freePort;
-        AccessControlContext acc = genAcc.apply(addr);
-        AccessController.doPrivileged((PrivilegedAction) () -> {
-            func.accept(freePort);
-            return null;
-        }, acc);
-    }
-
-    //negative tests
-    @Test(dataProvider = "negativeProvider", expectedExceptions = SecurityException.class)
-    public void testNegative(AccessControlContext acc, IntConsumer func) {
-        AccessController.doPrivileged((PrivilegedAction) () -> {
-            func.accept(freePort);
-            return null;
-        }, acc);
-    }
 
     @BeforeMethod
-    public void setFreePort() throws Exception {
-        freePort = getFreePort();
+    public void setupSecurityManager() throws Exception {
+        // All permissions, a specific ACC will be used to when testing
+        // with a reduced permission set.
+        Policy.setPolicy(new Policy() {
+             final PermissionCollection perms = new Permissions();
+             { perms.add(new java.security.AllPermission()); }
+             public PermissionCollection getPermissions(ProtectionDomain domain) {
+                 return perms;
+             }
+             public PermissionCollection getPermissions(CodeSource codesource) {
+                 return perms;
+             }
+             public boolean implies(ProtectionDomain domain, Permission perm) {
+                 return perms.implies(perm);
+             }
+        } );
+        System.setSecurityManager(new SecurityManager());
     }
 
-    @DataProvider
-    public Object[][] positiveProvider() {
-        //test for SocketPermission "host:port","connect,resolve";
-        Function<String, AccessControlContext> generateAcc1 = (addr) -> getAccessControlContext(
-                new SocketPermission(addr, "listen, connect,resolve"));
-        IntConsumer func1 = (i) -> connectSocketTest(i);
-        IntConsumer func2 = (i) -> connectDatagramSocketTest(i);
+    static final AccessControlContext RESTRICTED_ACC = getAccessControlContext();
 
-        //test for SocketPermission "localhost:1024-","accept";
-        Function<String, AccessControlContext> generateAcc2 = (addr) -> getAccessControlContext(
-                new SocketPermission(addr, "listen,connect,resolve"),
-                new SocketPermission("localhost:1024-", "accept"));
-        IntConsumer func3 = (i) -> acceptServerSocketTest(i);
+    @Test
+    public void connectSocketTest() throws Exception {
+        try (ServerSocket ss = new ServerSocket(0)) {
+            int port = ss.getLocalPort();
+
+            String addr = "localhost:" + port;
+            AccessControlContext acc = getAccessControlContext(
+                    new SocketPermission(addr, "listen,connect,resolve"));
 
-        //test for SocketPermission "229.227.226.221", "connect,accept"
-        Function<String, AccessControlContext> generateAcc3 = (addr) -> getAccessControlContext(
-                new SocketPermission(addr, "listen,resolve"),
-                new SocketPermission("229.227.226.221", "connect,accept"));
-        IntConsumer func4 = (i) -> sendDatagramPacketTest(i);
-        IntConsumer func5 = (i) -> joinGroupMulticastTest(i);
+            // Positive
+            AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                try (Socket client = new Socket(InetAddress.getLocalHost(), port)) {
+                }
+                return null;
+            }, acc);
 
-        //test for SocketPermission "host:port", "listen"
-        Function<String, AccessControlContext> generateAcc4 = (addr) -> getAccessControlContext(
-                new SocketPermission(addr, "listen"));
-        IntConsumer func6 = (i) -> listenDatagramSocketTest(i);
-        IntConsumer func7 = (i) -> listenMulticastSocketTest(i);
-        IntConsumer func8 = (i) -> listenServerSocketTest(i);
-
-        return new Object[][]{
-            {generateAcc1, func1},
-            {generateAcc1, func2},
-            {generateAcc2, func3},
-            {generateAcc3, func4},
-            {generateAcc3, func5},
-            {generateAcc4, func6},
-            {generateAcc4, func7},
-            {generateAcc4, func8}
-        };
+            //Negative
+            try {
+                AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                    Socket client = new Socket(InetAddress.getLocalHost(), port);
+                    fail("Expected SecurityException");
+                    return null;
+                }, RESTRICTED_ACC);
+            } catch (SecurityException expected) { }
+        }
     }
 
-    @DataProvider
-    public Object[][] negativeProvider() {
-        IntConsumer[] funcs = {i -> connectSocketTest(i),
-            i -> connectDatagramSocketTest(i), i -> acceptServerSocketTest(i),
-            i -> sendDatagramPacketTest(i), i -> joinGroupMulticastTest(i),
-            i -> listenDatagramSocketTest(i), i -> listenMulticastSocketTest(i),
-            i -> listenServerSocketTest(i)};
-        return Arrays.stream(funcs).map(f -> {
-            //Construct an AccessControlContext without SocketPermission
+    @Test
+    public void connectDatagramSocketTest() throws Exception {
+        byte[] msg = "Hello".getBytes(UTF_8);
+        InetAddress lh = InetAddress.getLocalHost();
+
+        try (DatagramSocket ds = new DatagramSocket(0)) {
+            int port = ds.getLocalPort();
+
+            String addr = lh.getHostAddress() + ":" + port;
             AccessControlContext acc = getAccessControlContext(
-                    new java.io.FilePermission("<<ALL FILES>>", "read,write,execute,delete"),
-                    new java.net.NetPermission("*"),
-                    new java.util.PropertyPermission("*", "read,write"),
-                    new java.lang.reflect.ReflectPermission("*"),
-                    new java.lang.RuntimePermission("*"),
-                    new java.security.SecurityPermission("*"),
-                    new java.io.SerializablePermission("*"));
-            return new Object[]{acc, f};
-        }).toArray(Object[][]::new);
+                    new SocketPermission(addr, "connect,resolve"));
+
+            // Positive
+            AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                DatagramPacket dp = new DatagramPacket(msg, msg.length, lh, port);
+                ds.send(dp);
+                return null;
+            }, acc);
+
+            // Negative
+            try {
+                AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                    DatagramPacket dp = new DatagramPacket(msg, msg.length, lh, port);
+                    ds.send(dp);
+                    fail("Expected SecurityException");
+                    return null;
+                }, RESTRICTED_ACC);
+            } catch (SecurityException expected) { }
+        }
     }
 
-    public void connectSocketTest(int port) {
-        try (ServerSocket server = new ServerSocket(port);
-                Socket client = new Socket(InetAddress.getLocalHost(), port);) {
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
+    @Test
+    public void acceptServerSocketTest() throws Exception {
+        try (ServerSocket ss = new ServerSocket(0)) {
+            int port = ss.getLocalPort();
+
+            String addr = "localhost:" + port;
+            AccessControlContext acc = getAccessControlContext(
+                    new SocketPermission(addr, "listen,connect,resolve"),
+                    new SocketPermission("localhost:1024-", "accept"));
+
+            // Positive
+            AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                InetAddress me = InetAddress.getLocalHost();
+                try (Socket client = new Socket(me, port)) {
+                    ss.accept();
+                }
+                return null;
+            }, acc);
+
+            // Negative
+            try {
+                AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                    InetAddress me = InetAddress.getLocalHost();
+                    try (Socket client = new Socket(me, port)) {
+                        ss.accept();
+                    }
+                    fail("Expected SecurityException");
+                    return null;
+                }, RESTRICTED_ACC);
+            } catch (SecurityException expected) { }
         }
     }
 
-    public void connectDatagramSocketTest(int port) {
-        String msg = "Hello";
-        try {
-            InetAddress me = InetAddress.getLocalHost();
-            try (DatagramSocket ds = new DatagramSocket(port, me)) {
-                DatagramPacket dp = new DatagramPacket(msg.getBytes(),
-                        msg.length(), me, port);
-                ds.send(dp);
-            }
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
+    @Test
+    public void sendDatagramPacketTest() throws Exception {
+        byte[] msg = "Hello".getBytes(UTF_8);
+        InetAddress group = InetAddress.getByName("229.227.226.221");
+
+        try (DatagramSocket ds = new DatagramSocket(0)) {
+            int port = ds.getLocalPort();
+
+            String addr = "localhost:" + port;
+            //test for SocketPermission "229.227.226.221", "connect,accept"
+            AccessControlContext acc = getAccessControlContext(
+                    new SocketPermission(addr, "listen,resolve"),
+                    new SocketPermission("229.227.226.221", "connect,accept"));
 
-    public void acceptServerSocketTest(int port) {
-        try {
-            InetAddress me = InetAddress.getLocalHost();
-            try (ServerSocket server = new ServerSocket(port)) {
-                Socket client = new Socket(me, port);
-                server.accept();
-            }
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
+            // Positive
+            AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                DatagramPacket hi = new DatagramPacket(msg, msg.length, group, port);
+                ds.send(hi);
+                return null;
+            }, acc);
+
+            // Negative
+            try {
+                AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                    DatagramPacket hi = new DatagramPacket(msg, msg.length, group, port);
+                    ds.send(hi);
+                    fail("Expected SecurityException");
+                    return null;
+                }, RESTRICTED_ACC);
+            } catch (SecurityException expected) { }
         }
     }
 
-    public static void sendDatagramPacketTest(int port) {
-        String msg = "Hello";
-        try {
-            InetAddress group = InetAddress.getByName("229.227.226.221");
-            try (DatagramSocket s = new DatagramSocket(port)) {
-                DatagramPacket hi = new DatagramPacket(msg.getBytes(),
-                        msg.length(), group, port);
-                s.send(hi);
-            }
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
+    @Test
+    public void joinGroupMulticastTest() throws Exception {
+        InetAddress group = InetAddress.getByName("229.227.226.221");
+        try (MulticastSocket s = new MulticastSocket(0)) {
+            int port = s.getLocalPort();
 
-    public void joinGroupMulticastTest(int port) {
-        try {
-            InetAddress group = InetAddress.getByName("229.227.226.221");
-            try (MulticastSocket s = new MulticastSocket(port)) {
+            String addr = "localhost:" + port;
+            AccessControlContext acc = getAccessControlContext(
+                    new SocketPermission(addr, "listen,resolve"),
+                    new SocketPermission("229.227.226.221", "connect,accept"));
+
+            // Positive
+            AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
                 s.joinGroup(group);
                 s.leaveGroup(group);
-            }
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
+                return null;
+            }, acc);
+
+            // Negative
+            try {
+                AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                    s.joinGroup(group);
+                    s.leaveGroup(group);
+                    fail("Expected SecurityException");
+                    return null;
+                }, RESTRICTED_ACC);
+            } catch (SecurityException expected) { }
         }
+
     }
 
-    public void listenDatagramSocketTest(int port) {
-        try (DatagramSocket ds = new DatagramSocket(port)) {
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
+    @Test
+    public void listenDatagramSocketTest() throws Exception {
+        // the hardcoded port number doesn't really matter since we expect the
+        // security permission to be checked before the underlying operation.
+        int port = 8899;
+        String addr = "localhost:" + port;
+        AccessControlContext acc = getAccessControlContext(
+                new SocketPermission(addr, "listen"));
+
+        // Positive
+        AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+            try (DatagramSocket ds = new DatagramSocket(port)) { }
+            catch (IOException intermittentlyExpected) { /* ignore */ }
+            return null;
+        }, acc);
+
+        // Negative
+        try {
+            AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                try (DatagramSocket ds = new DatagramSocket(port)) { }
+                catch (IOException intermittentlyExpected) { /* ignore */ }
+                fail("Expected SecurityException");
+                return null;
+            }, RESTRICTED_ACC);
+        } catch (SecurityException expected) { }
     }
 
-    public void listenMulticastSocketTest(int port) {
-        try (MulticastSocket ms = new MulticastSocket(port)) {
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
+    @Test
+    public void listenMulticastSocketTest() throws Exception {
+        // the hardcoded port number doesn't really matter since we expect the
+        // security permission to be checked before the underlying operation.
+        int port = 8899;
+        String addr = "localhost:" + port;
+        AccessControlContext acc = getAccessControlContext(
+                new SocketPermission(addr, "listen"));
+
+        // Positive
+        AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+            try (MulticastSocket ms = new MulticastSocket(port)) { }
+            catch (IOException intermittentlyExpected) { /* ignore */ }
+            return null;
+        }, acc);
+
+        // Negative
+        try {
+            AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                try (MulticastSocket ms = new MulticastSocket(port)) { }
+                catch (IOException intermittentlyExpected) { /* ignore */ }
+                fail("Expected SecurityException");
+                return null;
+            }, RESTRICTED_ACC);
+        } catch (SecurityException expected) { }
     }
 
-    public void listenServerSocketTest(int port) {
-        try (ServerSocket ms = new ServerSocket(port)) {
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
+    @Test
+    public void listenServerSocketTest() throws Exception {
+        // the hardcoded port number doesn't really matter since we expect the
+        // security permission to be checked before the underlying operation.
+        int port = 8899;
+        String addr = "localhost:" + port;
+        AccessControlContext acc = getAccessControlContext(
+                new SocketPermission(addr, "listen"));
+
+        // Positive
+        AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+            try (ServerSocket ss = new ServerSocket(port)) { }
+            catch (IOException intermittentlyExpected) { /* ignore */ }
+            return null;
+        }, acc);
+
+        // Negative
+        try {
+            AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                try (ServerSocket ss = new ServerSocket(port)) { }
+                catch (IOException intermittentlyExpected) { /* ignore */ }
+                fail("Expected SecurityException");
+                return null;
+            }, RESTRICTED_ACC);
+        } catch (SecurityException expected) { }
+
     }
 
     private static AccessControlContext getAccessControlContext(Permission... ps) {
@@ -234,4 +326,15 @@
         return new AccessControlContext(new ProtectionDomain[]{pd});
     }
 
+    // Standalone entry point for running with, possibly older, JDKs.
+    public static void main(String[] args) throws Throwable {
+        SocketPermissionTest test = new SocketPermissionTest();
+        test.setupSecurityManager();
+        for (java.lang.reflect.Method m : SocketPermissionTest.class.getDeclaredMethods()) {
+            if (m.getAnnotation(Test.class) != null) {
+                System.out.println("Invoking " + m.getName());
+                m.invoke(test);
+            }
+        }
+    }
 }
--- a/jdk/test/java/net/SocketPermission/policy	Thu Jan 28 09:43:08 2016 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-grant {
- permission java.security.AllPermission;
-};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URL/LocaleDependentURLTest.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 8147962
+ * @summary Verify URLs with upper-case protocols parse correctly in any
+ *          locale
+ * @run main/othervm LocaleDependentURLTest
+ */
+import java.net.*;
+import java.util.Locale;
+
+public class LocaleDependentURLTest {
+
+    public static void main(String args[]) throws MalformedURLException {
+        for (Locale locale : Locale.getAvailableLocales()) {
+            Locale.setDefault(locale);
+            new URL("FILE:///TMP/X");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/WatchService/LotsOfCloses.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ * 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.
+ */
+
+/* @test
+ * @bug 8148192
+ * @summary Invoking close asynchronously can cause register to fail with
+ *     an IOException rather than a ClosedWatchServiceException
+ * @run main LotsOfCloses
+ */
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.ClosedWatchServiceException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchService;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+public class LotsOfCloses {
+
+    private static final Random RAND = new Random();
+
+    public static void main(String[] args) throws Exception {
+        Path dir = Files.createTempDirectory("tmp");
+        ExecutorService pool = Executors.newCachedThreadPool();
+        try {
+
+            // run the test repeatedly
+            long start = System.currentTimeMillis();
+            while ((System.currentTimeMillis() - start) < 5000) {
+                test(dir, pool);
+            }
+
+        } finally {
+            pool.shutdown();
+        }
+
+    }
+
+    /**
+     * Create a WatchService to watch for changes in the given directory
+     * and then attempt to close the WatchService and change a registration
+     * at the same time.
+     */
+    static void test(Path dir, ExecutorService pool) throws Exception {
+        WatchService watcher = FileSystems.getDefault().newWatchService();
+
+        // initial registration
+        dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
+
+        // submit tasks to close the WatchService and update the registration
+        Future<Void> closeResult;
+        Future<Boolean> registerResult;
+
+        if (RAND.nextBoolean()) {
+            closeResult = pool.submit(newCloserTask(watcher));
+            registerResult = pool.submit(newRegisterTask(watcher, dir));
+        } else {
+            registerResult = pool.submit(newRegisterTask(watcher, dir));
+            closeResult = pool.submit(newCloserTask(watcher));
+        }
+
+        closeResult.get();
+        registerResult.get();
+
+    }
+
+    /**
+     * Returns a task that closes the given WatchService.
+     */
+    static Callable<Void> newCloserTask(WatchService watcher) {
+        return () ->  {
+            try {
+                watcher.close();
+                return null;
+            } catch (IOException ioe) {
+                throw new UncheckedIOException(ioe);
+            }
+        };
+    }
+
+    /**
+     * Returns a task that updates the registration of a directory with
+     * a WatchService.
+     */
+    static Callable<Boolean> newRegisterTask(WatchService watcher, Path dir) {
+        return () -> {
+            try {
+                dir.register(watcher, StandardWatchEventKinds.ENTRY_DELETE);
+                return true;
+            } catch (ClosedWatchServiceException e) {
+                return false;
+            } catch (IOException ioe) {
+                throw new UncheckedIOException(ioe);
+            }
+        };
+    }
+}
--- a/jdk/test/java/util/ArrayList/ArrayManagement.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/java/util/ArrayList/ArrayManagement.java	Thu Jan 28 15:43:15 2016 -0800
@@ -83,6 +83,7 @@
         int oldCapacity = capacity(list);
         int oldModCount = modCount(list);
         list.ensureCapacity(capacity);
+        assertTrue(capacity(list) >= capacity || capacity(list) == 0);
         assertEquals(modCount(list),
                      (capacity(list) == oldCapacity)
                      ? oldModCount
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Vector/ArrayManagement.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2016 Google, Inc.  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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8148174
+ * @summary brittle white box test of internal array management
+ * @run testng ArrayManagement
+ */
+
+import java.lang.reflect.Field;
+import java.util.AbstractList;
+import java.util.Vector;
+import java.util.Collections;
+import java.util.List;
+import java.util.SplittableRandom;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class ArrayManagement {
+
+    /**
+     * A Vector that exposes all protected elements, and checks class
+     * invariants.
+     */
+    static class PublicVector<E> extends Vector<E> {
+        public PublicVector() { super(); }
+        public PublicVector(int capacity) { super(capacity); }
+        public PublicVector(int capacity, int capacityIncrement) {
+            super(capacity, capacityIncrement);
+        }
+        public Object[] elementData()  { return elementData; }
+        public int modCount()          { return modCount; }
+        public int capacityIncrement() { return capacityIncrement; }
+        public int capacity()          { return elementData.length; }
+
+        public void ensureCapacity(int minCapacity) {
+            int oldCapacity = capacity();
+            int oldModCount = modCount();
+            super.ensureCapacity(minCapacity);
+            assertTrue(capacity() >= minCapacity);
+            if (minCapacity <= oldCapacity)
+                assertEquals(capacity(), oldCapacity);
+            if (minCapacity > 0)
+                assertEquals(modCount(), oldModCount + 1);
+        }
+    }
+
+    static final int DEFAULT_CAPACITY = 10;
+    static final SplittableRandom rnd = new SplittableRandom();
+
+    static int newCapacity(int oldCapacity) {
+        return 2 * oldCapacity;
+    }
+
+    static List<Object> singletonList() {
+        return Collections.singletonList(Boolean.TRUE);
+    }
+
+    /** Opportunistically randomly test various add operations. */
+    static void addOneElement(PublicVector<Object> list) {
+        int size = list.size();
+        int modCount = list.modCount();
+        switch (rnd.nextInt(4)) {
+        case 0: assertTrue(list.add(Boolean.TRUE)); break;
+        case 1: list.add(size, Boolean.TRUE); break;
+        case 2: assertTrue(list.addAll(singletonList())); break;
+        case 3: assertTrue(list.addAll(size, singletonList())); break;
+        default: throw new AssertionError();
+        }
+        assertEquals(list.modCount(), modCount + 1);
+        assertEquals(list.size(), size + 1);
+    }
+
+    @Test public void defaultCapacity() {
+        PublicVector<Object> list = new PublicVector<>();
+        assertEquals(new PublicVector<Object>().capacity(), DEFAULT_CAPACITY);
+        for (int i = 0; i < DEFAULT_CAPACITY; i++) {
+            addOneElement(list);
+            assertEquals(list.capacity(), DEFAULT_CAPACITY);
+        }
+        addOneElement(list);
+        assertEquals(list.capacity(), newCapacity(DEFAULT_CAPACITY));
+    }
+
+    @Test public void defaultCapacityEnsureCapacity() {
+        PublicVector<Object> list = new PublicVector<>();
+        for (int i = 0; i <= DEFAULT_CAPACITY; i++) {
+            list.ensureCapacity(i);     // no-op!
+            assertEquals(list.capacity(), DEFAULT_CAPACITY);
+        }
+        for (int i = 0; i < DEFAULT_CAPACITY; i++) {
+            addOneElement(list);
+            assertEquals(list.capacity(), DEFAULT_CAPACITY);
+        }
+        addOneElement(list);
+        assertEquals(list.capacity(), newCapacity(DEFAULT_CAPACITY));
+        {
+            int capacity = list.capacity();
+            list.ensureCapacity(capacity + 1);
+            assertEquals(list.capacity(), newCapacity(capacity));
+        }
+        {
+            int capacity = list.capacity();
+            list.ensureCapacity(3 * capacity);
+            assertEquals(list.capacity(), 3 * capacity);
+        }
+    }
+
+    @Test public void ensureCapacityBeyondDefaultCapacity() {
+        PublicVector<Object> list = new PublicVector<>();
+        list.ensureCapacity(DEFAULT_CAPACITY + 1);
+        assertEquals(list.capacity(), newCapacity(DEFAULT_CAPACITY));
+    }
+
+    @Test public void explicitZeroCapacity() {
+        PublicVector<Object> list = new PublicVector<>(0);
+        assertEquals(list.capacity(), 0);
+        addOneElement(list);
+        assertEquals(list.capacity(), 1);
+        addOneElement(list);
+        assertEquals(list.capacity(), 2);
+        addOneElement(list);
+        assertEquals(list.capacity(), 4);
+        addOneElement(list);
+        assertEquals(list.capacity(), 4);
+        addOneElement(list);
+        assertEquals(list.capacity(), 8);
+        addOneElement(list);
+        assertEquals(list.capacity(), 8);
+        addOneElement(list);
+        assertEquals(list.capacity(), 8);
+        list.clear();
+        assertEquals(list.capacity(), 8);
+    }
+
+    @Test public void explicitZeroCapacityWithCapacityIncrement() {
+        PublicVector<Object> list = new PublicVector<>(0, 2);
+        assertEquals(list.capacity(), 0);
+        addOneElement(list);
+        assertEquals(list.capacity(), 2);
+        addOneElement(list);
+        assertEquals(list.capacity(), 2);
+        addOneElement(list);
+        assertEquals(list.capacity(), 4);
+        addOneElement(list);
+        assertEquals(list.capacity(), 4);
+        addOneElement(list);
+        assertEquals(list.capacity(), 6);
+        addOneElement(list);
+        assertEquals(list.capacity(), 6);
+        addOneElement(list);
+        assertEquals(list.capacity(), 8);
+        list.clear();
+        assertEquals(list.capacity(), 8);
+    }
+
+    @Test public void explicitLargeCapacity() {
+        int n = DEFAULT_CAPACITY * 3;
+        PublicVector<Object> list = new PublicVector<>(n);
+        assertEquals(list.capacity(), n);
+        list.ensureCapacity(0);
+        list.ensureCapacity(n);
+        for (int i = 0; i < n; i++) addOneElement(list);
+        assertEquals(list.capacity(), n);
+
+        addOneElement(list);
+        assertEquals(list.capacity(), newCapacity(n));
+    }
+
+    @Test public void explicitLargeCapacityWithCapacityIncrement() {
+        int n = DEFAULT_CAPACITY * 3;
+        PublicVector<Object> list = new PublicVector<>(n, 2);
+        assertEquals(list.capacity(), n);
+        list.ensureCapacity(0);
+        list.ensureCapacity(n);
+        for (int i = 0; i < n; i++) addOneElement(list);
+        assertEquals(list.capacity(), n);
+
+        addOneElement(list);
+        assertEquals(list.capacity(), n + 2);
+    }
+
+    @Test public void emptyArraysAreNotShared() {
+        assertNotSame(new PublicVector<Object>(0).elementData(),
+                      new PublicVector<Object>(0).elementData());
+    }
+
+    @Test public void negativeCapacity() {
+        for (int capacity : new int[] { -1, Integer.MIN_VALUE }) {
+            try {
+                new Vector<Object>(capacity);
+                fail("should throw");
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Vector/Bug8148174.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Google, Inc.  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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8148174
+ * @summary repro for: NegativeArraySizeException in Vector.grow(int)
+ * @run main/othervm -Xmx17g Bug8148174
+ * @ignore This test has huge memory requirements
+ */
+
+public class Bug8148174 {
+    public static void main(String[] args) {
+        int size = Integer.MAX_VALUE - 2;
+        java.util.Vector<Object> huge = new java.util.Vector<>(size);
+        for (int i = 0; i < size; i++)
+            huge.add(null);
+        try {
+            huge.addAll(huge);
+            throw new Error("expected OutOfMemoryError not thrown");
+        } catch (OutOfMemoryError success) {}
+    }
+}
--- a/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java	Thu Jan 28 15:43:15 2016 -0800
@@ -36,17 +36,17 @@
  * @author Doug Lea
  * @bug 8004138
  * @summary Check if ForkJoinPool table leaks thrown exceptions.
- * @run main/othervm -Xmx2200k FJExceptionTableLeak
- * @key intermittent
+ * @run main/othervm -Xmx8m -Djava.util.concurrent.ForkJoinPool.common.parallelism=4 FJExceptionTableLeak
  */
 
 import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.RecursiveAction;
 
 public class FJExceptionTableLeak {
-    // This test was observed to fail with jdk7 -Xmx2200k,
+    // This test was observed to fail with pre-bug-fix jdk7 -Xmx8m,
     // using STEPS = 220 and TASKS_PER_STEP = 100
-    static final int STEPS = 500;
+    static final int PRE_BUG_FIX_FAILURE_STEPS = 220;
+    static final int STEPS = 10 * PRE_BUG_FIX_FAILURE_STEPS;
     static final int TASKS_PER_STEP = 100;
 
     static class FailingTaskException extends RuntimeException {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/nio/ch/TestMaxCachedBufferSize.java	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ * 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.
+ */
+
+import java.io.IOException;
+
+import java.lang.management.BufferPoolMXBean;
+import java.lang.management.ManagementFactory;
+
+import java.nio.ByteBuffer;
+
+import java.nio.channels.FileChannel;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static java.nio.file.StandardOpenOption.CREATE;
+import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
+import static java.nio.file.StandardOpenOption.WRITE;
+
+import java.util.List;
+import java.util.Random;
+
+/*
+ * @test
+ * @build TestMaxCachedBufferSize
+ * @run main/othervm TestMaxCachedBufferSize
+ * @run main/othervm -Djdk.nio.maxCachedBufferSize=0 TestMaxCachedBufferSize
+ * @run main/othervm -Djdk.nio.maxCachedBufferSize=2000 TestMaxCachedBufferSize
+ * @run main/othervm -Djdk.nio.maxCachedBufferSize=100000 TestMaxCachedBufferSize
+ * @run main/othervm -Djdk.nio.maxCachedBufferSize=10000000 TestMaxCachedBufferSize
+ *
+ * @summary Test the implementation of the jdk.nio.maxCachedBufferSize property.
+ */
+public class TestMaxCachedBufferSize {
+    private static final int DEFAULT_ITERS = 10 * 1000;
+    private static final int DEFAULT_THREAD_NUM = 4;
+
+    private static final int SMALL_BUFFER_MIN_SIZE =  4 * 1024;
+    private static final int SMALL_BUFFER_MAX_SIZE = 64 * 1024;
+    private static final int SMALL_BUFFER_DIFF_SIZE =
+                                 SMALL_BUFFER_MAX_SIZE - SMALL_BUFFER_MIN_SIZE;
+
+    private static final int LARGE_BUFFER_MIN_SIZE =      512 * 1024;
+    private static final int LARGE_BUFFER_MAX_SIZE = 4 * 1024 * 1024;
+    private static final int LARGE_BUFFER_DIFF_SIZE =
+                                 LARGE_BUFFER_MAX_SIZE - LARGE_BUFFER_MIN_SIZE;
+
+    private static final int LARGE_BUFFER_FREQUENCY = 100;
+
+    private static final String FILE_NAME_PREFIX = "nio-out-file-";
+    private static final int VERBOSE_PERIOD = 5 * 1000;
+
+    private static int iters = DEFAULT_ITERS;
+    private static int threadNum = DEFAULT_THREAD_NUM;
+
+    private static BufferPoolMXBean getDirectPool() {
+        final List<BufferPoolMXBean> pools =
+                  ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
+        for (BufferPoolMXBean pool : pools) {
+            if (pool.getName().equals("direct")) {
+                return pool;
+            }
+        }
+        throw new Error("could not find direct pool");
+    }
+    private static final BufferPoolMXBean directPool = getDirectPool();
+
+    // Each worker will do write operations on a file channel using
+    // buffers of various sizes. The buffer size is randomly chosen to
+    // be within a small or a large range. This way we can control
+    // which buffers can be cached (all, only the small ones, or none)
+    // by setting the jdk.nio.maxCachedBufferSize property.
+    private static class Worker implements Runnable {
+        private final int id;
+        private final Random random = new Random();
+        private long smallBufferCount = 0;
+        private long largeBufferCount = 0;
+
+        private int getWriteSize() {
+            int minSize = 0;
+            int diff = 0;
+            if (random.nextInt() % LARGE_BUFFER_FREQUENCY != 0) {
+                // small buffer
+                minSize = SMALL_BUFFER_MIN_SIZE;
+                diff = SMALL_BUFFER_DIFF_SIZE;
+                smallBufferCount += 1;
+            } else {
+                // large buffer
+                minSize = LARGE_BUFFER_MIN_SIZE;
+                diff = LARGE_BUFFER_DIFF_SIZE;
+                largeBufferCount += 1;
+            }
+            return minSize + random.nextInt(diff);
+        }
+
+        private void loop() {
+            final String fileName = String.format("%s%d", FILE_NAME_PREFIX, id);
+
+            try {
+                for (int i = 0; i < iters; i += 1) {
+                    final int writeSize = getWriteSize();
+
+                    // This will allocate a HeapByteBuffer. It should not
+                    // be a direct buffer, otherwise the write() method on
+                    // the channel below will not create a temporary
+                    // direct buffer for the write.
+                    final ByteBuffer buffer = ByteBuffer.allocate(writeSize);
+
+                    // Put some random data on it.
+                    while (buffer.hasRemaining()) {
+                        buffer.put((byte) random.nextInt());
+                    }
+                    buffer.rewind();
+
+                    final Path file = Paths.get(fileName);
+                    try (FileChannel outChannel = FileChannel.open(file, CREATE, TRUNCATE_EXISTING, WRITE)) {
+                        // The write() method will create a temporary
+                        // direct buffer for the write and attempt to cache
+                        // it. It's important that buffer is not a
+                        // direct buffer, otherwise the temporary buffer
+                        // will not be created.
+                        long res = outChannel.write(buffer);
+                    }
+
+                    if ((i + 1) % VERBOSE_PERIOD == 0) {
+                        System.out.printf(
+                          " Worker %3d | %8d Iters | Small %8d Large %8d | Direct %4d / %7dK\n",
+                          id, i + 1, smallBufferCount, largeBufferCount,
+                          directPool.getCount(), directPool.getTotalCapacity() / 1024);
+                    }
+                }
+            } catch (IOException e) {
+                throw new Error("I/O error", e);
+            }
+        }
+
+        @Override
+        public void run() {
+            loop();
+        }
+
+        public Worker(int id) {
+            this.id = id;
+        }
+    }
+
+    public static void checkDirectBuffers(long expectedCount, long expectedMax) {
+        final long directCount = directPool.getCount();
+        final long directTotalCapacity = directPool.getTotalCapacity();
+        System.out.printf("Direct %d / %dK\n",
+                          directCount, directTotalCapacity / 1024);
+
+        // Note that directCount could be < expectedCount. This can
+        // happen if a GC occurs after one of the worker threads exits
+        // since its thread-local DirectByteBuffer could be cleaned up
+        // before we reach here.
+        if (directCount > expectedCount) {
+            throw new Error(String.format(
+                "inconsistent direct buffer total count, expected = %d, found = %d",
+                expectedCount, directCount));
+        }
+
+        if (directTotalCapacity > expectedMax) {
+            throw new Error(String.format(
+                "inconsistent direct buffer total capacity, expectex max = %d, found = %d",
+                expectedMax, directTotalCapacity));
+        }
+    }
+
+    public static void main(String[] args) {
+        final String maxBufferSizeStr = System.getProperty("jdk.nio.maxCachedBufferSize");
+        final long maxBufferSize =
+            (maxBufferSizeStr != null) ? Long.valueOf(maxBufferSizeStr) : Long.MAX_VALUE;
+
+        // We assume that the max cannot be equal to a size of a
+        // buffer that can be allocated (makes sanity checking at the
+        // end easier).
+        if ((SMALL_BUFFER_MIN_SIZE <= maxBufferSize &&
+                                     maxBufferSize <= SMALL_BUFFER_MAX_SIZE) ||
+            (LARGE_BUFFER_MIN_SIZE <= maxBufferSize &&
+                                     maxBufferSize <= LARGE_BUFFER_MAX_SIZE)) {
+            throw new Error(String.format("max buffer size = %d not allowed",
+                                          maxBufferSize));
+        }
+
+        System.out.printf("Threads %d | Iterations %d | MaxBufferSize %d\n",
+                          threadNum, iters, maxBufferSize);
+        System.out.println();
+
+        final Thread[] threads = new Thread[threadNum];
+        for (int i = 0; i < threadNum; i += 1) {
+            threads[i] = new Thread(new Worker(i));
+            threads[i].start();
+        }
+
+        try {
+            for (int i = 0; i < threadNum; i += 1) {
+                threads[i].join();
+            }
+        } catch (InterruptedException e) {
+            throw new Error("join() interrupted!", e);
+        }
+
+        // There is an assumption here that, at this point, only the
+        // cached DirectByteBuffers should be active. Given we
+        // haven't used any other DirectByteBuffers in this test, this
+        // should hold.
+        //
+        // Also note that we can only do the sanity checking at the
+        // end and not during the run given that, at any time, there
+        // could be buffers currently in use by some of the workers
+        // that will not be cached.
+
+        System.out.println();
+        if (maxBufferSize < SMALL_BUFFER_MAX_SIZE) {
+            // The max buffer size is smaller than all buffers that
+            // were allocated. No buffers should have been cached.
+            checkDirectBuffers(0, 0);
+        } else if (maxBufferSize < LARGE_BUFFER_MIN_SIZE) {
+            // The max buffer size is larger than all small buffers
+            // but smaller than all large buffers that were
+            // allocated. Only small buffers could have been cached.
+            checkDirectBuffers(threadNum,
+                               (long) threadNum * (long) SMALL_BUFFER_MAX_SIZE);
+        } else {
+            // The max buffer size is larger than all buffers that
+            // were allocated. All buffers could have been cached.
+            checkDirectBuffers(threadNum,
+                               (long) threadNum * (long) LARGE_BUFFER_MAX_SIZE);
+        }
+    }
+}
--- a/jdk/test/sun/security/pkcs11/Cipher/ReinitCipher.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Cipher/ReinitCipher.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,21 +28,22 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm ReinitCipher
+ * @run main/othervm ReinitCipher sm
  */
 
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
+import java.security.Provider;
+import java.util.Random;
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
 
 public class ReinitCipher extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new ReinitCipher());
+        main(new ReinitCipher(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("Cipher", "ARCFOUR") == null) {
             System.out.println("Not supported by provider, skipping");
--- a/jdk/test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -27,16 +27,18 @@
  * @summary Test internal PKCS5Padding impl with various error conditions.
  * @author Valerie Peng
  * @library ..
+ * @run main/othervm TestPKCS5PaddingError
+ * @run main/othervm TestPKCS5PaddingError sm
  */
-import java.io.*;
-import java.nio.*;
-import java.util.*;
 
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.*;
-import javax.crypto.spec.IvParameterSpec;
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
 
 public class TestPKCS5PaddingError extends PKCS11Test {
     private static class CI { // class for holding Cipher Information
@@ -62,10 +64,8 @@
 
     private static StringBuffer debugBuf = new StringBuffer();
 
+    @Override
     public void main(Provider p) throws Exception {
-        boolean status = true;
-        Random random = new Random();
-
         try {
             byte[] plainText = new byte[200];
 
@@ -127,6 +127,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestPKCS5PaddingError());
+        main(new TestPKCS5PaddingError(), args);
     }
 }
--- a/jdk/test/sun/security/pkcs11/Cipher/TestRSACipher.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestRSACipher.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,20 +28,28 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm TestRSACipher
+ * @run main/othervm TestRSACipher sm
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Random;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
 
 public class TestRSACipher extends PKCS11Test {
 
     private static final String[] RSA_ALGOS =
         { "RSA/ECB/PKCS1Padding", "RSA" };
 
+    @Override
     public void main(Provider p) throws Exception {
         try {
             Cipher.getInstance(RSA_ALGOS[0], p);
@@ -122,7 +130,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestRSACipher());
+        main(new TestRSACipher(), args);
     }
 
 }
--- a/jdk/test/sun/security/pkcs11/Cipher/TestRSACipherWrap.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestRSACipherWrap.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -27,13 +27,20 @@
  * @summary basic test for RSA cipher key wrapping functionality
  * @author Valerie Peng
  * @library ..
+ * @run main/othervm TestRSACipherWrap
+ * @run main/othervm TestRSACipherWrap sm
  */
-import java.io.*;
-import java.util.*;
 
-import java.security.*;
-
-import javax.crypto.*;
+import java.security.GeneralSecurityException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
+import java.util.Arrays;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
 
 public class TestRSACipherWrap extends PKCS11Test {
@@ -41,6 +48,7 @@
     private static final String[] RSA_ALGOS =
         { "RSA/ECB/PKCS1Padding", "RSA" };
 
+    @Override
     public void main(Provider p) throws Exception {
         try {
             Cipher.getInstance(RSA_ALGOS[0], p);
@@ -104,6 +112,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestRSACipherWrap());
+        main(new TestRSACipherWrap(), args);
     }
 }
--- a/jdk/test/sun/security/pkcs11/Cipher/TestRawRSACipher.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestRawRSACipher.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -28,16 +28,21 @@
  * @author Valerie Peng
  * @library ..
  * @key randomness
+ * @run main/othervm TestRawRSACipher
+ * @run main/othervm TestRawRSACipher sm
  */
 
-import javax.crypto.*;
-import java.io.*;
-import javax.crypto.spec.SecretKeySpec;
-import java.security.*;
-import java.util.*;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
+import java.util.Arrays;
+import java.util.Random;
+import javax.crypto.Cipher;
 
 public class TestRawRSACipher extends PKCS11Test {
 
+    @Override
     public void main(Provider p) throws Exception {
         try {
             Cipher.getInstance("RSA/ECB/NoPadding", p);
@@ -80,6 +85,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestRawRSACipher());
+        main(new TestRawRSACipher(), args);
     }
 }
--- a/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -28,16 +28,19 @@
  * @author Valerie Peng
  * @library ..
  * @key randomness
+ * @run main/othervm TestSymmCiphers
+ * @run main/othervm TestSymmCiphers sm
  */
-import java.io.*;
-import java.nio.*;
-import java.util.*;
 
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.*;
-import javax.crypto.spec.IvParameterSpec;
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.util.Random;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
 
 public class TestSymmCiphers extends PKCS11Test {
 
@@ -81,6 +84,7 @@
     };
     private static StringBuffer debugBuf = new StringBuffer();
 
+    @Override
     public void main(Provider p) throws Exception {
         // NSS reports CKR_DEVICE_ERROR when the data passed to
         // its EncryptUpdate/DecryptUpdate is not multiple of blocks
@@ -272,6 +276,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestSymmCiphers());
+        main(new TestSymmCiphers(), args);
     }
 }
--- a/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, 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
@@ -28,17 +28,22 @@
  * @author Valerie Peng
  * @library ..
  * @key randomness
+ * @run main/othervm TestSymmCiphersNoPad
+ * @run main/othervm TestSymmCiphersNoPad sm
  */
 
-import java.io.*;
-import java.nio.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.*;
-import javax.crypto.spec.IvParameterSpec;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.util.Random;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
 
 public class TestSymmCiphersNoPad extends PKCS11Test {
 
@@ -67,6 +72,7 @@
 
     private static StringBuffer debugBuf;
 
+    @Override
     public void main(Provider p) throws Exception {
         boolean status = true;
         Random random = new Random();
@@ -234,6 +240,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestSymmCiphersNoPad());
+        main(new TestSymmCiphersNoPad(), args);
     }
 }
--- a/jdk/test/sun/security/pkcs11/KeyAgreement/TestDH.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/KeyAgreement/TestDH.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -27,17 +27,20 @@
  * @summary Verify that DH works properly
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm TestDH
+ * @run main/othervm TestDH sm
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
+import java.util.Arrays;
+import javax.crypto.KeyAgreement;
+import javax.crypto.SecretKey;
 
 public class TestDH extends PKCS11Test {
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("KeyAgreement", "DH") == null) {
             System.out.println("DH not supported, skipping");
@@ -91,8 +94,9 @@
         testAlgorithm(ka2, kp2, ka1, kp1, "TlsPremasterSecret");
     }
 
-    private static void testAlgorithm(KeyAgreement ka1, KeyPair kp1, KeyAgreement ka2, KeyPair kp2, String algorithm) throws Exception {
-        SecretKey key1 = null;
+    private static void testAlgorithm(KeyAgreement ka1, KeyPair kp1,
+            KeyAgreement ka2, KeyPair kp2, String algorithm) throws Exception {
+        SecretKey key1;
 
         ka1.init(kp1.getPrivate());
         ka1.doPhase(kp2.getPublic(), true);
@@ -115,7 +119,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestDH());
+        main(new TestDH(), args);
     }
 
 }
--- a/jdk/test/sun/security/pkcs11/KeyAgreement/TestInterop.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/KeyAgreement/TestInterop.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -26,14 +26,18 @@
  * @bug 7146728
  * @summary Interop test for DH with secret that has a leading 0x00 byte
  * @library ..
+ * @run main/othervm TestInterop
+ * @run main/othervm TestInterop sm
  */
 import java.math.BigInteger;
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.util.Arrays;
+import javax.crypto.KeyAgreement;
+import javax.crypto.spec.DHPrivateKeySpec;
+import javax.crypto.spec.DHPublicKeySpec;
 
 public class TestInterop extends PKCS11Test {
 
@@ -72,6 +76,7 @@
     + "30313414180008978013330410484011186019824874948204261839391153650949864"
     + "429505597086564709");
 
+    @Override
     public void main(Provider prov) throws Exception {
         if (prov.getService("KeyAgreement", "DH") == null) {
             System.out.println("DH not supported, skipping");
@@ -138,6 +143,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestInterop());
+        main(new TestInterop(), args);
     }
 }
--- a/jdk/test/sun/security/pkcs11/KeyAgreement/TestShort.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/KeyAgreement/TestShort.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -27,15 +27,19 @@
  * @summary KAT test for DH (normal and with secret that has leading a 0x00 byte)
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm TestShort
+ * @run main/othervm TestShort sm
  */
 
 import java.math.BigInteger;
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.util.Arrays;
+import javax.crypto.KeyAgreement;
+import javax.crypto.spec.DHPrivateKeySpec;
+import javax.crypto.spec.DHPublicKeySpec;
 
 public class TestShort extends PKCS11Test {
 
@@ -83,6 +87,7 @@
     + "1a:6a:15:d8:a4:8c:0a:ce:f0:15:03:0c:c2:56:82:a2:75:9b:49:fe:ed:60:c5:6e"
     + ":de:47:55:62:4f:16:20:6d:74:cc:7b:95:93:25:2c:ea");
 
+    @Override
     public void main(Provider provider) throws Exception {
         if (provider.getService("KeyAgreement", "DH") == null) {
             System.out.println("DH not supported, skipping");
@@ -142,7 +147,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestShort());
+        main(new TestShort(), args);
     }
 
 }
--- a/jdk/test/sun/security/pkcs11/KeyGenerator/DESParity.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/KeyGenerator/DESParity.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,19 +28,21 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm DESParity
+ * @run main/othervm DESParity sm
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.spec.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
+import java.security.Provider;
+import java.util.Random;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.SecretKeySpec;
 
 public class DESParity extends PKCS11Test {
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("SecretKeyFactory", "DES") == null) {
             System.out.println("Not supported by provider, skipping");
@@ -73,7 +75,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new DESParity());
+        main(new DESParity(), args);
     }
 
 }
--- a/jdk/test/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -27,13 +27,16 @@
  * @summary test the KeyGenerator
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm TestKeyGenerator
+ * @run main/othervm TestKeyGenerator sm
  */
 
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
+import java.security.InvalidParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.ProviderException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
 
 enum TestResult {
     PASS,
@@ -44,7 +47,7 @@
 public class TestKeyGenerator extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new TestKeyGenerator());
+        main(new TestKeyGenerator(), args);
     }
 
     private TestResult test(String algorithm, int keyLen, Provider p,
@@ -85,6 +88,7 @@
         return actual;
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         test("DES", 0, p, TestResult.FAIL);
         test("DES", 56, p, TestResult.PASS); // ensure JCE-Compatibility
--- a/jdk/test/sun/security/pkcs11/KeyPairGenerator/TestDH2048.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/KeyPairGenerator/TestDH2048.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -27,14 +27,14 @@
  * @summary Ensure that 2048-bit DH key pairs can be generated
  * @author Valerie Peng
  * @library ..
+ * @run main/othervm TestDH2048
+ * @run main/othervm TestDH2048 sm
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
 
 public class TestDH2048 extends PKCS11Test {
 
@@ -47,6 +47,7 @@
         }
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("KeyPairGenerator", "DH") == null) {
             System.out.println("KPG for DH not supported, skipping");
@@ -61,6 +62,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestDH2048());
+        main(new TestDH2048(), args);
     }
 }
--- a/jdk/test/sun/security/pkcs11/Mac/MacKAT.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Mac/MacKAT.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -36,7 +36,8 @@
  * @summary Basic known-answer-test for Hmac algorithms
  * @author Andreas Sterbenz
  * @library ..
- * @run main MacKAT
+ * @run main/othervm MacKAT
+ * @run main/othervm MacKAT sm
  */
 public class MacKAT extends PKCS11Test {
 
@@ -178,7 +179,7 @@
     };
 
     public static void main(String[] args) throws Exception {
-        main(new MacKAT());
+        main(new MacKAT(), args);
     }
 
     @Override
--- a/jdk/test/sun/security/pkcs11/Mac/MacSameTest.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Mac/MacSameTest.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -36,7 +36,8 @@
  * @summary Check if doFinal and update operation result in same Mac
  * @author Yu-Ching Valerie Peng, Bill Situ, Alexander Fomin
  * @library ..
- * @run main MacSameTest
+ * @run main/othervm MacSameTest
+ * @run main/othervm MacSameTest sm
  * @key randomness
  */
 public class MacSameTest extends PKCS11Test {
@@ -57,7 +58,7 @@
      * @param args the command line arguments
      */
     public static void main(String[] args) throws Exception {
-        main(new MacSameTest());
+        main(new MacSameTest(), args);
     }
 
     @Override
--- a/jdk/test/sun/security/pkcs11/Mac/ReinitMac.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Mac/ReinitMac.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,21 +28,22 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm ReinitMac
+ * @run main/othervm ReinitMac sm
  */
 
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
+import java.security.Provider;
+import java.util.Random;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
 
 public class ReinitMac extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new ReinitMac());
+        main(new ReinitMac(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("Mac", "HmacMD5") == null) {
             System.out.println(p + " does not support HmacMD5, skipping");
--- a/jdk/test/sun/security/pkcs11/MessageDigest/ByteBuffers.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/MessageDigest/ByteBuffers.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,19 +28,23 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm ByteBuffers
+ * @run main/othervm ByteBuffers sm
  */
 
-import java.util.*;
-import java.nio.*;
-
-import java.security.*;
+import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.security.Provider;
+import java.util.Arrays;
+import java.util.Random;
 
 public class ByteBuffers extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new ByteBuffers());
+        main(new ByteBuffers(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("MessageDigest", "MD5") == null) {
             System.out.println("Provider does not support MD5, skipping");
--- a/jdk/test/sun/security/pkcs11/MessageDigest/DigestKAT.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/MessageDigest/DigestKAT.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -27,19 +27,23 @@
  * @summary Basic known-answer-test for all our MessageDigest algorithms
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm DigestKAT
+ * @run main/othervm DigestKAT sm
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.security.MessageDigest;
+import java.security.Provider;
+import java.util.Arrays;
 
 public class DigestKAT extends PKCS11Test {
 
     private final static char[] hexDigits = "0123456789abcdef".toCharArray();
 
     public static String toString(byte[] b) {
-        StringBuffer sb = new StringBuffer(b.length * 3);
+        StringBuilder sb = new StringBuilder(b.length * 3);
         for (int i = 0; i < b.length; i++) {
             int k = b[i] & 0xff;
             if (i != 0) {
@@ -106,6 +110,7 @@
             this.data = data;
             this.digest = digest;
         }
+        @Override
         void run(Provider p) throws Exception {
             if (p.getService("MessageDigest", alg) == null) {
                 System.out.println("Skipped " + alg);
@@ -123,7 +128,6 @@
                 System.out.println("out:  " + DigestKAT.toString(myDigest));
                 throw new Exception("Digest test for " + alg + " failed");
             }
-//          System.out.println("Passed " + alg);
         }
     }
 
@@ -221,12 +225,13 @@
         System.out.println("Done (" + (stop - start) + " ms).");
     }
 
+    @Override
     public void main(Provider p) throws Exception{
         runTests(tests, p);
     }
 
     public static void main(String[] args) throws Exception {
-        main(new DigestKAT());
+        main(new DigestKAT(), args);
     }
 
 }
--- a/jdk/test/sun/security/pkcs11/MessageDigest/ReinitDigest.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/MessageDigest/ReinitDigest.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,18 +28,22 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm ReinitDigest
+ * @run main/othervm ReinitDigest sm
  */
 
-import java.util.*;
-
-import java.security.*;
+import java.security.MessageDigest;
+import java.security.Provider;
+import java.util.Arrays;
+import java.util.Random;
 
 public class ReinitDigest extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new ReinitDigest());
+        main(new ReinitDigest(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("MessageDigest", "MD5") == null) {
             System.out.println("Provider does not support MD5, skipping");
--- a/jdk/test/sun/security/pkcs11/MessageDigest/TestCloning.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/MessageDigest/TestCloning.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -28,11 +28,14 @@
  * @author Valerie Peng
  * @library ..
  * @key randomness
+ * @run main/othervm TestCloning
+ * @run main/othervm TestCloning sm
  */
 
-import java.util.*;
-
-import java.security.*;
+import java.security.MessageDigest;
+import java.security.Provider;
+import java.util.Arrays;
+import java.util.Random;
 
 public class TestCloning extends PKCS11Test {
 
@@ -41,13 +44,14 @@
     };
 
     public static void main(String[] args) throws Exception {
-        main(new TestCloning());
+        main(new TestCloning(), args);
     }
 
     private static final byte[] data1 = new byte[10];
     private static final byte[] data2 = new byte[10*1024];
 
 
+    @Override
     public void main(Provider p) throws Exception {
         Random r = new Random();
         byte[] data1 = new byte[10];
--- a/jdk/test/sun/security/pkcs11/PKCS11Test.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -24,15 +24,38 @@
 
 // common infrastructure for SunPKCS11 tests
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.ProviderException;
+import java.security.Security;
 import java.security.spec.ECGenParameterSpec;
 import java.security.spec.ECParameterSpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ServiceLoader;
+import java.util.Set;
 
 public abstract class PKCS11Test {
 
+    private boolean enableSM = false;
+
+    static final Properties props = System.getProperties();
+
     static final String PKCS11 = "PKCS11";
 
     // directory of the test source
@@ -40,7 +63,8 @@
 
     static final char SEP = File.separatorChar;
 
-    private final static String REL_CLOSED = "../../../../closed/sun/security/pkcs11".replace('/', SEP);
+    private static final String DEFAULT_POLICY =
+            BASE + SEP + ".." + SEP + "policy";
 
     // directory corresponding to BASE in the /closed hierarchy
     static final String CLOSED_BASE;
@@ -53,6 +77,9 @@
         String p1 = absBase.substring(0, k + 6);
         String p2 = absBase.substring(k + 5);
         CLOSED_BASE = p1 + "closed" + p2;
+
+        // set it as a system property to make it available in policy file
+        System.setProperty("closed.base", CLOSED_BASE);
     }
 
     static String NSPR_PREFIX = "";
@@ -86,7 +113,7 @@
                 if (p.getName().equals("SunPKCS11")) {
                     found = true;
                     break;
-                };
+                }
             } catch (Exception e) {
                 // ignore and move on to the next one
             }
@@ -103,6 +130,19 @@
         pkcs11 = p;
     }
 
+    /*
+     * Use Solaris SPARC 11.2 or later to avoid an intermittent failure
+     * when running SunPKCS11-Solaris (8044554)
+     */
+    static boolean isBadSolarisSparc(Provider p) {
+        if ("SunPKCS11-Solaris".equals(p.getName()) && badSolarisSparc) {
+            System.out.println("SunPKCS11-Solaris provider requires " +
+                "Solaris SPARC 11.2 or later, skipping");
+            return true;
+        }
+        return false;
+    }
+
     // Return a SunPKCS11 provider configured with the specified config file
     static Provider getSunPKCS11(String config) throws Exception {
         if (pkcs11 == null) {
@@ -114,15 +154,43 @@
     public abstract void main(Provider p) throws Exception;
 
     private void premain(Provider p) throws Exception {
-        long start = System.currentTimeMillis();
-        System.out.println("Running test with provider " + p.getName() + "...");
-        main(p);
-        long stop = System.currentTimeMillis();
-        System.out.println("Completed test with provider " + p.getName() +
-            " (" + (stop - start) + " ms).");
+        // set a security manager and policy before a test case runs,
+        // and disable them after the test case finished
+        try {
+            if (enableSM) {
+                System.setSecurityManager(new SecurityManager());
+            }
+            long start = System.currentTimeMillis();
+            System.out.printf(
+                    "Running test with provider %s (security manager %s) ...%n",
+                        p.getName(), enableSM ? "enabled" : "disabled");
+            main(p);
+            long stop = System.currentTimeMillis();
+            System.out.println("Completed test with provider " + p.getName() +
+                " (" + (stop - start) + " ms).");
+        } finally {
+            if (enableSM) {
+                System.setSecurityManager(null);
+            }
+        }
     }
 
     public static void main(PKCS11Test test) throws Exception {
+        main(test, null);
+    }
+
+    public static void main(PKCS11Test test, String[] args) throws Exception {
+        if (args != null) {
+            if (args.length > 0 && "sm".equals(args[0])) {
+                test.enableSM = true;
+            }
+            if (test.enableSM) {
+                System.setProperty("java.security.policy",
+                        (args.length > 1) ? BASE + SEP + args[1]
+                                : DEFAULT_POLICY);
+            }
+        }
+
         Provider[] oldProviders = Security.getProviders();
         try {
             System.out.println("Beginning test run " + test.getClass().getName() + "...");
@@ -218,7 +286,6 @@
     }
 
     static String getNSSLibDir(String library) throws Exception {
-        Properties props = System.getProperties();
         String osName = props.getProperty("os.name");
         if (osName.startsWith("Win")) {
             osName = "Windows";
@@ -249,6 +316,15 @@
         return nssLibDir;
     }
 
+    static boolean isBadNSSVersion(Provider p) {
+        if (isNSS(p) && badNSSVersion) {
+            System.out.println("NSS 3.11 has a DER issue that recent " +
+                    "version do not.");
+            return true;
+        }
+        return false;
+    }
+
     protected static void safeReload(String lib) throws Exception {
         try {
             System.load(lib);
@@ -317,34 +393,32 @@
 
         try {
             libfile = getNSSLibDir() + System.mapLibraryName(library);
-            FileInputStream is = new FileInputStream(libfile);
-            byte[] data = new byte[1000];
-            int read = 0;
+            try (FileInputStream is = new FileInputStream(libfile)) {
+                byte[] data = new byte[1000];
+                int read = 0;
 
-            while (is.available() > 0) {
-                if (read == 0) {
-                    read = is.read(data, 0, 1000);
-                } else {
-                    // Prepend last 100 bytes in case the header was split
-                    // between the reads.
-                    System.arraycopy(data, 900, data, 0, 100);
-                    read = 100 + is.read(data, 100, 900);
-                }
+                while (is.available() > 0) {
+                    if (read == 0) {
+                        read = is.read(data, 0, 1000);
+                    } else {
+                        // Prepend last 100 bytes in case the header was split
+                        // between the reads.
+                        System.arraycopy(data, 900, data, 0, 100);
+                        read = 100 + is.read(data, 100, 900);
+                    }
 
-                s = new String(data, 0, read);
-                if ((i = s.indexOf(nssHeader)) > 0) {
-                    found = true;
-                    // If the nssHeader is before 920 we can break, otherwise
-                    // we may not have the whole header so do another read.  If
-                    // no bytes are in the stream, that is ok, found is true.
-                    if (i < 920) {
-                        break;
+                    s = new String(data, 0, read);
+                    if ((i = s.indexOf(nssHeader)) > 0) {
+                        found = true;
+                        // If the nssHeader is before 920 we can break, otherwise
+                        // we may not have the whole header so do another read.  If
+                        // no bytes are in the stream, that is ok, found is true.
+                        if (i < 920) {
+                            break;
+                        }
                     }
                 }
             }
-
-            is.close();
-
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -438,14 +512,13 @@
     }
 
     // Generate a vector of supported elliptic curves of a given provider
-    static Vector<ECParameterSpec> getKnownCurves(Provider p) throws Exception {
+    static List<ECParameterSpec> getKnownCurves(Provider p) throws Exception {
         int index;
         int begin;
         int end;
         String curve;
-        KeyPair kp = null;
 
-        Vector<ECParameterSpec> results = new Vector<ECParameterSpec>();
+        List<ECParameterSpec> results = new ArrayList<>();
         // Get Curves to test from SunEC.
         String kcProp = Security.getProvider("SunEC").
                 getProperty("AlgorithmParameters.EC SupportedCurves");
@@ -483,7 +556,7 @@
             try {
                 KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", p);
                 kpg.initialize(e);
-                kp = kpg.generateKeyPair();
+                kpg.generateKeyPair();
                 results.add(e);
                 System.out.println("Supported");
             } catch (ProviderException ex) {
@@ -514,9 +587,8 @@
     }
 
     // Check support for a curve with a provided Vector of EC support
-    boolean checkSupport(Vector<ECParameterSpec> supportedEC,
+    boolean checkSupport(List<ECParameterSpec> supportedEC,
             ECParameterSpec curve) {
-        boolean found = false;
         for (ECParameterSpec ec: supportedEC) {
             if (ec.equals(curve)) {
                 return true;
@@ -529,7 +601,7 @@
 
     // Location of the NSS libraries on each supported platform
     static {
-        osMap = new HashMap<String,String[]>();
+        osMap = new HashMap<>();
         osMap.put("SunOS-sparc-32", new String[]{"/usr/lib/mps/"});
         osMap.put("SunOS-sparcv9-64", new String[]{"/usr/lib/mps/64/"});
         osMap.put("SunOS-x86-32", new String[]{"/usr/lib/mps/"});
@@ -551,11 +623,20 @@
 
     private final static char[] hexDigits = "0123456789abcdef".toCharArray();
 
+    static final boolean badNSSVersion =
+            getNSSVersion() >= 3.11 && getNSSVersion() < 3.12;
+
+    static final boolean badSolarisSparc =
+            System.getProperty("os.name").equals("SunOS") &&
+            System.getProperty("os.arch").equals("sparcv9") &&
+            System.getProperty("os.version").compareTo("5.11") <= 0 &&
+            getDistro().compareTo("11.2") < 0;
+
     public static String toString(byte[] b) {
         if (b == null) {
             return "(null)";
         }
-        StringBuffer sb = new StringBuffer(b.length * 3);
+        StringBuilder sb = new StringBuilder(b.length * 3);
         for (int i = 0; i < b.length; i++) {
             int k = b[i] & 0xff;
             if (i != 0) {
@@ -637,8 +718,7 @@
     /**
      * Get the identifier for the operating system distribution
      */
-    public String getDistro() {
-
+    static String getDistro() {
         try (BufferedReader in =
             new BufferedReader(new InputStreamReader(
                 Runtime.getRuntime().exec("uname -v").getInputStream()))) {
--- a/jdk/test/sun/security/pkcs11/Secmod/AddPrivateKey.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Secmod/AddPrivateKey.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -28,14 +28,26 @@
  * @author Andreas Sterbenz
  * @library ..
  * @run main/othervm AddPrivateKey
+ * @run main/othervm AddPrivateKey sm policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.KeyStore.*;
-import java.security.cert.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.KeyStore.PasswordProtection;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStoreException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.Signature;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 // this test is currently only run for the NSS KeyStore provider, but it
 // is really a generic KeyStore test so it should be modified to run for
@@ -63,6 +75,12 @@
         System.out.println();
         Security.addProvider(p);
 
+        if (args.length > 1 && "sm".equals(args[0])) {
+            System.setProperty("java.security.policy",
+                    BASE + File.separator + args[1]);
+            System.setSecurityManager(new SecurityManager());
+        }
+
         KeyStore ks = KeyStore.getInstance(PKCS11, p);
         ks.load(null, password);
         for (String alias : aliases(ks)) {
--- a/jdk/test/sun/security/pkcs11/Secmod/AddTrustedCert.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Secmod/AddTrustedCert.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -28,14 +28,21 @@
  * @author Andreas Sterbenz
  * @library ..
  * @run main/othervm AddTrustedCert
+ * @run main/othervm AddTrustedCert sm policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.KeyStore.*;
-import java.security.cert.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.KeyStore.TrustedCertificateEntry;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.TreeSet;
 
 public class AddTrustedCert extends SecmodTest {
 
@@ -56,6 +63,13 @@
 
         System.out.println(p);
         Security.addProvider(p);
+
+        if (args.length > 1 && "sm".equals(args[0])) {
+            System.setProperty("java.security.policy",
+                    BASE + File.separator + args[1]);
+            System.setSecurityManager(new SecurityManager());
+        }
+
         KeyStore ks = KeyStore.getInstance(PKCS11, p);
         ks.load(null, password);
         Collection<String> aliases = new TreeSet<>(Collections.list(
--- a/jdk/test/sun/security/pkcs11/Secmod/Crypto.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Secmod/Crypto.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -28,9 +28,14 @@
  * @author Andreas Sterbenz
  * @library ..
  * @run main/othervm Crypto
+ * @run main/othervm Crypto sm policy
  */
 
-import java.security.*;
+import java.io.File;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
+import java.security.Signature;
 
 public class Crypto extends SecmodTest {
 
@@ -42,6 +47,12 @@
         String configName = BASE + SEP + "nsscrypto.cfg";
         Provider p = getSunPKCS11(configName);
 
+        if (args.length > 1 && "sm".equals(args[0])) {
+            System.setProperty("java.security.policy",
+                    BASE + File.separator + args[1]);
+            System.setSecurityManager(new SecurityManager());
+        }
+
         KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", p);
         KeyPair kp = kpg.generateKeyPair();
 
--- a/jdk/test/sun/security/pkcs11/Secmod/GetPrivateKey.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Secmod/GetPrivateKey.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -29,13 +29,19 @@
  * @author Andreas Sterbenz
  * @library ..
  * @run main/othervm GetPrivateKey
+ * @run main/othervm GetPrivateKey sm policy
  */
 
-import java.util.*;
-
-import java.security.*;
-import java.security.KeyStore.*;
-import java.security.cert.*;
+import java.io.File;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Security;
+import java.security.Signature;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.TreeSet;
 
 public class GetPrivateKey extends SecmodTest {
 
@@ -49,6 +55,13 @@
 
         System.out.println(p);
         Security.addProvider(p);
+
+        if (args.length > 1 && "sm".equals(args[0])) {
+            System.setProperty("java.security.policy",
+                    BASE + File.separator + args[1]);
+            System.setSecurityManager(new SecurityManager());
+        }
+
         KeyStore ks = KeyStore.getInstance(PKCS11, p);
         ks.load(null, password);
         Collection<String> aliases = new TreeSet<>(
--- a/jdk/test/sun/security/pkcs11/Secmod/JksSetPrivateKey.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Secmod/JksSetPrivateKey.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -28,13 +28,19 @@
  * @author Wang Weijun
  * @library ..
  * @run main/othervm JksSetPrivateKey
+ * @run main/othervm JksSetPrivateKey sm policy
  */
 
-import java.util.*;
-
-import java.security.*;
-import java.security.KeyStore.*;
-import java.security.cert.*;
+import java.io.File;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.TreeSet;
 
 public class JksSetPrivateKey extends SecmodTest {
 
@@ -48,9 +54,16 @@
 
         System.out.println(p);
         Security.addProvider(p);
+
+        if (args.length > 1 && "sm".equals(args[0])) {
+            System.setProperty("java.security.policy",
+                    BASE + File.separator + args[1]);
+            System.setSecurityManager(new SecurityManager());
+        }
+
         KeyStore ks = KeyStore.getInstance("PKCS11", p);
         ks.load(null, password);
-        Collection<String> aliases = new TreeSet<String>(Collections.list(ks.aliases()));
+        Collection<String> aliases = new TreeSet<>(Collections.list(ks.aliases()));
         System.out.println("entries: " + aliases.size());
         System.out.println(aliases);
 
@@ -66,14 +79,14 @@
             jks.setKeyEntry("k1", privateKey, "changeit".toCharArray(), chain);
             throw new Exception("No, an NSS PrivateKey shouldn't be extractable and put inside a JKS keystore");
         } catch (KeyStoreException e) {
-            System.err.println(e);; // This is OK
+            System.err.println(e); // This is OK
         }
 
         try {
             jks.setKeyEntry("k2", new DummyPrivateKey(), "changeit".toCharArray(), chain);
             throw new Exception("No, non-PKCS#8 key shouldn't be put inside a KeyStore");
         } catch (KeyStoreException e) {
-            System.err.println(e);; // This is OK
+            System.err.println(e); // This is OK
         }
         System.out.println("OK");
 
@@ -81,35 +94,41 @@
             jks.setKeyEntry("k3", new DummyPrivateKey2(), "changeit".toCharArray(), chain);
             throw new Exception("No, not-extractble key shouldn't be put inside a KeyStore");
         } catch (KeyStoreException e) {
-            System.err.println(e);; // This is OK
+            System.err.println(e); // This is OK
         }
         System.out.println("OK");
     }
 }
 
 class DummyPrivateKey implements PrivateKey {
+    @Override
     public String getAlgorithm() {
         return "DUMMY";
     }
 
+    @Override
     public String getFormat() {
         return "DUMMY";
     }
 
+    @Override
     public byte[] getEncoded() {
         return "DUMMY".getBytes();
     }
 }
 
 class DummyPrivateKey2 implements PrivateKey {
+    @Override
     public String getAlgorithm() {
         return "DUMMY";
     }
 
+    @Override
     public String getFormat() {
         return "PKCS#8";
     }
 
+    @Override
     public byte[] getEncoded() {
         return null;
     }
--- a/jdk/test/sun/security/pkcs11/Secmod/LoadKeystore.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Secmod/LoadKeystore.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import java.io.File;
 import java.io.IOException;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
@@ -35,6 +36,7 @@
  * @summary Checks that PKCS#11 keystore can't be loaded with wrong password
  * @library ../
  * @run main/othervm LoadKeystore
+ * @run main/othervm LoadKeystore sm policy
  */
 public class LoadKeystore extends SecmodTest {
 
@@ -50,6 +52,12 @@
         System.out.println();
         Security.addProvider(p);
 
+        if (args.length > 1 && "sm".equals(args[0])) {
+            System.setProperty("java.security.policy",
+                    BASE + File.separator + args[1]);
+            System.setSecurityManager(new SecurityManager());
+        }
+
         try {
             System.out.println("Load keystore with wrong type");
             KeyStore.getInstance("unknown", p);
--- a/jdk/test/sun/security/pkcs11/Secmod/TrustAnchors.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Secmod/TrustAnchors.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -28,13 +28,17 @@
  * @author Andreas Sterbenz
  * @library ..
  * @run main/othervm TrustAnchors
+ * @run main/othervm TrustAnchors sm policy
  */
 
-import java.util.*;
-
-import java.security.*;
-import java.security.KeyStore.*;
-import java.security.cert.*;
+import java.io.File;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.TreeSet;
 
 public class TrustAnchors extends SecmodTest {
 
@@ -57,9 +61,16 @@
 
         System.out.println(p);
         Security.addProvider(p);
+
+        if (args.length > 1 && "sm".equals(args[0])) {
+            System.setProperty("java.security.policy",
+                    BASE + File.separator + args[1]);
+            System.setSecurityManager(new SecurityManager());
+        }
+
         KeyStore ks = KeyStore.getInstance("PKCS11", p);
         ks.load(null, null);
-        Collection<String> aliases = new TreeSet<String>(Collections.list(ks.aliases()));
+        Collection<String> aliases = new TreeSet<>(Collections.list(ks.aliases()));
         System.out.println("entries: " + aliases.size());
         System.out.println(aliases);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/Secmod/policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,6 @@
+grant {
+    permission java.security.SecurityPermission "authProvider.*";
+    permission java.io.FilePermission "${test.src}/-", "read";
+    permission java.io.FilePermission "${pkcs11test.nss.db}/-", "read";
+    permission java.io.FilePermission "${pkcs11test.nss.libdir}/-", "read";
+};
\ No newline at end of file
--- a/jdk/test/sun/security/pkcs11/SecureRandom/Basic.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/SecureRandom/Basic.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -28,17 +28,17 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm Basic
+ * @run main/othervm Basic sm
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.SecureRandom;
 
 public class Basic extends PKCS11Test {
 
+    @Override
     public void main(Provider p) throws Exception {
         SecureRandom random;
         try {
@@ -58,7 +58,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new Basic());
+        main(new Basic(), args);
     }
 
 }
--- a/jdk/test/sun/security/pkcs11/Signature/ByteBuffers.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Signature/ByteBuffers.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,19 +28,24 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm ByteBuffers
+ * @run main/othervm ByteBuffers sm
  */
 
-import java.util.*;
-import java.nio.*;
-
-import java.security.*;
+import java.nio.ByteBuffer;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
+import java.security.Signature;
+import java.util.Random;
 
 public class ByteBuffers extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new ByteBuffers());
+        main(new ByteBuffers(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
 
         /*
@@ -48,9 +53,9 @@
          * when running SunPKCS11-Solaris provider (8044554)
          */
         if (p.getName().equals("SunPKCS11-Solaris") &&
-            System.getProperty("os.name").equals("SunOS") &&
-            System.getProperty("os.arch").equals("sparcv9") &&
-            System.getProperty("os.version").compareTo("5.11") <= 0 &&
+            props.getProperty("os.name").equals("SunOS") &&
+            props.getProperty("os.arch").equals("sparcv9") &&
+            props.getProperty("os.version").compareTo("5.11") <= 0 &&
             getDistro().compareTo("11.2") < 0) {
 
             System.out.println("SunPKCS11-Solaris provider requires " +
--- a/jdk/test/sun/security/pkcs11/Signature/TestDSA.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Signature/TestDSA.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,14 +28,24 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm TestDSA
+ * @run main/othervm TestDSA sm
  */
 
-import java.io.*;
-import java.util.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
 import java.math.BigInteger;
-
-import java.security.*;
-import java.security.spec.*;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.DSAPublicKeySpec;
+import java.util.Random;
 
 public class TestDSA extends PKCS11Test {
 
@@ -102,9 +112,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestDSA());
+        main(new TestDSA(), args);
     }
 
+    @Override
     public void main(Provider provider) throws Exception {
         long start = System.currentTimeMillis();
 
@@ -115,9 +126,9 @@
          * when running SunPKCS11-Solaris (8044554)
          */
         if (provider.getName().equals("SunPKCS11-Solaris") &&
-            System.getProperty("os.name").equals("SunOS") &&
-            System.getProperty("os.arch").equals("sparcv9") &&
-            System.getProperty("os.version").compareTo("5.11") <= 0 &&
+            props.getProperty("os.name").equals("SunOS") &&
+            props.getProperty("os.arch").equals("sparcv9") &&
+            props.getProperty("os.version").compareTo("5.11") <= 0 &&
             getDistro().compareTo("11.2") < 0) {
 
             System.out.println("SunPKCS11-Solaris provider requires " +
--- a/jdk/test/sun/security/pkcs11/Signature/TestDSAKeyLength.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Signature/TestDSAKeyLength.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -20,6 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 /*
  * @test
  * @bug 7200306 8029158
@@ -27,19 +28,24 @@
  * with unsupported key sizes
  * @library ..
  * @key randomness
+ * @run main/othervm TestDSAKeyLength
+ * @run main/othervm TestDSAKeyLength sm
  */
 
-
-import java.security.*;
-import java.security.spec.*;
-import java.security.interfaces.*;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
 
 public class TestDSAKeyLength extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new TestDSAKeyLength());
+        main(new TestDSAKeyLength(), args);
     }
 
+    @Override
     public void main(Provider provider) throws Exception {
         if (isNSS(provider) && getNSSVersion() >= 3.14) {
             System.out.println("Skip testing NSS " + getNSSVersion());
@@ -51,9 +57,9 @@
          * when running SunPKCS11-Solaris (8044554)
          */
         if (provider.getName().equals("SunPKCS11-Solaris") &&
-            System.getProperty("os.name").equals("SunOS") &&
-            System.getProperty("os.arch").equals("sparcv9") &&
-            System.getProperty("os.version").compareTo("5.11") <= 0 &&
+            props.getProperty("os.name").equals("SunOS") &&
+            props.getProperty("os.arch").equals("sparcv9") &&
+            props.getProperty("os.version").compareTo("5.11") <= 0 &&
             getDistro().compareTo("11.2") < 0) {
 
             System.out.println("SunPKCS11-Solaris provider requires " +
--- a/jdk/test/sun/security/pkcs11/Signature/TestRSAKeyLength.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/Signature/TestRSAKeyLength.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -27,14 +27,26 @@
  * @summary Make sure initSign/initVerify() check RSA key lengths
  * @author Yu-Ching Valerie Peng
  * @library ..
+ * @run main/othervm TestRSAKeyLength
+ * @run main/othervm TestRSAKeyLength sm
  */
 
-import java.security.*;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignedObject;
 
 public class TestRSAKeyLength extends PKCS11Test {
+
     public static void main(String[] args) throws Exception {
-        main(new TestRSAKeyLength());
+        main(new TestRSAKeyLength(), args);
     }
+
+    @Override
     public void main(Provider p) throws Exception {
 
         /*
@@ -42,9 +54,9 @@
          * when running SunPKCS11-Solaris (8044554)
          */
         if (p.getName().equals("SunPKCS11-Solaris") &&
-            System.getProperty("os.name").equals("SunOS") &&
-            System.getProperty("os.arch").equals("sparcv9") &&
-            System.getProperty("os.version").compareTo("5.11") <= 0 &&
+            props.getProperty("os.name").equals("SunOS") &&
+            props.getProperty("os.arch").equals("sparcv9") &&
+            props.getProperty("os.version").compareTo("5.11") <= 0 &&
             getDistro().compareTo("11.2") < 0) {
 
             System.out.println("SunPKCS11-Solaris provider requires " +
--- a/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -29,16 +29,31 @@
  * @author Andreas Sterbenz
  * @library ..
  * @library ../../../../java/security/testlibrary
+ * @run main/othervm ReadCertificates
+ * @run main/othervm ReadCertificates sm policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.cert.*;
-import java.security.*;
-import java.security.interfaces.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPublicKey;
 import java.security.spec.ECParameterSpec;
-
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import javax.security.auth.x500.X500Principal;
 
 public class ReadCertificates extends PKCS11Test {
@@ -49,16 +64,18 @@
 
     private static Collection<X509Certificate> readCertificates(File file) throws Exception {
         System.out.println("Loading " + file.getName() + "...");
-        InputStream in = new FileInputStream(file);
-        Collection<X509Certificate> certs = (Collection<X509Certificate>)factory.generateCertificates(in);
-        in.close();
+        Collection<X509Certificate> certs;
+        try (InputStream in = new FileInputStream(file)) {
+            certs = (Collection<X509Certificate>)factory.generateCertificates(in);
+        }
         return certs;
     }
 
     public static void main(String[] args) throws Exception {
-        main(new ReadCertificates());
+        main(new ReadCertificates(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("Signature", "SHA1withECDSA") == null) {
             System.out.println("Provider does not support ECDSA, skipping...");
@@ -79,7 +96,7 @@
         } catch (CertificateException e) {
             // ignore
         }
-        Map<X500Principal,X509Certificate> certs = new LinkedHashMap<X500Principal,X509Certificate>();
+        Map<X500Principal,X509Certificate> certs = new LinkedHashMap<>();
 
         File dir = new File(BASE, "certs");
         File closedDir = new File(CLOSED_BASE, "certs");
@@ -103,7 +120,7 @@
         System.out.println("OK: " + certs.size() + " certificates.");
 
         // Get supported curves
-        Vector<ECParameterSpec> supportedEC = getKnownCurves(p);
+        List<ECParameterSpec> supportedEC = getKnownCurves(p);
 
         System.out.println("Test Certs:\n");
         for (X509Certificate cert : certs.values()) {
@@ -127,7 +144,8 @@
                System.out.println("Warning: " + e.getMessage() +
                    ". Trying another provider...");
                cert.verify(key);
-           } catch (Exception e) {
+           } catch (CertificateException | InvalidKeyException |
+                    NoSuchProviderException | SignatureException e) {
                System.out.println(e.getMessage());
                if (key instanceof ECPublicKey) {
                    System.out.println("Failed.\n\tCurve: " +
@@ -145,7 +163,7 @@
         // try some random invalid signatures to make sure we get the correct
         // error
         System.out.println("Checking incorrect signatures...");
-        List<X509Certificate> certList = new ArrayList<X509Certificate>(certs.values());
+        List<X509Certificate> certList = new ArrayList<>(certs.values());
         for (int i = 0; i < 20; i++) {
             X509Certificate cert, signer;
             do {
@@ -161,9 +179,7 @@
                 } else {
                     throw new Exception("Verified invalid signature");
                 }
-            } catch (SignatureException e) {
-                System.out.println("OK: " + e);
-            } catch (InvalidKeyException e) {
+            } catch (SignatureException | InvalidKeyException e) {
                 System.out.println("OK: " + e);
             }
         }
--- a/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -29,26 +29,41 @@
  * @library ..
  * @library ../../../../java/security/testlibrary
  * @key randomness
+ * @run main/othervm ReadPKCS12
+ * @run main/othervm ReadPKCS12 sm policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.interfaces.*;
-import java.security.cert.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
 import java.security.cert.Certificate;
-
-import javax.security.auth.x500.X500Principal;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
 
 public class ReadPKCS12 extends PKCS11Test {
 
     private final static boolean COPY = false;
 
     public static void main(String[] args) throws Exception {
-        main(new ReadPKCS12());
+        main(new ReadPKCS12(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("Signature", "SHA1withECDSA") == null) {
             System.out.println("Provider does not support ECDSA, skipping...");
@@ -71,29 +86,30 @@
         KeyStore ks2;
         if (COPY) {
             ks2 = KeyStore.getInstance("JKS");
-            InputStream in = new FileInputStream("keystore.old");
-            ks2.load(in, "passphrase".toCharArray());
-            in.close();
+            try (InputStream in = new FileInputStream("keystore.old")) {
+                ks2.load(in, "passphrase".toCharArray());
+            }
         }
 
         File dir = new File(BASE, "pkcs12");
         File closedDir = new File(CLOSED_BASE, "pkcs12");
 
-        Map<String,char[]> passwords = new HashMap<String,char[]>();
-        BufferedReader reader = new BufferedReader(new FileReader((new File(BASE, "p12passwords.txt"))));
-        while (true) {
-            String line = reader.readLine();
-            if (line == null) {
-                break;
+        Map<String,char[]> passwords = new HashMap<>();
+        try (BufferedReader reader = new BufferedReader(
+                new FileReader(new File(BASE, "p12passwords.txt")))) {
+            while (true) {
+                String line = reader.readLine();
+                if (line == null) {
+                    break;
+                }
+                line = line.trim();
+                if ((line.length() == 0) || line.startsWith("#")) {
+                    continue;
+                }
+                String[] s = line.split(" ");
+                passwords.put(s[0], s[1].toCharArray());
             }
-            line = line.trim();
-            if ((line.length() == 0) || line.startsWith("#")) {
-                continue;
-            }
-            String[] s = line.split(" ");
-            passwords.put(s[0], s[1].toCharArray());
         }
-        reader.close();
 
         for (File file : concat(dir.listFiles(), closedDir.listFiles())) {
             String name = file.getName();
@@ -108,10 +124,11 @@
                 password = passwords.get("*");
             }
 
-            InputStream in = new FileInputStream(file);
-            KeyStore ks = KeyStore.getInstance("PKCS12");
-            ks.load(in, password);
-            in.close();
+            KeyStore ks;
+            try (InputStream in = new FileInputStream(file)) {
+                ks = KeyStore.getInstance("PKCS12");
+                ks.load(in, password);
+            }
             List<String> aliases = Collections.list(ks.aliases());
             System.out.println("Aliases: " + aliases);
 
@@ -147,9 +164,9 @@
         }
 
         if (COPY) {
-            OutputStream out = new FileOutputStream("keystore.new");
-            ks2.store(out, "passphrase".toCharArray());
-            out.close();
+            try (OutputStream out = new FileOutputStream("keystore.new")) {
+                ks2.store(out, "passphrase".toCharArray());
+            }
         }
 
         System.out.println("OK");
--- a/jdk/test/sun/security/pkcs11/ec/TestCurves.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/TestCurves.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -29,53 +29,46 @@
  * @library ..
  * @modules jdk.crypto.pkcs11/sun.security.pkcs11.wrapper
  * @compile -XDignore.symbol.file TestCurves.java
- * @run main TestCurves
+ * @run main/othervm TestCurves
+ * @run main/othervm TestCurves sm
  * @key randomness
  */
 
-import java.util.*;
-
-import java.security.*;
-import java.security.spec.*;
-
-import javax.crypto.*;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
+import java.security.ProviderException;
+import java.security.Signature;
+import java.security.spec.ECParameterSpec;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import javax.crypto.KeyAgreement;
 
 public class TestCurves extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new TestCurves());
+        main(new TestCurves(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("KeyAgreement", "ECDH") == null) {
             System.out.println("Not supported by provider, skipping");
             return;
         }
 
-        if (isNSS(p) && getNSSVersion() >= 3.11 && getNSSVersion() < 3.12) {
-            System.out.println("NSS 3.11 has a DER issue that recent " +
-                    "version do not.");
+        if (isBadNSSVersion(p)) {
             return;
         }
 
-        /*
-         * Use Solaris SPARC 11.2 or later to avoid an intermittent failure
-         * when running SunPKCS11-Solaris (8044554)
-         */
-        if (p.getName().equals("SunPKCS11-Solaris") &&
-            System.getProperty("os.name").equals("SunOS") &&
-            System.getProperty("os.arch").equals("sparcv9") &&
-            System.getProperty("os.version").compareTo("5.11") <= 0 &&
-            getDistro().compareTo("11.2") < 0) {
-
-            System.out.println("SunPKCS11-Solaris provider requires " +
-                "Solaris SPARC 11.2 or later, skipping");
+        if (isBadSolarisSparc(p)) {
             return;
         }
 
         // Check if this is sparc for later failure avoidance.
         boolean sparc = false;
-        if (System.getProperty("os.arch").equals("sparcv9")) {
+        if (props.getProperty("os.arch").equals("sparcv9")) {
             sparc = true;
             System.out.println("This is a sparcv9");
         }
@@ -84,7 +77,7 @@
         byte[] data = new byte[2048];
         random.nextBytes(data);
 
-        Vector<ECParameterSpec> curves = getKnownCurves(p);
+        List<ECParameterSpec> curves = getKnownCurves(p);
         for (ECParameterSpec params : curves) {
             System.out.println("Testing " + params + "...");
             KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", p);
--- a/jdk/test/sun/security/pkcs11/ec/TestECDH.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDH.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -28,16 +28,21 @@
  * @author Andreas Sterbenz
  * @library ..
  * @library ../../../../java/security/testlibrary
+ * @run main/othervm TestECDH
+ * @run main/othervm TestECDH sm policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.spec.*;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
 import java.security.interfaces.ECPublicKey;
-
-import javax.crypto.*;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import javax.crypto.KeyAgreement;
 
 public class TestECDH extends PKCS11Test {
 
@@ -55,6 +60,7 @@
 
     private final static String secret163 = "04:ae:71:c1:c6:4d:f4:34:4d:72:70:a4:64:65:7f:2d:88:2d:3f:50:be";
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("KeyAgreement", "ECDH") == null) {
             System.out.println("Provider does not support ECDH, skipping");
@@ -89,10 +95,12 @@
         System.out.println("OK");
     }
 
-    private final static void test(Provider p, String pub1s, String priv1s, String pub2s, String priv2s, String secrets) throws Exception {
+    private final static void test(Provider p, String pub1s, String priv1s,
+            String pub2s, String priv2s, String secrets) throws Exception {
         KeyFactory kf = KeyFactory.getInstance("EC", p);
         PublicKey pub1 = kf.generatePublic(new X509EncodedKeySpec(parse(pub1s)));
-        System.out.println("Testing using parameters " + ((ECPublicKey)pub1).getParams() + "...");
+        System.out.println("Testing using parameters "
+                + ((ECPublicKey)pub1).getParams() + "...");
 
         PrivateKey priv1 = kf.generatePrivate(new PKCS8EncodedKeySpec(parse(priv1s)));
         PublicKey pub2 = kf.generatePublic(new X509EncodedKeySpec(parse(pub2s)));
@@ -121,7 +129,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestECDH());
+        main(new TestECDH(), args);
     }
 
 }
--- a/jdk/test/sun/security/pkcs11/ec/TestECDH2.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDH2.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -30,19 +30,25 @@
  * @library ../../../../java/security/testlibrary
  * @modules java.base/sun.security.util
  * @compile -XDignore.symbol.file TestECDH2.java
- * @run main TestECDH2
+ * @run main/othervm TestECDH2
+ * @run main/othervm TestECDH2 sm
  */
 
-import java.io.*;
-import java.util.*;
 import java.math.BigInteger;
-
-import java.security.*;
-import java.security.spec.*;
-import java.security.interfaces.*;
-import javax.crypto.*;
-
-import sun.security.util.ECUtil;
+import java.security.AlgorithmParameters;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
+import java.util.Arrays;
+import javax.crypto.KeyAgreement;
 
 public class TestECDH2 extends PKCS11Test {
 
@@ -81,7 +87,9 @@
 
     private KeyPair genECKeyPair(String curvName, String privD, String pubX,
                                  String pubY, Provider p) throws Exception {
-        ECParameterSpec ecParams = ECUtil.getECParameterSpec(p, curvName);
+        AlgorithmParameters params = AlgorithmParameters.getInstance("EC", p);
+        params.init(new ECGenParameterSpec(curvName));
+        ECParameterSpec ecParams = params.getParameterSpec(ECParameterSpec.class);
         ECPrivateKeySpec privKeySpec =
             new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams);
         ECPublicKeySpec pubKeySpec =
@@ -98,19 +106,17 @@
         return kpg.generateKeyPair();
     }
     public static void main(String[] args) throws Exception {
-        main(new TestECDH2());
+        main(new TestECDH2(), args);
     }
 
+    @Override
     public void main(Provider provider) throws Exception {
         if (provider.getService("KeyAgreement", "ECDH") == null) {
             System.out.println("ECDH not supported, skipping");
             return;
         }
 
-        if (isNSS(provider) && getNSSVersion() >= 3.11 &&
-                getNSSVersion() < 3.12) {
-            System.out.println("NSS 3.11 has a DER issue that recent " +
-                    "version do not.");
+        if (isBadNSSVersion(provider)) {
             return;
         }
 
--- a/jdk/test/sun/security/pkcs11/ec/TestECDSA.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -29,13 +29,22 @@
  * @library ..
  * @library ../../../../java/security/testlibrary
  * @key randomness
+ * @run main/othervm TestECDSA
+ * @run main/othervm TestECDSA sm policy
  */
 
-import java.util.*;
-
-import java.security.*;
-import java.security.spec.*;
-import java.security.interfaces.*;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Random;
 
 public class TestECDSA extends PKCS11Test {
 
@@ -79,7 +88,8 @@
     private final static byte[] data2Raw = {};
     private final static byte[] data2SHA = b("da:39:a3:ee:5e:6b:4b:0d:32:55:bf:ef:95:60:18:90:af:d8:07:09");
 
-    private static void verify(Provider provider, String alg, PublicKey key, byte[] data, byte[] sig, boolean result) throws Exception {
+    private static void verify(Provider provider, String alg, PublicKey key,
+            byte[] data, byte[] sig, boolean result) throws Exception {
         Signature s = Signature.getInstance(alg, provider);
         s.initVerify(key);
         boolean r;
@@ -105,9 +115,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestECDSA());
+        main(new TestECDSA(), args);
     }
 
+    @Override
     public void main(Provider provider) throws Exception {
         long start = System.currentTimeMillis();
 
@@ -116,25 +127,11 @@
             return;
         }
 
-        if (isNSS(provider) && getNSSVersion() >= 3.11 &&
-                getNSSVersion() < 3.12) {
-            System.out.println("NSS 3.11 has a DER issue that recent " +
-                    "version do not.");
+        if (isBadNSSVersion(provider)) {
             return;
         }
 
-        /*
-         * Use Solaris SPARC 11.2 or later to avoid an intermittent failure
-         * when running SunPKCS11-Solaris (8044554)
-         */
-        if (provider.getName().equals("SunPKCS11-Solaris") &&
-            System.getProperty("os.name").equals("SunOS") &&
-            System.getProperty("os.arch").equals("sparcv9") &&
-            System.getProperty("os.version").compareTo("5.11") <= 0 &&
-            getDistro().compareTo("11.2") < 0) {
-
-            System.out.println("SunPKCS11-Solaris provider requires " +
-                "Solaris SPARC 11.2 or later, skipping");
+        if (isBadSolarisSparc(provider)) {
             return;
         }
 
--- a/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -30,18 +30,23 @@
  * @library ../../../../java/security/testlibrary
  * @modules java.base/sun.security.util
  * @compile -XDignore.symbol.file TestECDSA2.java
- * @run main TestECDSA2
+ * @run main/othervm TestECDSA2
+ * @run main/othervm TestECDSA2 sm
  */
 
-import java.io.*;
-import java.util.*;
 import java.math.BigInteger;
-
-import java.security.*;
-import java.security.spec.*;
-import java.security.interfaces.*;
-
-import sun.security.util.ECUtil;
+import java.security.AlgorithmParameters;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
 
 public class TestECDSA2 extends PKCS11Test {
 
@@ -78,7 +83,9 @@
 
     private KeyPair genECKeyPair(String curvName, String privD, String pubX,
             String pubY, Provider p) throws Exception {
-        ECParameterSpec ecParams = ECUtil.getECParameterSpec(p, curvName);
+        AlgorithmParameters params = AlgorithmParameters.getInstance("EC", p);
+        params.init(new ECGenParameterSpec(curvName));
+        ECParameterSpec ecParams = params.getParameterSpec(ECParameterSpec.class);
         ECPrivateKeySpec privKeySpec =
             new ECPrivateKeySpec(new BigInteger(privD, 16), ecParams);
         ECPublicKeySpec pubKeySpec =
@@ -90,9 +97,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestECDSA2());
+        main(new TestECDSA2(), args);
     }
 
+    @Override
     public void main(Provider provider) throws Exception {
         boolean testP256 =
             (provider.getService("Signature", "SHA256withECDSA") != null);
@@ -105,10 +113,7 @@
             return;
         }
 
-        if (isNSS(provider) && getNSSVersion() >= 3.11 &&
-                getNSSVersion() < 3.12) {
-            System.out.println("NSS 3.11 has a DER issue that recent " +
-                    "version do not.");
+        if (isBadNSSVersion(provider)) {
             return;
         }
 
--- a/jdk/test/sun/security/pkcs11/ec/TestECGenSpec.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/TestECGenSpec.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -27,29 +27,32 @@
  * @summary Verify that we can use ECGenParameterSpec
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm TestECGenSpec
+ * @run main/othervm TestECGenSpec sm
  */
 
-import java.util.*;
-
-import java.security.*;
-import java.security.spec.*;
+import java.security.AlgorithmParameters;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Provider;
 import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
 
 public class TestECGenSpec extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new TestECGenSpec());
+        main(new TestECGenSpec(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("Signature", "SHA1withECDSA") == null) {
             System.out.println("Provider does not support ECDSA, skipping...");
             return;
         }
 
-        if (isNSS(p) && getNSSVersion() >= 3.11 && getNSSVersion() < 3.12) {
-            System.out.println("NSS 3.11 has a DER issue that recent " +
-                    "version do not.");
+        if (isBadNSSVersion(p)) {
             return;
         }
 
--- a/jdk/test/sun/security/pkcs11/ec/TestKeyFactory.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/TestKeyFactory.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -27,14 +27,23 @@
  * @summary Test the P11ECKeyFactory
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm TestKeyFactory
+ * @run main/othervm TestKeyFactory sm
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.interfaces.*;
-import java.security.spec.*;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
 
 public class TestKeyFactory extends PKCS11Test {
 
@@ -111,9 +120,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestKeyFactory());
+        main(new TestKeyFactory(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         if (p.getService("KeyFactory", "EC") == null) {
             System.out.println("Provider does not support EC, skipping");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/ec/policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,7 @@
+grant {
+    permission java.lang.RuntimePermission "setSecurityManager";
+    permission java.security.SecurityPermission "insertProvider.*";   
+    permission java.security.SecurityPermission "removeProvider.*";
+    permission java.io.FilePermission "${test.src}/-", "read";
+    permission java.io.FilePermission "${closed.base}/-", "read";
+};
\ No newline at end of file
--- a/jdk/test/sun/security/pkcs11/fips/TrustManagerTest.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/fips/TrustManagerTest.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -29,15 +29,21 @@
  * @library ..
  * @modules java.base/com.sun.net.ssl.internal.ssl
  * @run main/othervm TrustManagerTest
+ * @run main/othervm TrustManagerTest sm TrustManagerTest.policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.cert.*;
-
-import javax.net.ssl.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.Policy;
+import java.security.Provider;
+import java.security.Security;
+import java.security.URIParameter;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
 
 // This test belongs more in JSSE than here, but the JSSE workspace does not
 // have the NSS test infrastructure. It will live here for the time being.
@@ -73,6 +79,12 @@
         X509Certificate ca = loadCertificate("certs/ca.cer");
         X509Certificate anchor = loadCertificate("certs/anchor.cer");
 
+        if (args.length > 1 && "sm".equals(args[0])) {
+            Policy.setPolicy(Policy.getInstance("JavaPolicy",
+                    new URIParameter(new File(BASE, args[1]).toURI())));
+            System.setSecurityManager(new SecurityManager());
+        }
+
         KeyStore trustStore = KeyStore.getInstance("JKS");
         trustStore.load(null, null);
         trustStore.setCertificateEntry("anchor", anchor);
@@ -90,11 +102,10 @@
     }
 
     private static X509Certificate loadCertificate(String name) throws Exception {
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-        InputStream in = new FileInputStream(BASE + SEP + name);
-        X509Certificate cert = (X509Certificate)cf.generateCertificate(in);
-        in.close();
-        return cert;
+        try (InputStream in = new FileInputStream(BASE + SEP + name)) {
+            return (X509Certificate) CertificateFactory.getInstance("X.509")
+                    .generateCertificate(in);
+        }
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/fips/TrustManagerTest.policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,3 @@
+grant {
+    
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,3 @@
+grant {
+    permission java.lang.RuntimePermission "setSecurityManager";
+};
\ No newline at end of file
--- a/jdk/test/sun/security/pkcs11/rsa/KeyWrap.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/rsa/KeyWrap.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -28,18 +28,28 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm KeyWrap
+ * @run main/othervm KeyWrap sm
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.util.Random;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
 
 public class KeyWrap extends PKCS11Test {
 
+    @Override
     public void main(Provider p) throws Exception {
         try {
             Cipher.getInstance("RSA/ECB/PKCS1Padding", p);
@@ -62,7 +72,7 @@
                 PublicKey pub = (PublicKey)kf.translateKey(kp.getPublic());
                 PrivateKey priv = (PrivateKey)kf.translateKey(kp.getPrivate());
                 kp = new KeyPair(pub, priv);
-            } catch (Exception ee) {
+            } catch (NoSuchAlgorithmException | InvalidKeyException ee) {
                 ee.printStackTrace();
                 System.out.println("Provider does not support RSA, skipping");
                 return;
@@ -93,7 +103,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new KeyWrap());
+        main(new KeyWrap(), args);
     }
 
 }
--- a/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,24 +28,28 @@
  * @author Andreas Sterbenz
  * @library ..
  * @library ../../../../java/security/testlibrary
+ * @run main/othervm TestCACerts
+ * @run main/othervm TestCACerts sm TestCACerts.policy
  */
 
 // this test serves as our known answer test
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.cert.*;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
 
 public class TestCACerts extends PKCS11Test {
 
-    private final static char SEP = File.separatorChar;
-
     public static void main(String[] args) throws Exception {
-        main(new TestCACerts());
+        main(new TestCACerts(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
 
         /*
@@ -53,9 +57,9 @@
          * when running SunPKCS11-Solaris (8044554)
          */
         if (p.getName().equals("SunPKCS11-Solaris") &&
-            System.getProperty("os.name").equals("SunOS") &&
-            System.getProperty("os.arch").equals("sparcv9") &&
-            System.getProperty("os.version").compareTo("5.11") <= 0 &&
+            props.getProperty("os.name").equals("SunOS") &&
+            props.getProperty("os.arch").equals("sparcv9") &&
+            props.getProperty("os.version").compareTo("5.11") <= 0 &&
             getDistro().compareTo("11.2") < 0) {
 
             System.out.println("SunPKCS11-Solaris provider requires " +
@@ -67,12 +71,13 @@
         Providers.setAt(p, 1);
         try {
             String PROVIDER = p.getName();
-            String javaHome = System.getProperty("java.home");
+            String javaHome = props.getProperty("java.home");
             String caCerts = javaHome + SEP + "lib" + SEP + "security" + SEP + "cacerts";
-            InputStream in = new FileInputStream(caCerts);
-            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
-            ks.load(in, null);
-            in.close();
+            KeyStore ks;
+            try (InputStream in = new FileInputStream(caCerts)) {
+                ks = KeyStore.getInstance(KeyStore.getDefaultType());
+                ks.load(in, null);
+            }
             for (Enumeration e = ks.aliases(); e.hasMoreElements(); ) {
                 String alias = (String)e.nextElement();
                 if (ks.isCertificateEntry(alias)) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/rsa/TestCACerts.policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,7 @@
+grant {
+    permission java.lang.RuntimePermission "setSecurityManager";
+    permission java.security.SecurityPermission "insertProvider.*";
+    permission java.security.SecurityPermission "removeProvider.*";
+    permission java.util.PropertyPermission "java.home", "read";
+    permission java.io.FilePermission "${java.home}/lib/security/cacerts", "read";
+};
\ No newline at end of file
--- a/jdk/test/sun/security/pkcs11/rsa/TestKeyFactory.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/rsa/TestKeyFactory.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -27,26 +27,26 @@
  * @summary Test KeyFactory of the new RSA provider
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm TestKeyFactory
+ * @run main/othervm TestKeyFactory sm rsakeys.ks.policy
  */
 
 import java.io.*;
 import java.util.*;
 
 import java.security.*;
-import java.security.interfaces.*;
 import java.security.spec.*;
 
 public class TestKeyFactory extends PKCS11Test {
 
-    private final static String BASE = System.getProperty("test.src", ".");
-
     private static final char[] password = "test12".toCharArray();
 
     static KeyStore getKeyStore() throws Exception {
-        InputStream in = new FileInputStream(new File(BASE, "rsakeys.ks"));
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(in, password);
-        in.close();
+        KeyStore ks;
+        try (InputStream in = new FileInputStream(new File(BASE, "rsakeys.ks"))) {
+            ks = KeyStore.getInstance("JKS");
+            ks.load(in, password);
+        }
         return ks;
     }
 
@@ -128,9 +128,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestKeyFactory());
+        main(new TestKeyFactory(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         long start = System.currentTimeMillis();
         KeyStore ks = getKeyStore();
--- a/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -30,16 +30,20 @@
  * @library /lib/testlibrary
  * @build jdk.testlibrary.*
  * @run main/othervm TestKeyPairGenerator
+ * @run main/othervm TestKeyPairGenerator sm TestKeyPairGenerator.policy
  * @key intermittent randomness
  */
 
-import java.io.*;
-import java.util.*;
 import java.math.BigInteger;
-
-import java.security.*;
-import java.security.interfaces.*;
-import java.security.spec.*;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAKeyGenParameterSpec;
 import jdk.testlibrary.RandomFactory;
 
 public class TestKeyPairGenerator extends PKCS11Test {
@@ -48,7 +52,8 @@
 
     private static byte[] data;
 
-    private static void testSignature(String algorithm, PrivateKey privateKey, PublicKey publicKey) throws Exception {
+    private static void testSignature(String algorithm, PrivateKey privateKey,
+            PublicKey publicKey) throws Exception {
         System.out.println("Testing " + algorithm + "...");
         Signature s = Signature.getInstance(algorithm, provider);
         s.initSign(privateKey);
@@ -98,9 +103,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestKeyPairGenerator());
+        main(new TestKeyPairGenerator(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
         long start = System.currentTimeMillis();
         provider = p;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,4 @@
+grant {
+    permission java.lang.RuntimePermission "setSecurityManager";
+    permission java.util.PropertyPermission "seed", "read";
+};
\ No newline at end of file
--- a/jdk/test/sun/security/pkcs11/rsa/TestSignatures.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/rsa/TestSignatures.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -28,18 +28,25 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
+ * @run main/othervm TestSignatures
+ * @run main/othervm TestSignatures sm rsakeys.ks.policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.interfaces.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Enumeration;
+import java.util.Random;
 
 public class TestSignatures extends PKCS11Test {
 
-    private final static String BASE = System.getProperty("test.src", ".");
-
     private static final char[] password = "test12".toCharArray();
 
     private static Provider provider;
@@ -47,14 +54,16 @@
     private static byte[] data;
 
     static KeyStore getKeyStore() throws Exception {
-        InputStream in = new FileInputStream(new File(BASE, "rsakeys.ks"));
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(in, password);
-        in.close();
+        KeyStore ks;
+        try (InputStream in = new FileInputStream(new File(BASE, "rsakeys.ks"))) {
+            ks = KeyStore.getInstance("JKS");
+            ks.load(in, password);
+        }
         return ks;
     }
 
-    private static void testSignature(String algorithm, PrivateKey privateKey, PublicKey publicKey) throws Exception {
+    private static void testSignature(String algorithm, PrivateKey privateKey,
+            PublicKey publicKey) throws Exception {
         System.out.println("Testing " + algorithm + "...");
         Signature s = Signature.getInstance(algorithm, provider);
         s.initSign(privateKey);
@@ -78,7 +87,8 @@
         }
     }
 
-    private static void test(PrivateKey privateKey, PublicKey publicKey) throws Exception {
+    private static void test(PrivateKey privateKey, PublicKey publicKey)
+            throws Exception {
         testSignature("MD2withRSA", privateKey, publicKey);
         testSignature("MD5withRSA", privateKey, publicKey);
         testSignature("SHA1withRSA", privateKey, publicKey);
@@ -93,9 +103,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        main(new TestSignatures());
+        main(new TestSignatures(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
 
         /*
@@ -103,9 +114,9 @@
          * when running SunPKCS11-Solaris (8044554)
          */
         if (p.getName().equals("SunPKCS11-Solaris") &&
-            System.getProperty("os.name").equals("SunOS") &&
-            System.getProperty("os.arch").equals("sparcv9") &&
-            System.getProperty("os.version").compareTo("5.11") <= 0 &&
+            props.getProperty("os.name").equals("SunOS") &&
+            props.getProperty("os.arch").equals("sparcv9") &&
+            props.getProperty("os.version").compareTo("5.11") <= 0 &&
             getDistro().compareTo("11.2") < 0) {
 
             System.out.println("SunPKCS11-Solaris provider requires " +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/rsa/rsakeys.ks.policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,4 @@
+grant {
+    permission java.lang.RuntimePermission "setSecurityManager";
+    permission java.io.FilePermission "${test.src}/rsakeys.ks", "read";
+};
\ No newline at end of file
--- a/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -47,7 +47,8 @@
     // use any available port for the server socket
     static volatile int serverPort = 0;
 
-    final int THREADS;
+    static final int THREADS = Integer.getInteger("numThreads", 4);
+    static final String TEST_SRC = System.getProperty("test.src", ".");
 
     // assume that if we do not read anything for 20 seconds, something
     // has gone wrong
@@ -68,6 +69,7 @@
             this.cipherTest = cipherTest;
         }
 
+        @Override
         public abstract void run();
 
         void handleRequest(InputStream in, OutputStream out) throws IOException {
@@ -117,6 +119,7 @@
             return TLSCipherStatus.isEnabled(cipherSuite, protocol);
         }
 
+        @Override
         public String toString() {
             String s = cipherSuite + " in " + protocol + " mode";
             if (clientAuth != null) {
@@ -260,7 +263,6 @@
     private boolean failed;
 
     private CipherTest(PeerFactory peerFactory) throws IOException {
-        THREADS = Integer.parseInt(System.getProperty("numThreads", "4"));
         factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
         SSLSocket socket = (SSLSocket)factory.createSocket();
         String[] cipherSuites = socket.getSupportedCipherSuites();
@@ -350,6 +352,7 @@
             this.cipherTest = cipherTest;
         }
 
+        @Override
         public final void run() {
             while (true) {
                 TestParameters params = cipherTest.getTest();
@@ -405,10 +408,11 @@
 
     private static KeyStore readKeyStore(String name) throws Exception {
         File file = new File(PATH, name);
-        InputStream in = new FileInputStream(file);
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(in, passwd);
-        in.close();
+        KeyStore ks;
+        try (InputStream in = new FileInputStream(file)) {
+            ks = KeyStore.getInstance("JKS");
+            ks.load(in, passwd);
+        }
         return ks;
     }
 
@@ -421,7 +425,7 @@
         } else {
             relPath = pathToStores;
         }
-        PATH = new File(System.getProperty("test.src", "."), relPath);
+        PATH = new File(TEST_SRC, relPath);
         CipherTest.peerFactory = peerFactory;
         System.out.print(
             "Initializing test '" + peerFactory.getName() + "'...");
@@ -494,16 +498,19 @@
 
     }
 
+    @Override
     public void checkClientTrusted(X509Certificate[] chain, String authType)
             throws CertificateException {
         // empty
     }
 
+    @Override
     public void checkServerTrusted(X509Certificate[] chain, String authType)
             throws CertificateException {
         // empty
     }
 
+    @Override
     public X509Certificate[] getAcceptedIssuers() {
         return new X509Certificate[0];
     }
@@ -522,6 +529,7 @@
         this.authType = "ECDSA".equals(authType) ? "EC" : authType;
     }
 
+    @Override
     public String[] getClientAliases(String keyType, Principal[] issuers) {
         if (authType == null) {
             return null;
@@ -529,6 +537,7 @@
         return keyManager.getClientAliases(authType, issuers);
     }
 
+    @Override
     public String chooseClientAlias(String[] keyType, Principal[] issuers,
             Socket socket) {
         if (authType == null) {
@@ -538,6 +547,7 @@
             issuers, socket);
     }
 
+    @Override
     public String chooseEngineClientAlias(String[] keyType,
             Principal[] issuers, SSLEngine engine) {
         if (authType == null) {
@@ -547,24 +557,29 @@
             issuers, engine);
     }
 
+    @Override
     public String[] getServerAliases(String keyType, Principal[] issuers) {
         throw new UnsupportedOperationException("Servers not supported");
     }
 
+    @Override
     public String chooseServerAlias(String keyType, Principal[] issuers,
             Socket socket) {
         throw new UnsupportedOperationException("Servers not supported");
     }
 
+    @Override
     public String chooseEngineServerAlias(String keyType, Principal[] issuers,
             SSLEngine engine) {
         throw new UnsupportedOperationException("Servers not supported");
     }
 
+    @Override
     public X509Certificate[] getCertificateChain(String alias) {
         return keyManager.getCertificateChain(alias);
     }
 
+    @Override
     public PrivateKey getPrivateKey(String alias) {
         return keyManager.getPrivateKey(alias);
     }
@@ -577,6 +592,7 @@
 
     private final static ThreadFactory DEFAULT = Executors.defaultThreadFactory();
 
+    @Override
     public Thread newThread(Runnable r) {
         Thread t = DEFAULT.newThread(r);
         t.setDaemon(true);
--- a/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -34,25 +34,28 @@
  * @library ..
  * @library ../../../../java/security/testlibrary
  * @run main/othervm ClientJSSEServerJSSE
+ * @run main/othervm ClientJSSEServerJSSE sm policy
  */
 
-import java.security.*;
+import java.security.Provider;
+import java.security.Security;
 
 public class ClientJSSEServerJSSE extends PKCS11Test {
 
     private static String[] cmdArgs;
 
     public static void main(String[] args) throws Exception {
-        cmdArgs = args;
-        main(new ClientJSSEServerJSSE());
-    }
-
-    public void main(Provider p) throws Exception {
         // reset security properties to make sure that the algorithms
         // and keys used in this test are not disabled.
         Security.setProperty("jdk.tls.disabledAlgorithms", "");
         Security.setProperty("jdk.certpath.disabledAlgorithms", "");
 
+        cmdArgs = args;
+        main(new ClientJSSEServerJSSE(), args);
+    }
+
+    @Override
+    public void main(Provider p) throws Exception {
         if (p.getService("KeyFactory", "EC") == null) {
             System.out.println("Provider does not support EC, skipping");
             return;
@@ -64,14 +67,17 @@
 
     private static class JSSEFactory extends CipherTest.PeerFactory {
 
+        @Override
         String getName() {
             return "Client JSSE - Server JSSE";
         }
 
+        @Override
         CipherTest.Client newClient(CipherTest cipherTest) throws Exception {
             return new JSSEClient(cipherTest);
         }
 
+        @Override
         CipherTest.Server newServer(CipherTest cipherTest) throws Exception {
             return new JSSEServer(cipherTest);
         }
--- a/jdk/test/sun/security/pkcs11/sslecc/JSSEServer.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/sslecc/JSSEServer.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -21,16 +21,17 @@
  * questions.
  */
 
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import java.security.*;
-import java.security.cert.*;
-import java.security.cert.Certificate;
-
-import javax.net.ssl.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
 
 class JSSEServer extends CipherTest.Server {
 
@@ -48,15 +49,17 @@
         serverSocket.setWantClientAuth(true);
     }
 
+    @Override
     public void run() {
         System.out.println("JSSE Server listening on port " + cipherTest.serverPort);
         Executor exec = Executors.newFixedThreadPool
-                            (cipherTest.THREADS, DaemonThreadFactory.INSTANCE);
+                            (CipherTest.THREADS, DaemonThreadFactory.INSTANCE);
         try {
             while (true) {
                 final SSLSocket socket = (SSLSocket)serverSocket.accept();
                 socket.setSoTimeout(cipherTest.TIMEOUT);
                 Runnable r = new Runnable() {
+                    @Override
                     public void run() {
                         try {
                             InputStream in = socket.getInputStream();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/sslecc/policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,9 @@
+grant {
+    permission java.lang.RuntimePermission "setSecurityManager";
+    permission java.security.SecurityPermission "insertProvider.*";
+    permission java.security.SecurityPermission "removeProvider.*";
+    permission java.util.PropertyPermission "test.src", "read";
+    permission java.util.PropertyPermission "numThreads", "read";
+    permission java.io.FilePermission "${test.src}/*", "read";
+    permission java.net.SocketPermission "127.0.0.1:*", "listen,resolve,accept,connect";
+};
\ No newline at end of file
--- a/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -28,136 +28,138 @@
  * @author Andreas Sterbenz
  * @library ..
  * @modules java.base/sun.security.internal.spec
+ * @run main/othervm TestKeyMaterial
+ * @run main/othervm TestKeyMaterial sm policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.Security;
+import java.io.BufferedReader;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.Provider;
-
+import java.util.Arrays;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
-
-import javax.crypto.spec.*;
-
-import sun.security.internal.spec.*;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import sun.security.internal.spec.TlsKeyMaterialParameterSpec;
+import sun.security.internal.spec.TlsKeyMaterialSpec;
 
 public class TestKeyMaterial extends PKCS11Test {
 
-    private static int PREFIX_LENGTH = "km-master:  ".length();
+    private static final int PREFIX_LENGTH = "km-master:  ".length();
 
     public static void main(String[] args) throws Exception {
-        main(new TestKeyMaterial());
+        main(new TestKeyMaterial(), args);
     }
 
+    @Override
     public void main(Provider provider) throws Exception {
         if (provider.getService("KeyGenerator", "SunTlsKeyMaterial") == null) {
             System.out.println("Provider does not support algorithm, skipping");
             return;
         }
 
-        InputStream in = new FileInputStream(new File(BASE, "keymatdata.txt"));
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+        try (BufferedReader reader = Files.newBufferedReader(
+                Paths.get(BASE, "keymatdata.txt"))) {
+
+            int n = 0;
+            int lineNumber = 0;
 
-        int n = 0;
-        int lineNumber = 0;
+            byte[] master = null;
+            int major = 0;
+            int minor = 0;
+            byte[] clientRandom = null;
+            byte[] serverRandom = null;
+            String cipherAlgorithm = null;
+            int keyLength = 0;
+            int expandedKeyLength = 0;
+            int ivLength = 0;
+            int macLength = 0;
+            byte[] clientCipherBytes = null;
+            byte[] serverCipherBytes = null;
+            byte[] clientIv = null;
+            byte[] serverIv = null;
+            byte[] clientMacBytes = null;
+            byte[] serverMacBytes = null;
 
-        byte[] master = null;
-        int major = 0;
-        int minor = 0;
-        byte[] clientRandom = null;
-        byte[] serverRandom = null;
-        String cipherAlgorithm = null;
-        int keyLength = 0;
-        int expandedKeyLength = 0;
-        int ivLength = 0;
-        int macLength = 0;
-        byte[] clientCipherBytes = null;
-        byte[] serverCipherBytes = null;
-        byte[] clientIv = null;
-        byte[] serverIv = null;
-        byte[] clientMacBytes = null;
-        byte[] serverMacBytes = null;
+            while (true) {
+                String line = reader.readLine();
+                lineNumber++;
+                if (line == null) {
+                    break;
+                }
+                if (line.startsWith("km-") == false) {
+                    continue;
+                }
+                String data = line.substring(PREFIX_LENGTH);
+                if (line.startsWith("km-master:")) {
+                    master = parse(data);
+                } else if (line.startsWith("km-major:")) {
+                    major = Integer.parseInt(data);
+                } else if (line.startsWith("km-minor:")) {
+                    minor = Integer.parseInt(data);
+                } else if (line.startsWith("km-crandom:")) {
+                    clientRandom = parse(data);
+                } else if (line.startsWith("km-srandom:")) {
+                    serverRandom = parse(data);
+                } else if (line.startsWith("km-cipalg:")) {
+                    cipherAlgorithm = data;
+                } else if (line.startsWith("km-keylen:")) {
+                    keyLength = Integer.parseInt(data);
+                } else if (line.startsWith("km-explen:")) {
+                    expandedKeyLength = Integer.parseInt(data);
+                } else if (line.startsWith("km-ivlen:")) {
+                    ivLength = Integer.parseInt(data);
+                } else if (line.startsWith("km-maclen:")) {
+                    macLength = Integer.parseInt(data);
+                } else if (line.startsWith("km-ccipkey:")) {
+                    clientCipherBytes = parse(data);
+                } else if (line.startsWith("km-scipkey:")) {
+                    serverCipherBytes = parse(data);
+                } else if (line.startsWith("km-civ:")) {
+                    clientIv = parse(data);
+                } else if (line.startsWith("km-siv:")) {
+                    serverIv = parse(data);
+                } else if (line.startsWith("km-cmackey:")) {
+                    clientMacBytes = parse(data);
+                } else if (line.startsWith("km-smackey:")) {
+                    serverMacBytes = parse(data);
 
-        while (true) {
-            String line = reader.readLine();
-            lineNumber++;
-            if (line == null) {
-                break;
-            }
-            if (line.startsWith("km-") == false) {
-                continue;
+                    System.out.print(".");
+                    n++;
+
+                    KeyGenerator kg =
+                        KeyGenerator.getInstance("SunTlsKeyMaterial", provider);
+                    SecretKey masterKey =
+                        new SecretKeySpec(master, "TlsMasterSecret");
+                    TlsKeyMaterialParameterSpec spec =
+                        new TlsKeyMaterialParameterSpec(masterKey, major, minor,
+                        clientRandom, serverRandom, cipherAlgorithm,
+                        keyLength, expandedKeyLength, ivLength, macLength,
+                        null, -1, -1);
+
+                    kg.init(spec);
+                    TlsKeyMaterialSpec result =
+                        (TlsKeyMaterialSpec)kg.generateKey();
+                    match(lineNumber, clientCipherBytes,
+                        result.getClientCipherKey(), cipherAlgorithm);
+                    match(lineNumber, serverCipherBytes,
+                        result.getServerCipherKey(), cipherAlgorithm);
+                    match(lineNumber, clientIv, result.getClientIv(), "");
+                    match(lineNumber, serverIv, result.getServerIv(), "");
+                    match(lineNumber, clientMacBytes, result.getClientMacKey(), "");
+                    match(lineNumber, serverMacBytes, result.getServerMacKey(), "");
+
+                } else {
+                    throw new Exception("Unknown line: " + line);
+                }
             }
-            String data = line.substring(PREFIX_LENGTH);
-            if (line.startsWith("km-master:")) {
-                master = parse(data);
-            } else if (line.startsWith("km-major:")) {
-                major = Integer.parseInt(data);
-            } else if (line.startsWith("km-minor:")) {
-                minor = Integer.parseInt(data);
-            } else if (line.startsWith("km-crandom:")) {
-                clientRandom = parse(data);
-            } else if (line.startsWith("km-srandom:")) {
-                serverRandom = parse(data);
-            } else if (line.startsWith("km-cipalg:")) {
-                cipherAlgorithm = data;
-            } else if (line.startsWith("km-keylen:")) {
-                keyLength = Integer.parseInt(data);
-            } else if (line.startsWith("km-explen:")) {
-                expandedKeyLength = Integer.parseInt(data);
-            } else if (line.startsWith("km-ivlen:")) {
-                ivLength = Integer.parseInt(data);
-            } else if (line.startsWith("km-maclen:")) {
-                macLength = Integer.parseInt(data);
-            } else if (line.startsWith("km-ccipkey:")) {
-                clientCipherBytes = parse(data);
-            } else if (line.startsWith("km-scipkey:")) {
-                serverCipherBytes = parse(data);
-            } else if (line.startsWith("km-civ:")) {
-                clientIv = parse(data);
-            } else if (line.startsWith("km-siv:")) {
-                serverIv = parse(data);
-            } else if (line.startsWith("km-cmackey:")) {
-                clientMacBytes = parse(data);
-            } else if (line.startsWith("km-smackey:")) {
-                serverMacBytes = parse(data);
-
-                System.out.print(".");
-                n++;
-
-                KeyGenerator kg =
-                    KeyGenerator.getInstance("SunTlsKeyMaterial", provider);
-                SecretKey masterKey =
-                    new SecretKeySpec(master, "TlsMasterSecret");
-                TlsKeyMaterialParameterSpec spec =
-                    new TlsKeyMaterialParameterSpec(masterKey, major, minor,
-                    clientRandom, serverRandom, cipherAlgorithm,
-                    keyLength, expandedKeyLength, ivLength, macLength,
-                    null, -1, -1);
-
-                kg.init(spec);
-                TlsKeyMaterialSpec result =
-                    (TlsKeyMaterialSpec)kg.generateKey();
-                match(lineNumber, clientCipherBytes,
-                    result.getClientCipherKey(), cipherAlgorithm);
-                match(lineNumber, serverCipherBytes,
-                    result.getServerCipherKey(), cipherAlgorithm);
-                match(lineNumber, clientIv, result.getClientIv(), "");
-                match(lineNumber, serverIv, result.getServerIv(), "");
-                match(lineNumber, clientMacBytes, result.getClientMacKey(), "");
-                match(lineNumber, serverMacBytes, result.getServerMacKey(), "");
-
-            } else {
-                throw new Exception("Unknown line: " + line);
+            if (n == 0) {
+                throw new Exception("no tests");
             }
-        }
-        if (n == 0) {
-            throw new Exception("no tests");
+            System.out.println();
+            System.out.println("OK: " + n + " tests");
         }
-        in.close();
-        System.out.println();
-        System.out.println("OK: " + n + " tests");
     }
 
     private static void stripParity(byte[] b) {
--- a/jdk/test/sun/security/pkcs11/tls/TestLeadingZeroesP11.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/tls/TestLeadingZeroesP11.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -27,15 +27,18 @@
  * @summary Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
  * @library ..
  * @author Pasi Eronen
+ * @run main/othervm TestLeadingZeroesP11
+ * @run main/othervm TestLeadingZeroesP11 sm
  */
 
-import java.io.*;
-import java.security.*;
-import java.security.spec.*;
-import java.security.interfaces.*;
-import javax.crypto.*;
-import javax.crypto.spec.*;
-import javax.crypto.interfaces.*;
+
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import javax.crypto.KeyAgreement;
 
 /**
  * Test that leading zeroes are stripped in TlsPremasterSecret case,
@@ -48,9 +51,10 @@
 public class TestLeadingZeroesP11 extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new TestLeadingZeroesP11());
+        main(new TestLeadingZeroesP11(), args);
     }
 
+    @Override
     public void main(Provider p) throws Exception {
 
         // decode pre-generated keypairs
--- a/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -29,111 +29,112 @@
  * @library ..
  * @modules java.base/sun.security.internal.interfaces
  *          java.base/sun.security.internal.spec
+ * @run main/othervm TestMasterSecret
+ * @run main/othervm TestMasterSecret sm TestMasterSecret.policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.Security;
+import java.io.BufferedReader;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.Provider;
-
+import java.util.Arrays;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
-
-import javax.crypto.spec.*;
-
-import sun.security.internal.spec.*;
+import javax.crypto.spec.SecretKeySpec;
 import sun.security.internal.interfaces.TlsMasterSecret;
+import sun.security.internal.spec.TlsMasterSecretParameterSpec;
 
 public class TestMasterSecret extends PKCS11Test {
 
-    private static int PREFIX_LENGTH = "m-premaster:  ".length();
+    private static final int PREFIX_LENGTH = "m-premaster:  ".length();
 
     public static void main(String[] args) throws Exception {
-        main(new TestMasterSecret());
+        main(new TestMasterSecret(), args);
     }
 
+    @Override
     public void main(Provider provider) throws Exception {
         if (provider.getService("KeyGenerator", "SunTlsMasterSecret") == null) {
             System.out.println("Not supported by provider, skipping");
             return;
         }
-        InputStream in = new FileInputStream(new File(BASE, "masterdata.txt"));
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+
+        try (BufferedReader reader = Files.newBufferedReader(
+                Paths.get(BASE, "masterdata.txt"))) {
+
+            int n = 0;
+            int lineNumber = 0;
 
-        int n = 0;
-        int lineNumber = 0;
+            String algorithm = null;
+            byte[] premaster = null;
+            byte[] clientRandom = null;
+            byte[] serverRandom = null;
+            int protoMajor = 0;
+            int protoMinor = 0;
+            int preMajor = 0;
+            int preMinor = 0;
+            byte[] master = null;
 
-        String algorithm = null;
-        byte[] premaster = null;
-        byte[] clientRandom = null;
-        byte[] serverRandom = null;
-        int protoMajor = 0;
-        int protoMinor = 0;
-        int preMajor = 0;
-        int preMinor = 0;
-        byte[] master = null;
+            while (true) {
+                String line = reader.readLine();
+                lineNumber++;
+                if (line == null) {
+                    break;
+                }
+                if (line.startsWith("m-") == false) {
+                    continue;
+                }
+                String data = line.substring(PREFIX_LENGTH);
+                if (line.startsWith("m-algorithm:")) {
+                    algorithm = data;
+                } else if (line.startsWith("m-premaster:")) {
+                    premaster = parse(data);
+                } else if (line.startsWith("m-crandom:")) {
+                    clientRandom = parse(data);
+                } else if (line.startsWith("m-srandom:")) {
+                    serverRandom = parse(data);
+                } else if (line.startsWith("m-protomajor:")) {
+                    protoMajor = Integer.parseInt(data);
+                } else if (line.startsWith("m-protominor:")) {
+                    protoMinor = Integer.parseInt(data);
+                } else if (line.startsWith("m-premajor:")) {
+                    preMajor = Integer.parseInt(data);
+                } else if (line.startsWith("m-preminor:")) {
+                    preMinor = Integer.parseInt(data);
+                } else if (line.startsWith("m-master:")) {
+                    master = parse(data);
 
-        while (true) {
-            String line = reader.readLine();
-            lineNumber++;
-            if (line == null) {
-                break;
-            }
-            if (line.startsWith("m-") == false) {
-                continue;
+                    System.out.print(".");
+                    n++;
+
+                    KeyGenerator kg =
+                        KeyGenerator.getInstance("SunTlsMasterSecret", provider);
+                    SecretKey premasterKey =
+                        new SecretKeySpec(premaster, algorithm);
+                    TlsMasterSecretParameterSpec spec =
+                        new TlsMasterSecretParameterSpec(premasterKey,
+                            protoMajor, protoMinor, clientRandom, serverRandom,
+                            null, -1, -1);
+                    kg.init(spec);
+                    TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
+                    byte[] enc = key.getEncoded();
+                    if (Arrays.equals(master, enc) == false) {
+                        throw new Exception("mismatch line: " + lineNumber);
+                    }
+                    if ((preMajor != key.getMajorVersion()) ||
+                            (preMinor != key.getMinorVersion())) {
+                        throw new Exception("version mismatch line: " + lineNumber);
+                    }
+                } else {
+                    throw new Exception("Unknown line: " + line);
+                }
             }
-            String data = line.substring(PREFIX_LENGTH);
-            if (line.startsWith("m-algorithm:")) {
-                algorithm = data;
-            } else if (line.startsWith("m-premaster:")) {
-                premaster = parse(data);
-            } else if (line.startsWith("m-crandom:")) {
-                clientRandom = parse(data);
-            } else if (line.startsWith("m-srandom:")) {
-                serverRandom = parse(data);
-            } else if (line.startsWith("m-protomajor:")) {
-                protoMajor = Integer.parseInt(data);
-            } else if (line.startsWith("m-protominor:")) {
-                protoMinor = Integer.parseInt(data);
-            } else if (line.startsWith("m-premajor:")) {
-                preMajor = Integer.parseInt(data);
-            } else if (line.startsWith("m-preminor:")) {
-                preMinor = Integer.parseInt(data);
-            } else if (line.startsWith("m-master:")) {
-                master = parse(data);
-
-                System.out.print(".");
-                n++;
-
-                KeyGenerator kg =
-                    KeyGenerator.getInstance("SunTlsMasterSecret", provider);
-                SecretKey premasterKey =
-                    new SecretKeySpec(premaster, algorithm);
-                TlsMasterSecretParameterSpec spec =
-                    new TlsMasterSecretParameterSpec(premasterKey,
-                        protoMajor, protoMinor, clientRandom, serverRandom,
-                        null, -1, -1);
-                kg.init(spec);
-                TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
-                byte[] enc = key.getEncoded();
-                if (Arrays.equals(master, enc) == false) {
-                    throw new Exception("mismatch line: " + lineNumber);
-                }
-                if ((preMajor != key.getMajorVersion()) ||
-                        (preMinor != key.getMinorVersion())) {
-                    throw new Exception("version mismatch line: " + lineNumber);
-                }
-            } else {
-                throw new Exception("Unknown line: " + line);
+            if (n == 0) {
+                throw new Exception("no tests");
             }
-        }
-        if (n == 0) {
-            throw new Exception("no tests");
+            System.out.println();
+            System.out.println("OK: " + n + " tests");
         }
-        in.close();
-        System.out.println();
-        System.out.println("OK: " + n + " tests");
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,8 @@
+grant {
+    permission java.lang.RuntimePermission "setSecurityManager";
+    permission java.io.FilePermission "${test.src}/*", "read";
+    permission java.lang.RuntimePermission
+        "accessClassInPackage.sun.security.internal.spec";
+    permission java.lang.RuntimePermission
+        "accessClassInPackage.sun.security.internal.interfaces";
+};
\ No newline at end of file
--- a/jdk/test/sun/security/pkcs11/tls/TestPRF.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/tls/TestPRF.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -28,116 +28,116 @@
  * @author Andreas Sterbenz
  * @library ..
  * @modules java.base/sun.security.internal.spec
+ * @run main/othervm TestPRF
+ * @run main/othervm TestPRF sm policy
  */
 
-import java.io.*;
-import java.util.*;
-
-import java.security.Security;
+import java.io.BufferedReader;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.Provider;
-
+import java.util.Arrays;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
-
-import javax.crypto.spec.*;
-
-import sun.security.internal.spec.*;
+import javax.crypto.spec.SecretKeySpec;
+import sun.security.internal.spec.TlsPrfParameterSpec;
 
 public class TestPRF extends PKCS11Test {
 
-    private static int PREFIX_LENGTH = "prf-output: ".length();
+    private static final int PREFIX_LENGTH = "prf-output: ".length();
 
     public static void main(String[] args) throws Exception {
-        main(new TestPRF());
+        main(new TestPRF(), args);
     }
 
+    @Override
     public void main(Provider provider) throws Exception {
         if (provider.getService("KeyGenerator", "SunTlsPrf") == null) {
             System.out.println("Provider does not support algorithm, skipping");
             return;
         }
 
-        InputStream in = new FileInputStream(new File(BASE, "prfdata.txt"));
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+        try (BufferedReader reader = Files.newBufferedReader(
+                Paths.get(BASE, "prfdata.txt"))) {
 
-        int n = 0;
-        int lineNumber = 0;
+            int n = 0;
+            int lineNumber = 0;
 
-        byte[] secret = null;
-        String label = null;
-        byte[] seed = null;
-        int length = 0;
-        byte[] output = null;
+            byte[] secret = null;
+            String label = null;
+            byte[] seed = null;
+            int length = 0;
+            byte[] output = null;
 
-        while (true) {
-            String line = reader.readLine();
-            lineNumber++;
-            if (line == null) {
-                break;
-            }
-            if (line.startsWith("prf-") == false) {
-                continue;
-            }
+            while (true) {
+                String line = reader.readLine();
+                lineNumber++;
+                if (line == null) {
+                    break;
+                }
+                if (line.startsWith("prf-") == false) {
+                    continue;
+                }
 
-            String data = line.substring(PREFIX_LENGTH);
-            if (line.startsWith("prf-secret:")) {
-                secret = parse(data);
-            } else if (line.startsWith("prf-label:")) {
-                label = data;
-            } else if (line.startsWith("prf-seed:")) {
-                seed = parse(data);
-            } else if (line.startsWith("prf-length:")) {
-                length = Integer.parseInt(data);
-            } else if (line.startsWith("prf-output:")) {
-                output = parse(data);
+                String data = line.substring(PREFIX_LENGTH);
+                if (line.startsWith("prf-secret:")) {
+                    secret = parse(data);
+                } else if (line.startsWith("prf-label:")) {
+                    label = data;
+                } else if (line.startsWith("prf-seed:")) {
+                    seed = parse(data);
+                } else if (line.startsWith("prf-length:")) {
+                    length = Integer.parseInt(data);
+                } else if (line.startsWith("prf-output:")) {
+                    output = parse(data);
 
-                System.out.print(".");
-                n++;
+                    System.out.print(".");
+                    n++;
 
-                KeyGenerator kg =
-                    KeyGenerator.getInstance("SunTlsPrf", provider);
-                SecretKey inKey;
-                if (secret == null) {
-                    inKey = null;
-                } else {
-                    inKey = new SecretKeySpec(secret, "Generic");
-                }
-                TlsPrfParameterSpec spec =
-                    new TlsPrfParameterSpec(inKey, label, seed, length,
-                        null, -1, -1);
-                SecretKey key;
-                try {
-                    kg.init(spec);
-                    key = kg.generateKey();
-                } catch (Exception e) {
+                    KeyGenerator kg =
+                        KeyGenerator.getInstance("SunTlsPrf", provider);
+                    SecretKey inKey;
                     if (secret == null) {
-                        // This fails on Solaris, but since we never call this
-                        // API for this case in JSSE, ignore the failure.
-                        // (SunJSSE uses the CKM_TLS_KEY_AND_MAC_DERIVE
-                        // mechanism)
-                        System.out.print("X");
-                        continue;
+                        inKey = null;
+                    } else {
+                        inKey = new SecretKeySpec(secret, "Generic");
                     }
-                    System.out.println();
-                    throw new Exception("Error on line: " + lineNumber, e);
+                    TlsPrfParameterSpec spec =
+                        new TlsPrfParameterSpec(inKey, label, seed, length,
+                            null, -1, -1);
+                    SecretKey key;
+                    try {
+                        kg.init(spec);
+                        key = kg.generateKey();
+                    } catch (Exception e) {
+                        if (secret == null) {
+                            // This fails on Solaris, but since we never call this
+                            // API for this case in JSSE, ignore the failure.
+                            // (SunJSSE uses the CKM_TLS_KEY_AND_MAC_DERIVE
+                            // mechanism)
+                            System.out.print("X");
+                            continue;
+                        }
+                        System.out.println();
+                        throw new Exception("Error on line: " + lineNumber, e);
+                    }
+                    byte[] enc = key.getEncoded();
+                    if (Arrays.equals(output, enc) == false) {
+                        System.out.println();
+                        System.out.println("expected: " + toString(output));
+                        System.out.println("actual:   " + toString(enc));
+                        throw new Exception("mismatch line: " + lineNumber);
+                    }
+                } else {
+                    throw new Exception("Unknown line: " + line);
                 }
-                byte[] enc = key.getEncoded();
-                if (Arrays.equals(output, enc) == false) {
-                    System.out.println();
-                    System.out.println("expected: " + toString(output));
-                    System.out.println("actual:   " + toString(enc));
-                    throw new Exception("mismatch line: " + lineNumber);
-                }
-            } else {
-                throw new Exception("Unknown line: " + line);
+            }
+            if (n == 0) {
+                throw new Exception("no tests");
             }
-        }
-        if (n == 0) {
-            throw new Exception("no tests");
+            System.out.println();
+            System.out.println("OK: " + n + " tests");
         }
-        in.close();
-        System.out.println();
-        System.out.println("OK: " + n + " tests");
     }
 
 }
--- a/jdk/test/sun/security/pkcs11/tls/TestPremaster.java	Thu Jan 28 09:43:08 2016 -0800
+++ b/jdk/test/sun/security/pkcs11/tls/TestPremaster.java	Thu Jan 28 15:43:15 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -28,23 +28,22 @@
  * @author Andreas Sterbenz
  * @library ..
  * @modules java.base/sun.security.internal.spec
+ * @run main/othervm TestPremaster
+ * @run main/othervm TestPremaster sm policy
  */
 
-import java.security.Security;
 import java.security.Provider;
-
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
-import java.util.Formatter;
-
 import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
 
 public class TestPremaster extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
-        main(new TestPremaster());
+        main(new TestPremaster(), args);
     }
 
+    @Override
     public void main(Provider provider) throws Exception {
         if (provider.getService(
                 "KeyGenerator", "SunTlsRsaPremasterSecret") == null) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/tls/policy	Thu Jan 28 15:43:15 2016 -0800
@@ -0,0 +1,5 @@
+grant {
+    permission java.lang.RuntimePermission "setSecurityManager";
+    permission java.io.FilePermission "${test.src}/*", "read";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.security.internal.spec";
+};
\ No newline at end of file