changeset 8100:d267c066b006

Merge
author lana
date Fri, 06 Sep 2013 15:09:44 -0700
parents e4ba3d9ea041 (current diff) aafc0f332658 (diff)
children fbb6f976d780
files src/share/classes/sun/misc/Compare.java src/share/classes/sun/misc/Sort.java
diffstat 131 files changed, 6488 insertions(+), 1072 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Sep 05 15:37:40 2013 +0400
+++ b/.hgtags	Fri Sep 06 15:09:44 2013 -0700
@@ -226,3 +226,5 @@
 8ed8e2b4b90e0ac9aa5b3efef51cd576a9db96a9 jdk8-b102
 e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103
 f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104
+1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105
+c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106
--- a/make/com/sun/security/auth/FILES_java.gmk	Thu Sep 05 15:37:40 2013 +0400
+++ b/make/com/sun/security/auth/FILES_java.gmk	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,6 @@
 	com/sun/security/auth/UserPrincipal.java \
 	com/sun/security/auth/LdapPrincipal.java \
 	com/sun/security/auth/PolicyFile.java \
-	com/sun/security/auth/SubjectCodeSource.java \
-	com/sun/security/auth/PolicyParser.java \
 	com/sun/security/auth/PrincipalComparator.java \
 	com/sun/security/auth/callback/TextCallbackHandler.java \
 	com/sun/security/auth/callback/DialogCallbackHandler.java
--- a/makefiles/CopyFiles.gmk	Thu Sep 05 15:37:40 2013 +0400
+++ b/makefiles/CopyFiles.gmk	Fri Sep 06 15:09:44 2013 -0700
@@ -292,8 +292,11 @@
 JVMCFG_DIR := $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_LIBDIR)
 JVMCFG := $(JVMCFG_DIR)/jvm.cfg
 
+# To do: should this also support -zeroshark?
 
-ifeq ($(OPENJDK_TARGET_CPU_BITS),32)
+ifeq ($(OPENJDK_TARGET_CPU_BITS),64)
+  COPY_JVM_CFG_FILE := true
+else
   # On 32-bit machines we have three potential VMs: client, server and minimal.
   # Historically we usually have both client and server and so that is what the
   # committed jvm.cfg expects (including platform specific ergonomics switches
@@ -302,16 +305,21 @@
   # The main problem is deciding whether to use aliases for the VMs that are not
   # present and the current position is that we add aliases for client and server, but
   # not for minimal.
-  # To do: should this also support, -zero and -zeroshark?
-
   CLIENT_AND_SERVER := $(and $(findstring true,$(JVM_VARIANT_SERVER)),$(findstring true,$(JVM_VARIANT_CLIENT)))
+  ifeq ($(CLIENT_AND_SERVER), true)
+    COPY_JVM_CFG_FILE := true
+  else
+    # For zero, the default jvm.cfg file is sufficient
+    ifeq ($(JVM_VARIANT_ZERO), true)
+      COPY_JVM_CFG_FILE := true
+    endif
+  endif
+endif
 
-  ifeq ($(CLIENT_AND_SERVER), true)
-    # Use the committed jvm.cfg for this 32 bit setup (the minimal
-    # VM is already KNOWN on platforms that potentially support it)
+ifeq ($(COPY_JVM_CFG_FILE), true)
     $(JVMCFG): $(JVMCFG_SRC)
 	$(call install-file)
-  else
+else
     $(JVMCFG):
 	$(MKDIR) -p $(@D)
 	$(RM) $(@)
@@ -338,12 +346,6 @@
             endif
         endif
     endif
-  endif
-
-else
-    # Use the default jvm.cfg for this 64 bit setup.
-    $(JVMCFG): $(JVMCFG_SRC)
-	$(call install-file)
 endif
 
 COPY_FILES += $(JVMCFG)
--- a/makefiles/Profiles.gmk	Thu Sep 05 15:37:40 2013 +0400
+++ b/makefiles/Profiles.gmk	Fri Sep 06 15:09:44 2013 -0700
@@ -65,10 +65,6 @@
     $(if $(PROFILE_2_JRE_JAR_FILES), $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_2_JRE_JAR_FILES))) \
     $(PROFILE_1_JARS)
 
-ifneq ($(ENABLE_JFR), true)
-  PROFILE_3_JRE_JAR_FILES :=  $(filter-out jfr.jar, $(PROFILE_3_JRE_JAR_FILES))
-endif
-
 PROFILE_3_JARS := \
     $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_3_JRE_JAR_FILES)) \
     $(PROFILE_2_JARS)
@@ -77,6 +73,10 @@
   FULL_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(FULL_JRE_JAR_FILES))
 endif
 
+ifneq ($(ENABLE_JFR), true)
+  FULL_JRE_JAR_FILES :=  $(filter-out jfr.jar, $(FULL_JRE_JAR_FILES))
+endif
+
 FULL_JRE_JARS := \
     $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(FULL_JRE_JAR_FILES)) \
     $(PROFILE_3_JARS)
--- a/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Fri Sep 06 15:09:44 2013 -0700
@@ -87,6 +87,7 @@
     private int incomingInterruptFD;
 
     static {
+        IOUtil.load();
         initStructSizes();
         String datamodel = java.security.AccessController.doPrivileged(
             new sun.security.action.GetPropertyAction("sun.arch.data.model")
--- a/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -246,9 +246,4 @@
         }
         return this;
     }
-
-
-    static {
-        Util.load();
-    }
 }
--- a/src/share/back/SDE.c	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/back/SDE.c	Fri Sep 06 15:09:44 2013 -0700
@@ -28,6 +28,12 @@
 #include "util.h"
 #include "SDE.h"
 
+#ifdef __APPLE__
+/* use setjmp/longjmp versions that do not save/restore the signal mask */
+#define setjmp _setjmp
+#define longjmp _longjmp
+#endif
+
 /**
  * This SourceDebugExtension code does not
  * allow concurrent translation - due to caching method.
--- a/src/share/classes/com/sun/tools/attach/VirtualMachine.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/com/sun/tools/attach/VirtualMachine.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -59,7 +59,7 @@
  * {@link java.lang.instrument} for a detailed description on how these agents
  * are loaded and started). The {@link #loadAgentLibrary loadAgentLibrary} and
  * {@link #loadAgentPath loadAgentPath} methods are used to load agents that
- * are deployed in a dynamic library and make use of the <a
+ * are deployed either in a dynamic library or statically linked into the VM and make use of the <a
  * href="../../../../../../../../technotes/guides/jvmti/index.html">JVM Tools
  * Interface</a>. </p>
  *
@@ -298,25 +298,29 @@
      * <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM
      * TI</a> client is called an <i>agent</i>. It is developed in a native language.
      * A JVM TI agent is deployed in a platform specific manner but it is typically the
-     * platform equivalent of a dynamic library. This method causes the given agent
-     * library to be loaded into the target VM (if not already loaded).
+     * platform equivalent of a dynamic library. Alternatively, it may be statically linked into the VM.
+     * This method causes the given agent library to be loaded into the target
+     * VM (if not already loaded or if not statically linked into the VM).
      * It then causes the target VM to invoke the <code>Agent_OnAttach</code> function
+     * or, for a statically linked agent named 'L', the <code>Agent_OnAttach_L</code> function
      * as specified in the
      * <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools
-     * Interface</a> specification. Note that the <code>Agent_OnAttach</code>
+     * Interface</a> specification. Note that the <code>Agent_OnAttach[_L]</code>
      * function is invoked even if the agent library was loaded prior to invoking
      * this method.
      *
      * <p> The agent library provided is the name of the agent library. It is interpreted
      * in the target virtual machine in an implementation-dependent manner. Typically an
      * implementation will expand the library name into an operating system specific file
-     * name. For example, on UNIX systems, the name <tt>foo</tt> might be expanded to
-     * <tt>libfoo.so</tt>, and located using the search path specified by the
-     * <tt>LD_LIBRARY_PATH</tt> environment variable.</p>
+     * name. For example, on UNIX systems, the name <tt>L</tt> might be expanded to
+     * <tt>libL.so</tt>, and located using the search path specified by the
+     * <tt>LD_LIBRARY_PATH</tt> environment variable. If the agent named 'L' is
+     * statically linked into the VM then the VM must export a function named
+     * <code>Agent_OnAttach_L</code>.</p>
      *
-     * <p> If the <code>Agent_OnAttach</code> function in the agent library returns
+     * <p> If the <code>Agent_OnAttach[_L]</code> function in the agent library returns
      * an error then an {@link com.sun.tools.attach.AgentInitializationException} is
-     * thrown. The return value from the <code>Agent_OnAttach</code> can then be
+     * thrown. The return value from the <code>Agent_OnAttach[_L]</code> can then be
      * obtained by invoking the {@link
      * com.sun.tools.attach.AgentInitializationException#returnValue() returnValue}
      * method on the exception. </p>
@@ -325,15 +329,16 @@
      *          The name of the agent library.
      *
      * @param   options
-     *          The options to provide to the <code>Agent_OnAttach</code>
+     *          The options to provide to the <code>Agent_OnAttach[_L]</code>
      *          function (can be <code>null</code>).
      *
      * @throws  AgentLoadException
-     *          If the agent library does not exist, or cannot be loaded for
-     *          another reason.
+     *          If the agent library does not exist, the agent library is not
+     *          statically linked with the VM, or the agent library cannot be
+     *          loaded for another reason.
      *
      * @throws  AgentInitializationException
-     *          If the <code>Agent_OnAttach</code> function returns an error
+     *          If the <code>Agent_OnAttach[_L]</code> function returns an error.
      *
      * @throws  IOException
      *          If an I/O error occurs
@@ -359,11 +364,12 @@
      *          The name of the agent library.
      *
      * @throws  AgentLoadException
-     *          If the agent library does not exist, or cannot be loaded for
-     *          another reason.
+     *          If the agent library does not exist, the agent library is not
+     *          statically linked with the VM, or the agent library cannot be
+     *          loaded for another reason.
      *
      * @throws  AgentInitializationException
-     *          If the <code>Agent_OnAttach</code> function returns an error
+     *          If the <code>Agent_OnAttach[_L]</code> function returns an error.
      *
      * @throws  IOException
      *          If an I/O error occurs
@@ -383,12 +389,23 @@
      * <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM
      * TI</a> client is called an <i>agent</i>. It is developed in a native language.
      * A JVM TI agent is deployed in a platform specific manner but it is typically the
-     * platform equivalent of a dynamic library. This method causes the given agent
-     * library to be loaded into the target VM (if not already loaded).
-     * It then causes the target VM to invoke the <code>Agent_OnAttach</code> function
-     * as specified in the
+     * platform equivalent of a dynamic library. Alternatively, the native
+     * library specified by the agentPath parameter may be statically
+     * linked with the VM. The parsing of the agentPath parameter into
+     * a statically linked library name is done in a platform
+     * specific manner in the VM. For example, in UNIX, an agentPath parameter
+     * of <code>/a/b/libL.so</code> would name a library 'L'.
+     *
+     * See the JVM TI Specification for more details.
+     *
+     * This method causes the given agent library to be loaded into the target
+     * VM (if not already loaded or if not statically linked into the VM).
+     * It then causes the target VM to invoke the <code>Agent_OnAttach</code>
+     * function or, for a statically linked agent named 'L', the
+     * <code>Agent_OnAttach_L</code> function as specified in the
      * <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools
-     * Interface</a> specification. Note that the <code>Agent_OnAttach</code>
+     * Interface</a> specification.
+     * Note that the <code>Agent_OnAttach[_L]</code>
      * function is invoked even if the agent library was loaded prior to invoking
      * this method.
      *
@@ -396,9 +413,9 @@
      * agent library. Unlike {@link #loadAgentLibrary loadAgentLibrary}, the library name
      * is not expanded in the target virtual machine. </p>
      *
-     * <p> If the <code>Agent_OnAttach</code> function in the agent library returns
+     * <p> If the <code>Agent_OnAttach[_L]</code> function in the agent library returns
      * an error then an {@link com.sun.tools.attach.AgentInitializationException} is
-     * thrown. The return value from the <code>Agent_OnAttach</code> can then be
+     * thrown. The return value from the <code>Agent_OnAttach[_L]</code> can then be
      * obtained by invoking the {@link
      * com.sun.tools.attach.AgentInitializationException#returnValue() returnValue}
      * method on the exception. </p>
@@ -407,15 +424,16 @@
      *          The full path of the agent library.
      *
      * @param   options
-     *          The options to provide to the <code>Agent_OnAttach</code>
+     *          The options to provide to the <code>Agent_OnAttach[_L]</code>
      *          function (can be <code>null</code>).
      *
      * @throws  AgentLoadException
-     *          If the agent library does not exist, or cannot be loaded for
-     *          another reason.
+     *          If the agent library does not exist, the agent library is not
+     *          statically linked with the VM, or the agent library cannot be
+     *          loaded for another reason.
      *
      * @throws  AgentInitializationException
-     *          If the <code>Agent_OnAttach</code> function returns an error
+     *          If the <code>Agent_OnAttach[_L]</code> function returns an error.
      *
      * @throws  IOException
      *          If an I/O error occurs
@@ -441,11 +459,12 @@
      *          The full path to the agent library.
      *
      * @throws  AgentLoadException
-     *          If the agent library does not exist, or cannot be loaded for
-     *          another reason.
+     *          If the agent library does not exist, the agent library is not
+     *          statically linked with the VM, or the agent library cannot be
+     *          loaded for another reason.
      *
      * @throws  AgentInitializationException
-     *          If the <code>Agent_OnAttach</code> function returns an error
+     *          If the <code>Agent_OnAttach[_L]</code> function returns an error.
      *
      * @throws  IOException
      *          If an I/O error occurs
--- a/src/share/classes/java/io/BufferedInputStream.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/io/BufferedInputStream.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,15 @@
 public
 class BufferedInputStream extends FilterInputStream {
 
-    private static int defaultBufferSize = 8192;
+    private static int DEFAULT_BUFFER_SIZE = 8192;
+
+    /**
+     * The maximum size of array to allocate.
+     * 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 int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
 
     /**
      * The internal buffer array where the data is stored. When necessary,
@@ -172,7 +180,7 @@
      * @param   in   the underlying input stream.
      */
     public BufferedInputStream(InputStream in) {
-        this(in, defaultBufferSize);
+        this(in, DEFAULT_BUFFER_SIZE);
     }
 
     /**
@@ -215,8 +223,11 @@
             } else if (buffer.length >= marklimit) {
                 markpos = -1;   /* buffer got too big, invalidate mark */
                 pos = 0;        /* drop buffer contents */
+            } else if (buffer.length >= MAX_BUFFER_SIZE) {
+                throw new OutOfMemoryError("Required array size too large");
             } else {            /* grow buffer */
-                int nsz = pos * 2;
+                int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
+                        pos * 2 : MAX_BUFFER_SIZE;
                 if (nsz > marklimit)
                     nsz = marklimit;
                 byte nbuf[] = new byte[nsz];
--- a/src/share/classes/java/lang/AbstractStringBuilder.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/lang/AbstractStringBuilder.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1307,7 +1307,7 @@
      * specified substring, starting at the specified index.  The integer
      * returned is the smallest value {@code k} for which:
      * <blockquote><pre>
-     *     k >= Math.min(fromIndex, str.length()) &&
+     *     k >= Math.min(fromIndex, this.length()) &&
      *                   this.toString().startsWith(str, k)
      * </pre></blockquote>
      * If no such value of <i>k</i> exists, then -1 is returned.
@@ -1346,7 +1346,7 @@
      * specified substring. The integer returned is the largest value <i>k</i>
      * such that:
      * <blockquote><pre>
-     *     k <= Math.min(fromIndex, str.length()) &&
+     *     k <= Math.min(fromIndex, this.length()) &&
      *                   this.toString().startsWith(str, k)
      * </pre></blockquote>
      * If no such value of <i>k</i> exists, then -1 is returned.
--- a/src/share/classes/java/lang/Class.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/lang/Class.java	Fri Sep 06 15:09:44 2013 -0700
@@ -3338,8 +3338,16 @@
      * @since 1.8
      */
     public AnnotatedType getAnnotatedSuperclass() {
-         return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this);
-}
+        if (this == Object.class ||
+                isInterface() ||
+                isArray() ||
+                isPrimitive() ||
+                this == Void.TYPE) {
+            return null;
+        }
+
+        return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this);
+    }
 
     /**
      * Returns an array of AnnotatedType objects that represent the use of types to
--- a/src/share/classes/java/lang/Math.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/lang/Math.java	Fri Sep 06 15:09:44 2013 -0700
@@ -698,11 +698,8 @@
             return 0;
     }
 
-    private static Random randomNumberGenerator;
-
-    private static synchronized Random initRNG() {
-        Random rnd = randomNumberGenerator;
-        return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
+    private static final class RandomNumberGeneratorHolder {
+        static final Random randomNumberGenerator = new Random();
     }
 
     /**
@@ -729,9 +726,7 @@
      * @see Random#nextDouble()
      */
     public static double random() {
-        Random rnd = randomNumberGenerator;
-        if (rnd == null) rnd = initRNG();
-        return rnd.nextDouble();
+        return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
     }
 
     /**
--- a/src/share/classes/java/lang/ProcessBuilder.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/lang/ProcessBuilder.java	Fri Sep 06 15:09:44 2013 -0700
@@ -29,7 +29,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.security.AccessControlException;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
@@ -1033,9 +1032,9 @@
                 // Can not disclose the fail reason for read-protected files.
                 try {
                     security.checkRead(prog);
-                } catch (AccessControlException ace) {
+                } catch (SecurityException se) {
                     exceptionInfo = "";
-                    cause = ace;
+                    cause = se;
                 }
             }
             // It's much easier for us to create a high-quality error
--- a/src/share/classes/java/lang/StrictMath.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/lang/StrictMath.java	Fri Sep 06 15:09:44 2013 -0700
@@ -678,11 +678,8 @@
         return Math.round(a);
     }
 
-    private static Random randomNumberGenerator;
-
-    private static synchronized Random initRNG() {
-        Random rnd = randomNumberGenerator;
-        return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
+    private static final class RandomNumberGeneratorHolder {
+        static final Random randomNumberGenerator = new Random();
     }
 
     /**
@@ -709,9 +706,7 @@
      * @see Random#nextDouble()
      */
     public static double random() {
-        Random rnd = randomNumberGenerator;
-        if (rnd == null) rnd = initRNG();
-        return rnd.nextDouble();
+        return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
     }
 
     /**
--- a/src/share/classes/java/math/BigDecimal.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/math/BigDecimal.java	Fri Sep 06 15:09:44 2013 -0700
@@ -2659,28 +2659,32 @@
         if (ys == 0)
             return 1;
 
-        int sdiff = this.scale - val.scale;
+        long sdiff = (long)this.scale - val.scale;
         if (sdiff != 0) {
             // Avoid matching scales if the (adjusted) exponents differ
-            int xae = this.precision() - this.scale;   // [-1]
-            int yae = val.precision() - val.scale;     // [-1]
+            long xae = (long)this.precision() - this.scale;   // [-1]
+            long yae = (long)val.precision() - val.scale;     // [-1]
             if (xae < yae)
                 return -1;
             if (xae > yae)
                 return 1;
             BigInteger rb = null;
             if (sdiff < 0) {
-                if ( (xs == INFLATED ||
-                      (xs = longMultiplyPowerTen(xs, -sdiff)) == INFLATED) &&
+                // The cases sdiff <= Integer.MIN_VALUE intentionally fall through.
+                if ( sdiff > Integer.MIN_VALUE &&
+                      (xs == INFLATED ||
+                      (xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) &&
                      ys == INFLATED) {
-                    rb = bigMultiplyPowerTen(-sdiff);
+                    rb = bigMultiplyPowerTen((int)-sdiff);
                     return rb.compareMagnitude(val.intVal);
                 }
             } else { // sdiff > 0
-                if ( (ys == INFLATED ||
-                      (ys = longMultiplyPowerTen(ys, sdiff)) == INFLATED) &&
+                // The cases sdiff > Integer.MAX_VALUE intentionally fall through.
+                if ( sdiff <= Integer.MAX_VALUE &&
+                      (ys == INFLATED ||
+                      (ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) &&
                      xs == INFLATED) {
-                    rb = val.bigMultiplyPowerTen(sdiff);
+                    rb = val.bigMultiplyPowerTen((int)sdiff);
                     return this.intVal.compareMagnitude(rb);
                 }
             }
@@ -4545,7 +4549,7 @@
         if(cmp > 0) { // satisfy constraint (b)
             yscale -= 1; // [that is, divisor *= 10]
             int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
-            if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+            if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
                 // assert newScale >= xscale
                 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
                 long scaledXs;
@@ -4626,7 +4630,7 @@
         // return BigDecimal object whose scale will be set to 'scl'.
         int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
         BigDecimal quotient;
-        if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+        if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
             int raise = checkScaleNonZero((long) mcp + yscale - xscale);
             long scaledXs;
             if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
@@ -4673,7 +4677,7 @@
         // return BigDecimal object whose scale will be set to 'scl'.
         BigDecimal quotient;
         int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
-        if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+        if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
             int raise = checkScaleNonZero((long) mcp + yscale - xscale);
             BigInteger rb = bigMultiplyPowerTen(xs,raise);
             quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
@@ -4714,7 +4718,7 @@
         // return BigDecimal object whose scale will be set to 'scl'.
         BigDecimal quotient;
         int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
-        if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+        if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
             int raise = checkScaleNonZero((long) mcp + yscale - xscale);
             BigInteger rb = bigMultiplyPowerTen(xs,raise);
             quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
@@ -4745,7 +4749,7 @@
         // return BigDecimal object whose scale will be set to 'scl'.
         BigDecimal quotient;
         int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
-        if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+        if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
             int raise = checkScaleNonZero((long) mcp + yscale - xscale);
             BigInteger rb = bigMultiplyPowerTen(xs,raise);
             quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
--- a/src/share/classes/java/math/BigInteger.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/math/BigInteger.java	Fri Sep 06 15:09:44 2013 -0700
@@ -2109,7 +2109,7 @@
         // This is a quick way to approximate the size of the result,
         // similar to doing log2[n] * exponent.  This will give an upper bound
         // of how big the result can be, and which algorithm to use.
-        int scaleFactor = remainingBits * exponent;
+        long scaleFactor = (long)remainingBits * exponent;
 
         // Use slightly different algorithms for small and large operands.
         // See if the result will safely fit into a long. (Largest 2^63-1)
--- a/src/share/classes/java/rmi/server/RMISocketFactory.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/rmi/server/RMISocketFactory.java	Fri Sep 06 15:09:44 2013 -0700
@@ -50,13 +50,13 @@
  * @implNote
  * <p>You can use the {@code RMISocketFactory} class to create a server socket that
  * is bound to a specific address, restricting the origin of requests. For example,
- * the following code implements a socket factory that binds server sockets to the
+ * the following code implements a socket factory that binds server sockets to an IPv4
  * loopback address. This restricts RMI to processing requests only from the local host.
  *
  * <pre>{@code
  *     class LoopbackSocketFactory extends RMISocketFactory {
  *         public ServerSocket createServerSocket(int port) throws IOException {
- *             return new ServerSocket(port, 5, InetAddress.getLoopbackAddress());
+ *             return new ServerSocket(port, 5, InetAddress.getByName("127.0.0.1"));
  *         }
  *
  *         public Socket createSocket(String host, int port) throws IOException {
@@ -72,8 +72,8 @@
  * }</pre>
  *
  * Set the {@code java.rmi.server.hostname} system property
- * to a host name (typically {@code localhost}) that resolves to the loopback
- * interface to ensure that the generated stubs use the right network interface.
+ * to {@code 127.0.0.1} to ensure that the generated stubs connect to the right
+ * network interface.
  *
  * @author  Ann Wollrath
  * @author  Peter Jones
--- a/src/share/classes/java/util/Collections.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/Collections.java	Fri Sep 06 15:09:44 2013 -0700
@@ -27,7 +27,6 @@
 import java.io.Serializable;
 import java.io.ObjectOutputStream;
 import java.io.IOException;
-import java.io.InvalidObjectException;
 import java.lang.reflect.Array;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
@@ -35,6 +34,7 @@
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
+import java.util.stream.IntStream;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
@@ -1148,7 +1148,16 @@
         public Spliterator<E> spliterator() {
             return (Spliterator<E>)c.spliterator();
         }
-
+        @SuppressWarnings("unchecked")
+        @Override
+        public Stream<E> stream() {
+            return (Stream<E>)c.stream();
+        }
+        @SuppressWarnings("unchecked")
+        @Override
+        public Stream<E> parallelStream() {
+            return (Stream<E>)c.parallelStream();
+        }
     }
 
     /**
@@ -2009,8 +2018,8 @@
      * through the returned collection.<p>
      *
      * It is imperative that the user manually synchronize on the returned
-     * collection when traversing it via {@link Iterator} or
-     * {@link Spliterator}:
+     * collection when traversing it via {@link Iterator}, {@link Spliterator}
+     * or {@link Stream}:
      * <pre>
      *  Collection c = Collections.synchronizedCollection(myCollection);
      *     ...
@@ -2120,6 +2129,14 @@
         public Spliterator<E> spliterator() {
             return c.spliterator(); // Must be manually synched by user!
         }
+        @Override
+        public Stream<E> stream() {
+            return c.stream(); // Must be manually synched by user!
+        }
+        @Override
+        public Stream<E> parallelStream() {
+            return c.parallelStream(); // Must be manually synched by user!
+        }
         private void writeObject(ObjectOutputStream s) throws IOException {
             synchronized (mutex) {s.defaultWriteObject();}
         }
@@ -3172,6 +3189,10 @@
         }
         @Override
         public Spliterator<E> spliterator() {return c.spliterator();}
+        @Override
+        public Stream<E> stream()           {return c.stream();}
+        @Override
+        public Stream<E> parallelStream()   {return c.parallelStream();}
     }
 
     /**
@@ -5096,6 +5117,22 @@
                                                    ") > toIndex(" + toIndex + ")");
             return new CopiesList<>(toIndex - fromIndex, element);
         }
+
+        // Override default methods in Collection
+        @Override
+        public Stream<E> stream() {
+            return IntStream.range(0, n).mapToObj(i -> element);
+        }
+
+        @Override
+        public Stream<E> parallelStream() {
+            return IntStream.range(0, n).parallel().mapToObj(i -> element);
+        }
+
+        @Override
+        public Spliterator<E> spliterator() {
+            return stream().spliterator();
+        }
     }
 
     /**
@@ -5503,6 +5540,10 @@
 
         @Override
         public Spliterator<E> spliterator() {return s.spliterator();}
+        @Override
+        public Stream<E> stream()           {return s.stream();}
+        @Override
+        public Stream<E> parallelStream()   {return s.parallelStream();}
 
         private static final long serialVersionUID = 2454657854757543876L;
 
@@ -5568,10 +5609,14 @@
         @Override
         public void forEach(Consumer<? super E> action) {q.forEach(action);}
         @Override
-        public Spliterator<E> spliterator() {return q.spliterator();}
-        @Override
         public boolean removeIf(Predicate<? super E> filter) {
             return q.removeIf(filter);
         }
+        @Override
+        public Spliterator<E> spliterator() {return q.spliterator();}
+        @Override
+        public Stream<E> stream()           {return q.stream();}
+        @Override
+        public Stream<E> parallelStream()   {return q.parallelStream();}
     }
 }
--- a/src/share/classes/java/util/ComparableTimSort.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/ComparableTimSort.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Google Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -146,7 +147,7 @@
          */
         int stackLen = (len <    120  ?  5 :
                         len <   1542  ? 10 :
-                        len < 119151  ? 19 : 40);
+                        len < 119151  ? 24 : 40);
         runBase = new int[stackLen];
         runLen = new int[stackLen];
     }
--- a/src/share/classes/java/util/Comparator.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/Comparator.java	Fri Sep 06 15:09:44 2013 -0700
@@ -199,7 +199,7 @@
      * composed using following code,
      *
      * <pre>{@code
-     *     Comparator<String> cmp = Comparator.comparing(String::length)
+     *     Comparator<String> cmp = Comparator.comparingInt(String::length)
      *             .thenComparing(String.CASE_INSENSITIVE_ORDER);
      * }</pre>
      *
@@ -270,18 +270,18 @@
      * extracts a {@code int} sort key.
      *
      * @implSpec This default implementation behaves as if {@code
-     *           thenComparing(comparing(keyExtractor))}.
+     *           thenComparing(comparingInt(keyExtractor))}.
      *
      * @param  keyExtractor the function used to extract the integer sort key
      * @return a lexicographic-order comparator composed of this and then the
      *         {@code int} sort key
      * @throws NullPointerException if the argument is null.
-     * @see #comparing(ToIntFunction)
+     * @see #comparingInt(ToIntFunction)
      * @see #thenComparing(Comparator)
      * @since 1.8
      */
-    default Comparator<T> thenComparing(ToIntFunction<? super T> keyExtractor) {
-        return thenComparing(comparing(keyExtractor));
+    default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
+        return thenComparing(comparingInt(keyExtractor));
     }
 
     /**
@@ -289,18 +289,18 @@
      * extracts a {@code long} sort key.
      *
      * @implSpec This default implementation behaves as if {@code
-     *           thenComparing(comparing(keyExtractor))}.
+     *           thenComparing(comparingLong(keyExtractor))}.
      *
      * @param  keyExtractor the function used to extract the long sort key
      * @return a lexicographic-order comparator composed of this and then the
      *         {@code long} sort key
      * @throws NullPointerException if the argument is null.
-     * @see #comparing(ToLongFunction)
+     * @see #comparingLong(ToLongFunction)
      * @see #thenComparing(Comparator)
      * @since 1.8
      */
-    default Comparator<T> thenComparing(ToLongFunction<? super T> keyExtractor) {
-        return thenComparing(comparing(keyExtractor));
+    default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
+        return thenComparing(comparingLong(keyExtractor));
     }
 
     /**
@@ -308,18 +308,18 @@
      * extracts a {@code double} sort key.
      *
      * @implSpec This default implementation behaves as if {@code
-     *           thenComparing(comparing(keyExtractor))}.
+     *           thenComparing(comparingDouble(keyExtractor))}.
      *
      * @param  keyExtractor the function used to extract the double sort key
      * @return a lexicographic-order comparator composed of this and then the
      *         {@code double} sort key
      * @throws NullPointerException if the argument is null.
-     * @see #comparing(ToDoubleFunction)
+     * @see #comparingDouble(ToDoubleFunction)
      * @see #thenComparing(Comparator)
      * @since 1.8
      */
-    default Comparator<T> thenComparing(ToDoubleFunction<? super T> keyExtractor) {
-        return thenComparing(comparing(keyExtractor));
+    default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
+        return thenComparing(comparingDouble(keyExtractor));
     }
 
     /**
@@ -484,7 +484,7 @@
      * @throws NullPointerException if the argument is null
      * @since 1.8
      */
-    public static <T> Comparator<T> comparing(ToIntFunction<? super T> keyExtractor) {
+    public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
         Objects.requireNonNull(keyExtractor);
         return (Comparator<T> & Serializable)
             (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
@@ -505,7 +505,7 @@
      * @throws NullPointerException if the argument is null
      * @since 1.8
      */
-    public static <T> Comparator<T> comparing(ToLongFunction<? super T> keyExtractor) {
+    public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
         Objects.requireNonNull(keyExtractor);
         return (Comparator<T> & Serializable)
             (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
@@ -526,7 +526,7 @@
      * @throws NullPointerException if the argument is null
      * @since 1.8
      */
-    public static<T> Comparator<T> comparing(ToDoubleFunction<? super T> keyExtractor) {
+    public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
         Objects.requireNonNull(keyExtractor);
         return (Comparator<T> & Serializable)
             (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
--- a/src/share/classes/java/util/Random.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/Random.java	Fri Sep 06 15:09:44 2013 -0700
@@ -26,9 +26,13 @@
 package java.util;
 import java.io.*;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
 import java.util.stream.DoubleStream;
 import java.util.stream.IntStream;
 import java.util.stream.LongStream;
+import java.util.stream.StreamSupport;
 
 import sun.misc.Unsafe;
 
@@ -85,6 +89,13 @@
     private static final long addend = 0xBL;
     private static final long mask = (1L << 48) - 1;
 
+    private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
+
+    // IllegalArgumentException messages
+    static final String BadBound = "bound must be positive";
+    static final String BadRange = "bound must be greater than origin";
+    static final String BadSize  = "size must be non-negative";
+
     /**
      * Creates a new random number generator. This constructor sets
      * the seed of the random number generator to a value very likely
@@ -222,6 +233,82 @@
     }
 
     /**
+     * The form of nextLong used by LongStream Spliterators.  If
+     * origin is greater than bound, acts as unbounded form of
+     * nextLong, else as bounded form.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final long internalNextLong(long origin, long bound) {
+        long r = nextLong();
+        if (origin < bound) {
+            long n = bound - origin, m = n - 1;
+            if ((n & m) == 0L)  // power of two
+                r = (r & m) + origin;
+            else if (n > 0L) {  // reject over-represented candidates
+                for (long u = r >>> 1;            // ensure nonnegative
+                     u + m - (r = u % n) < 0L;    // rejection check
+                     u = nextLong() >>> 1) // retry
+                    ;
+                r += origin;
+            }
+            else {              // range not representable as long
+                while (r < origin || r >= bound)
+                    r = nextLong();
+            }
+        }
+        return r;
+    }
+
+    /**
+     * The form of nextInt used by IntStream Spliterators.
+     * For the unbounded case: uses nextInt().
+     * For the bounded case with representable range: uses nextInt(int bound)
+     * For the bounded case with unrepresentable range: uses nextInt()
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final int internalNextInt(int origin, int bound) {
+        if (origin < bound) {
+            int n = bound - origin;
+            if (n > 0) {
+                return nextInt(n) + origin;
+            }
+            else {  // range not representable as int
+                int r;
+                do {
+                    r = nextInt();
+                } while (r < origin || r >= bound);
+                return r;
+            }
+        }
+        else {
+            return nextInt();
+        }
+    }
+
+    /**
+     * The form of nextDouble used by DoubleStream Spliterators.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final double internalNextDouble(double origin, double bound) {
+        double r = nextDouble();
+        if (origin < bound) {
+            r = r * (bound - origin) + origin;
+            if (r >= bound) // correct for rounding
+                r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+        }
+        return r;
+    }
+
+    /**
      * Returns the next pseudorandom, uniformly distributed {@code int}
      * value from this random number generator's sequence. The general
      * contract of {@code nextInt} is that one {@code int} value is
@@ -247,23 +334,23 @@
      * between 0 (inclusive) and the specified value (exclusive), drawn from
      * this random number generator's sequence.  The general contract of
      * {@code nextInt} is that one {@code int} value in the specified range
-     * is pseudorandomly generated and returned.  All {@code n} possible
+     * is pseudorandomly generated and returned.  All {@code bound} possible
      * {@code int} values are produced with (approximately) equal
-     * probability.  The method {@code nextInt(int n)} is implemented by
+     * probability.  The method {@code nextInt(int bound)} is implemented by
      * class {@code Random} as if by:
      *  <pre> {@code
-     * public int nextInt(int n) {
-     *   if (n <= 0)
-     *     throw new IllegalArgumentException("n must be positive");
+     * public int nextInt(int bound) {
+     *   if (bound <= 0)
+     *     throw new IllegalArgumentException("bound must be positive");
      *
-     *   if ((n & -n) == n)  // i.e., n is a power of 2
-     *     return (int)((n * (long)next(31)) >> 31);
+     *   if ((bound & -bound) == bound)  // i.e., bound is a power of 2
+     *     return (int)((bound * (long)next(31)) >> 31);
      *
      *   int bits, val;
      *   do {
      *       bits = next(31);
-     *       val = bits % n;
-     *   } while (bits - val + (n-1) < 0);
+     *       val = bits % bound;
+     *   } while (bits - val + (bound-1) < 0);
      *   return val;
      * }}</pre>
      *
@@ -289,28 +376,28 @@
      * greatly increases the length of the sequence of values returned by
      * successive calls to this method if n is a small power of two.
      *
-     * @param n the bound on the random number to be returned.  Must be
-     *        positive.
+     * @param bound the upper bound (exclusive).  Must be positive.
      * @return the next pseudorandom, uniformly distributed {@code int}
-     *         value between {@code 0} (inclusive) and {@code n} (exclusive)
+     *         value between zero (inclusive) and {@code bound} (exclusive)
      *         from this random number generator's sequence
-     * @throws IllegalArgumentException if n is not positive
+     * @throws IllegalArgumentException if bound is not positive
      * @since 1.2
      */
-
-    public int nextInt(int n) {
-        if (n <= 0)
-            throw new IllegalArgumentException("n must be positive");
+    public int nextInt(int bound) {
+        if (bound <= 0)
+            throw new IllegalArgumentException(BadBound);
 
-        if ((n & -n) == n)  // i.e., n is a power of 2
-            return (int)((n * (long)next(31)) >> 31);
-
-        int bits, val;
-        do {
-            bits = next(31);
-            val = bits % n;
-        } while (bits - val + (n-1) < 0);
-        return val;
+        int r = next(31);
+        int m = bound - 1;
+        if ((bound & m) == 0)  // i.e., bound is a power of 2
+            r = (int)((bound * (long)r) >> 31);
+        else {
+            for (int u = r;
+                 u - (r = u % bound) + m < 0;
+                 u = next(31))
+                ;
+        }
+        return r;
     }
 
     /**
@@ -442,8 +529,7 @@
      * @see Math#random
      */
     public double nextDouble() {
-        return (((long)(next(26)) << 27) + next(27))
-            / (double)(1L << 53);
+        return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
     }
 
     private double nextNextGaussian;
@@ -513,57 +599,563 @@
         }
     }
 
+    // stream methods, coded in a way intended to better isolate for
+    // maintenance purposes the small differences across forms.
+
     /**
-     * Returns a stream of pseudorandom, uniformly distributed
-     * {@code integer} values from this random number generator's
-     * sequence. Values are obtained as needed by calling
-     * {@link #nextInt()}.
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code int} values.
+     *
+     * <p>A pseudorandom {@code int} value is generated as if it's the result of
+     * calling the method {@link #nextInt()}.
      *
-     * @return an infinite stream of {@code integer} values
+     * @param streamSize the number of values to generate
+     * @return a stream of pseudorandom {@code int} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @since 1.8
+     */
+    public IntStream ints(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        return StreamSupport.intStream
+                (new RandomIntsSpliterator
+                         (this, 0L, streamSize, Integer.MAX_VALUE, 0),
+                 false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code int}
+     * values.
+     *
+     * <p>A pseudorandom {@code int} value is generated as if it's the result of
+     * calling the method {@link #nextInt()}.
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * ints(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code int} values
      * @since 1.8
      */
     public IntStream ints() {
-        return IntStream.generate(this::nextInt);
+        return StreamSupport.intStream
+                (new RandomIntsSpliterator
+                         (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
+                 false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number
+     * of pseudorandom {@code int} values, each conforming to the given
+     * origin (inclusive) and bound (exclusive).
+     *
+     * <p>A pseudorandom {@code int} value is generated as if it's the result of
+     * calling the following method with the origin and bound:
+     * <pre> {@code
+     * int nextInt(int origin, int bound) {
+     *   int n = bound - origin;
+     *   if (n > 0) {
+     *     return nextInt(n) + origin;
+     *   }
+     *   else {  // range not representable as int
+     *     int r;
+     *     do {
+     *       r = nextInt();
+     *     } while (r < origin || r >= bound);
+     *     return r;
+     *   }
+     * }}</pre>
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code int} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero, or {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public IntStream ints(long streamSize, int randomNumberOrigin,
+                          int randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.intStream
+                (new RandomIntsSpliterator
+                         (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+                 false);
     }
 
     /**
-     * Returns a stream of pseudorandom, uniformly distributed
-     * {@code long} values from this random number generator's
-     * sequence. Values are obtained as needed by calling
-     * {@link #nextLong()}.
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * int} values, each conforming to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * <p>A pseudorandom {@code int} value is generated as if it's the result of
+     * calling the following method with the origin and bound:
+     * <pre> {@code
+     * int nextInt(int origin, int bound) {
+     *   int n = bound - origin;
+     *   if (n > 0) {
+     *     return nextInt(n) + origin;
+     *   }
+     *   else {  // range not representable as int
+     *     int r;
+     *     do {
+     *       r = nextInt();
+     *     } while (r < origin || r >= bound);
+     *     return r;
+     *   }
+     * }}</pre>
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
      *
-     * @return an infinite stream of {@code long} values
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code int} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.intStream
+                (new RandomIntsSpliterator
+                         (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+                 false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code long} values.
+     *
+     * <p>A pseudorandom {@code long} value is generated as if it's the result
+     * of calling the method {@link #nextLong()}.
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of pseudorandom {@code long} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @since 1.8
+     */
+    public LongStream longs(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        return StreamSupport.longStream
+                (new RandomLongsSpliterator
+                         (this, 0L, streamSize, Long.MAX_VALUE, 0L),
+                 false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code long}
+     * values.
+     *
+     * <p>A pseudorandom {@code long} value is generated as if it's the result
+     * of calling the method {@link #nextLong()}.
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * longs(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code long} values
      * @since 1.8
      */
     public LongStream longs() {
-        return LongStream.generate(this::nextLong);
+        return StreamSupport.longStream
+                (new RandomLongsSpliterator
+                         (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
+                 false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code long}, each conforming to the given origin
+     * (inclusive) and bound (exclusive).
+     *
+     * <p>A pseudorandom {@code long} value is generated as if it's the result
+     * of calling the following method with the origin and bound:
+     * <pre> {@code
+     * long nextLong(long origin, long bound) {
+     *   long r = nextLong();
+     *   long n = bound - origin, m = n - 1;
+     *   if ((n & m) == 0L)  // power of two
+     *     r = (r & m) + origin;
+     *   else if (n > 0L) {  // reject over-represented candidates
+     *     for (long u = r >>> 1;            // ensure nonnegative
+     *          u + m - (r = u % n) < 0L;    // rejection check
+     *          u = nextLong() >>> 1) // retry
+     *         ;
+     *     r += origin;
+     *   }
+     *   else {              // range not representable as long
+     *     while (r < origin || r >= bound)
+     *       r = nextLong();
+     *   }
+     *   return r;
+     * }}</pre>
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code long} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero, or {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public LongStream longs(long streamSize, long randomNumberOrigin,
+                            long randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.longStream
+                (new RandomLongsSpliterator
+                         (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+                 false);
     }
 
     /**
-     * Returns a stream of pseudorandom, uniformly distributed
-     * {@code double} values between {@code 0.0} and {@code 1.0}
-     * from this random number generator's sequence. Values are
-     * obtained as needed by calling {@link #nextDouble()}.
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * long} values, each conforming to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * <p>A pseudorandom {@code long} value is generated as if it's the result
+     * of calling the following method with the origin and bound:
+     * <pre> {@code
+     * long nextLong(long origin, long bound) {
+     *   long r = nextLong();
+     *   long n = bound - origin, m = n - 1;
+     *   if ((n & m) == 0L)  // power of two
+     *     r = (r & m) + origin;
+     *   else if (n > 0L) {  // reject over-represented candidates
+     *     for (long u = r >>> 1;            // ensure nonnegative
+     *          u + m - (r = u % n) < 0L;    // rejection check
+     *          u = nextLong() >>> 1) // retry
+     *         ;
+     *     r += origin;
+     *   }
+     *   else {              // range not representable as long
+     *     while (r < origin || r >= bound)
+     *       r = nextLong();
+     *   }
+     *   return r;
+     * }}</pre>
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
      *
-     * @return an infinite stream of {@code double} values
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code long} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.longStream
+                (new RandomLongsSpliterator
+                         (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+                 false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code double} values, each between zero
+     * (inclusive) and one (exclusive).
+     *
+     * <p>A pseudorandom {@code double} value is generated as if it's the result
+     * of calling the method {@link #nextDouble()}}.
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of {@code double} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @since 1.8
+     */
+    public DoubleStream doubles(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        return StreamSupport.doubleStream
+                (new RandomDoublesSpliterator
+                         (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
+                 false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * double} values, each between zero (inclusive) and one
+     * (exclusive).
+     *
+     * <p>A pseudorandom {@code double} value is generated as if it's the result
+     * of calling the method {@link #nextDouble()}}.
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * doubles(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code double} values
      * @since 1.8
      */
     public DoubleStream doubles() {
-        return DoubleStream.generate(this::nextDouble);
+        return StreamSupport.doubleStream
+                (new RandomDoublesSpliterator
+                         (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
+                 false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code double} values, each conforming to the given origin
+     * (inclusive) and bound (exclusive).
+     *
+     * <p>A pseudorandom {@code double} value is generated as if it's the result
+     * of calling the following method with the origin and bound:
+     * <pre> {@code
+     * double nextDouble(double origin, double bound) {
+     *   double r = nextDouble();
+     *   r = r * (bound - origin) + origin;
+     *   if (r >= bound) // correct for rounding
+     *     r = Math.nextDown(bound);
+     *   return r;
+     * }}</pre>
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code double} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public DoubleStream doubles(long streamSize, double randomNumberOrigin,
+                                double randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        if (!(randomNumberOrigin < randomNumberBound))
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.doubleStream
+                (new RandomDoublesSpliterator
+                         (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+                 false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * double} values, each conforming to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * <p>A pseudorandom {@code double} value is generated as if it's the result
+     * of calling the following method with the origin and bound:
+     * <pre> {@code
+     * double nextDouble(double origin, double bound) {
+     *   double r = nextDouble();
+     *   r = r * (bound - origin) + origin;
+     *   if (r >= bound) // correct for rounding
+     *     r = Math.nextDown(bound);
+     *   return r;
+     * }}</pre>
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code double} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+        if (!(randomNumberOrigin < randomNumberBound))
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.doubleStream
+                (new RandomDoublesSpliterator
+                         (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+                 false);
     }
 
     /**
-     * Returns a stream of pseudorandom, Gaussian ("normally")
-     * distributed {@code double} values with mean {@code 0.0}
-     * and standard deviation {@code 1.0} from this random number
-     * generator's sequence. Values are obtained as needed by
-     * calling {@link #nextGaussian()}.
-     *
-     * @return an infinite stream of {@code double} values
-     * @since 1.8
+     * Spliterator for int streams.  We multiplex the four int
+     * versions into one class by treating a bound less than origin as
+     * unbounded, and also by treating "infinite" as equivalent to
+     * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
+     * approach. The long and double versions of this class are
+     * identical except for types.
+     */
+    static final class RandomIntsSpliterator implements Spliterator.OfInt {
+        final Random rng;
+        long index;
+        final long fence;
+        final int origin;
+        final int bound;
+        RandomIntsSpliterator(Random rng, long index, long fence,
+                              int origin, int bound) {
+            this.rng = rng; this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomIntsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                   new RandomIntsSpliterator(rng, i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rng.internalNextInt(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                Random r = rng;
+                int o = origin, b = bound;
+                do {
+                    consumer.accept(r.internalNextInt(o, b));
+                } while (++i < f);
+            }
+        }
+    }
+
+    /**
+     * Spliterator for long streams.
      */
-    public DoubleStream gaussians() {
-        return DoubleStream.generate(this::nextGaussian);
+    static final class RandomLongsSpliterator implements Spliterator.OfLong {
+        final Random rng;
+        long index;
+        final long fence;
+        final long origin;
+        final long bound;
+        RandomLongsSpliterator(Random rng, long index, long fence,
+                               long origin, long bound) {
+            this.rng = rng; this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomLongsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                   new RandomLongsSpliterator(rng, i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rng.internalNextLong(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                Random r = rng;
+                long o = origin, b = bound;
+                do {
+                    consumer.accept(r.internalNextLong(o, b));
+                } while (++i < f);
+            }
+        }
+
+    }
+
+    /**
+     * Spliterator for double streams.
+     */
+    static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
+        final Random rng;
+        long index;
+        final long fence;
+        final double origin;
+        final double bound;
+        RandomDoublesSpliterator(Random rng, long index, long fence,
+                                 double origin, double bound) {
+            this.rng = rng; this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomDoublesSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                   new RandomDoublesSpliterator(rng, i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rng.internalNextDouble(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                Random r = rng;
+                double o = origin, b = bound;
+                do {
+                    consumer.accept(r.internalNextDouble(o, b));
+                } while (++i < f);
+            }
+        }
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/SplittableRandom.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,1002 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util;
+
+import java.security.SecureRandom;
+import java.net.InetAddress;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.function.DoubleConsumer;
+import java.util.stream.StreamSupport;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.DoubleStream;
+
+/**
+ * A generator of uniform pseudorandom values applicable for use in
+ * (among other contexts) isolated parallel computations that may
+ * generate subtasks. Class {@code SplittableRandom} supports methods for
+ * producing pseudorandom numbers of type {@code int}, {@code long},
+ * and {@code double} with similar usages as for class
+ * {@link java.util.Random} but differs in the following ways:
+ *
+ * <ul>
+ *
+ * <li>Series of generated values pass the DieHarder suite testing
+ * independence and uniformity properties of random number generators.
+ * (Most recently validated with <a
+ * href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version
+ * 3.31.1</a>.) These tests validate only the methods for certain
+ * types and ranges, but similar properties are expected to hold, at
+ * least approximately, for others as well. The <em>period</em>
+ * (length of any series of generated values before it repeats) is at
+ * least 2<sup>64</sup>. </li>
+ *
+ * <li> Method {@link #split} constructs and returns a new
+ * SplittableRandom instance that shares no mutable state with the
+ * current instance. However, with very high probability, the
+ * values collectively generated by the two objects have the same
+ * statistical properties as if the same quantity of values were
+ * generated by a single thread using a single {@code
+ * SplittableRandom} object.  </li>
+ *
+ * <li>Instances of SplittableRandom are <em>not</em> thread-safe.
+ * They are designed to be split, not shared, across threads. For
+ * example, a {@link java.util.concurrent.ForkJoinTask
+ * fork/join-style} computation using random numbers might include a
+ * construction of the form {@code new
+ * Subtask(aSplittableRandom.split()).fork()}.
+ *
+ * <li>This class provides additional methods for generating random
+ * streams, that employ the above techniques when used in {@code
+ * stream.parallel()} mode.</li>
+ *
+ * </ul>
+ *
+ * <p>Instances of {@code SplittableRandom} are not cryptographically
+ * secure.  Consider instead using {@link java.security.SecureRandom}
+ * in security-sensitive applications. Additionally,
+ * default-constructed instances do not use a cryptographically random
+ * seed unless the {@linkplain System#getProperty system property}
+ * {@code java.util.secureRandomSeed} is set to {@code true}.
+ *
+ * @author  Guy Steele
+ * @author  Doug Lea
+ * @since   1.8
+ */
+public final class SplittableRandom {
+
+    /*
+     * Implementation Overview.
+     *
+     * This algorithm was inspired by the "DotMix" algorithm by
+     * Leiserson, Schardl, and Sukha "Deterministic Parallel
+     * Random-Number Generation for Dynamic-Multithreading Platforms",
+     * PPoPP 2012, as well as those in "Parallel random numbers: as
+     * easy as 1, 2, 3" by Salmon, Morae, Dror, and Shaw, SC 2011.  It
+     * differs mainly in simplifying and cheapening operations.
+     *
+     * The primary update step (method nextSeed()) is to add a
+     * constant ("gamma") to the current (64 bit) seed, forming a
+     * simple sequence.  The seed and the gamma values for any two
+     * SplittableRandom instances are highly likely to be different.
+     *
+     * Methods nextLong, nextInt, and derivatives do not return the
+     * sequence (seed) values, but instead a hash-like bit-mix of
+     * their bits, producing more independently distributed sequences.
+     * For nextLong, the mix64 bit-mixing function computes the same
+     * value as the "64-bit finalizer" function in Austin Appleby's
+     * MurmurHash3 algorithm.  See
+     * http://code.google.com/p/smhasher/wiki/MurmurHash3 , which
+     * comments: "The constants for the finalizers were generated by a
+     * simple simulated-annealing algorithm, and both avalanche all
+     * bits of 'h' to within 0.25% bias." The mix32 function is
+     * equivalent to (int)(mix64(seed) >>> 32), but faster because it
+     * omits a step that doesn't contribute to result.
+     *
+     * The split operation uses the current generator to form the seed
+     * and gamma for another SplittableRandom.  To conservatively
+     * avoid potential correlations between seed and value generation,
+     * gamma selection (method nextGamma) uses the "Mix13" constants
+     * for MurmurHash3 described by David Stafford
+     * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html)
+     * To avoid potential weaknesses in bit-mixing transformations, we
+     * restrict gammas to odd values with at least 12 and no more than
+     * 52 bits set.  Rather than rejecting candidates with too few or
+     * too many bits set, method nextGamma flips some bits (which has
+     * the effect of mapping at most 4 to any given gamma value).
+     * This reduces the effective set of 64bit odd gamma values by
+     * about 2<sup>14</sup>, a very tiny percentage, and serves as an
+     * automated screening for sequence constant selection that is
+     * left as an empirical decision in some other hashing and crypto
+     * algorithms.
+     *
+     * The resulting generator thus transforms a sequence in which
+     * (typically) many bits change on each step, with an inexpensive
+     * mixer with good (but less than cryptographically secure)
+     * avalanching.
+     *
+     * The default (no-argument) constructor, in essence, invokes
+     * split() for a common "seeder" SplittableRandom.  Unlike other
+     * cases, this split must be performed in a thread-safe manner, so
+     * we use an AtomicLong to represent the seed rather than use an
+     * explicit SplittableRandom. To bootstrap the seeder, we start
+     * off using a seed based on current time and host unless the
+     * java.util.secureRandomSeed property is set. This serves as a
+     * slimmed-down (and insecure) variant of SecureRandom that also
+     * avoids stalls that may occur when using /dev/random.
+     *
+     * It is a relatively simple matter to apply the basic design here
+     * to use 128 bit seeds. However, emulating 128bit arithmetic and
+     * carrying around twice the state add more overhead than appears
+     * warranted for current usages.
+     *
+     * File organization: First the non-public methods that constitute
+     * the main algorithm, then the main public methods, followed by
+     * some custom spliterator classes needed for stream methods.
+     */
+
+    /**
+     * The initial gamma value for (unsplit) SplittableRandoms. Must
+     * be odd with at least 12 and no more than 52 bits set. Currently
+     * set to the golden ratio scaled to 64bits.
+     */
+    private static final long INITIAL_GAMMA = 0x9e3779b97f4a7c15L;
+
+    /**
+     * The least non-zero value returned by nextDouble(). This value
+     * is scaled by a random value of 53 bits to produce a result.
+     */
+    private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
+
+    /**
+     * The seed. Updated only via method nextSeed.
+     */
+    private long seed;
+
+    /**
+     * The step value.
+     */
+    private final long gamma;
+
+    /**
+     * Internal constructor used by all others except default constructor.
+     */
+    private SplittableRandom(long seed, long gamma) {
+        this.seed = seed;
+        this.gamma = gamma;
+    }
+
+    /**
+     * Computes MurmurHash3 64bit mix function.
+     */
+    private static long mix64(long z) {
+        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+        z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
+        return z ^ (z >>> 33);
+    }
+
+    /**
+     * Returns the 32 high bits of mix64(z) as int.
+     */
+    private static int mix32(long z) {
+        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+        return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
+    }
+
+    /**
+     * Returns the gamma value to use for a new split instance.
+     */
+    private static long nextGamma(long z) {
+        z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L; // Stafford "Mix13"
+        z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
+        z = (z ^ (z >>> 31)) | 1L; // force to be odd
+        int n = Long.bitCount(z);  // ensure enough 0 and 1 bits
+        return (n < 12 || n > 52) ? z ^ 0xaaaaaaaaaaaaaaaaL : z;
+    }
+
+    /**
+     * Adds gamma to seed.
+     */
+    private long nextSeed() {
+        return seed += gamma;
+    }
+
+    /**
+     * The seed generator for default constructors.
+     */
+    private static final AtomicLong seeder = new AtomicLong(initialSeed());
+
+    private static long initialSeed() {
+        String pp = java.security.AccessController.doPrivileged(
+                new sun.security.action.GetPropertyAction(
+                        "java.util.secureRandomSeed"));
+        if (pp != null && pp.equalsIgnoreCase("true")) {
+            byte[] seedBytes = java.security.SecureRandom.getSeed(8);
+            long s = (long)(seedBytes[0]) & 0xffL;
+            for (int i = 1; i < 8; ++i)
+                s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
+            return s;
+        }
+        int hh = 0; // hashed host address
+        try {
+            hh = InetAddress.getLocalHost().hashCode();
+        } catch (Exception ignore) {
+        }
+        return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^
+                mix64(System.nanoTime()));
+    }
+
+    // IllegalArgumentException messages
+    static final String BadBound = "bound must be positive";
+    static final String BadRange = "bound must be greater than origin";
+    static final String BadSize  = "size must be non-negative";
+
+    /*
+     * Internal versions of nextX methods used by streams, as well as
+     * the public nextX(origin, bound) methods.  These exist mainly to
+     * avoid the need for multiple versions of stream spliterators
+     * across the different exported forms of streams.
+     */
+
+    /**
+     * The form of nextLong used by LongStream Spliterators.  If
+     * origin is greater than bound, acts as unbounded form of
+     * nextLong, else as bounded form.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final long internalNextLong(long origin, long bound) {
+        /*
+         * Four Cases:
+         *
+         * 1. If the arguments indicate unbounded form, act as
+         * nextLong().
+         *
+         * 2. If the range is an exact power of two, apply the
+         * associated bit mask.
+         *
+         * 3. If the range is positive, loop to avoid potential bias
+         * when the implicit nextLong() bound (2<sup>64</sup>) is not
+         * evenly divisible by the range. The loop rejects candidates
+         * computed from otherwise over-represented values.  The
+         * expected number of iterations under an ideal generator
+         * varies from 1 to 2, depending on the bound. The loop itself
+         * takes an unlovable form. Because the first candidate is
+         * already available, we need a break-in-the-middle
+         * construction, which is concisely but cryptically performed
+         * within the while-condition of a body-less for loop.
+         *
+         * 4. Otherwise, the range cannot be represented as a positive
+         * long.  The loop repeatedly generates unbounded longs until
+         * obtaining a candidate meeting constraints (with an expected
+         * number of iterations of less than two).
+         */
+
+        long r = mix64(nextSeed());
+        if (origin < bound) {
+            long n = bound - origin, m = n - 1;
+            if ((n & m) == 0L)  // power of two
+                r = (r & m) + origin;
+            else if (n > 0L) {  // reject over-represented candidates
+                for (long u = r >>> 1;            // ensure nonnegative
+                     u + m - (r = u % n) < 0L;    // rejection check
+                     u = mix64(nextSeed()) >>> 1) // retry
+                    ;
+                r += origin;
+            }
+            else {              // range not representable as long
+                while (r < origin || r >= bound)
+                    r = mix64(nextSeed());
+            }
+        }
+        return r;
+    }
+
+    /**
+     * The form of nextInt used by IntStream Spliterators.
+     * Exactly the same as long version, except for types.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final int internalNextInt(int origin, int bound) {
+        int r = mix32(nextSeed());
+        if (origin < bound) {
+            int n = bound - origin, m = n - 1;
+            if ((n & m) == 0)
+                r = (r & m) + origin;
+            else if (n > 0) {
+                for (int u = r >>> 1;
+                     u + m - (r = u % n) < 0;
+                     u = mix32(nextSeed()) >>> 1)
+                    ;
+                r += origin;
+            }
+            else {
+                while (r < origin || r >= bound)
+                    r = mix32(nextSeed());
+            }
+        }
+        return r;
+    }
+
+    /**
+     * The form of nextDouble used by DoubleStream Spliterators.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final double internalNextDouble(double origin, double bound) {
+        double r = (nextLong() >>> 11) * DOUBLE_UNIT;
+        if (origin < bound) {
+            r = r * (bound - origin) + origin;
+            if (r >= bound) // correct for rounding
+                r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+        }
+        return r;
+    }
+
+    /* ---------------- public methods ---------------- */
+
+    /**
+     * Creates a new SplittableRandom instance using the specified
+     * initial seed. SplittableRandom instances created with the same
+     * seed in the same program generate identical sequences of values.
+     *
+     * @param seed the initial seed
+     */
+    public SplittableRandom(long seed) {
+        this(seed, INITIAL_GAMMA);
+    }
+
+    /**
+     * Creates a new SplittableRandom instance that is likely to
+     * generate sequences of values that are statistically independent
+     * of those of any other instances in the current program; and
+     * may, and typically does, vary across program invocations.
+     */
+    public SplittableRandom() { // emulate seeder.split()
+        this.gamma = nextGamma(this.seed = seeder.addAndGet(INITIAL_GAMMA));
+    }
+
+    /**
+     * Constructs and returns a new SplittableRandom instance that
+     * shares no mutable state with this instance. However, with very
+     * high probability, the set of values collectively generated by
+     * the two objects has the same statistical properties as if the
+     * same quantity of values were generated by a single thread using
+     * a single SplittableRandom object.  Either or both of the two
+     * objects may be further split using the {@code split()} method,
+     * and the same expected statistical properties apply to the
+     * entire set of generators constructed by such recursive
+     * splitting.
+     *
+     * @return the new SplittableRandom instance
+     */
+    public SplittableRandom split() {
+        long s = nextSeed();
+        return new SplittableRandom(s, nextGamma(s));
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value.
+     *
+     * @return a pseudorandom {@code int} value
+     */
+    public int nextInt() {
+        return mix32(nextSeed());
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value between zero (inclusive)
+     * and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code int} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public int nextInt(int bound) {
+        if (bound <= 0)
+            throw new IllegalArgumentException(BadBound);
+        // Specialize internalNextInt for origin 0
+        int r = mix32(nextSeed());
+        int m = bound - 1;
+        if ((bound & m) == 0) // power of two
+            r &= m;
+        else { // reject over-represented candidates
+            for (int u = r >>> 1;
+                 u + m - (r = u % bound) < 0;
+                 u = mix32(nextSeed()) >>> 1)
+                ;
+        }
+        return r;
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value between the specified
+     * origin (inclusive) and the specified bound (exclusive).
+     *
+     * @param origin the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return a pseudorandom {@code int} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
+     */
+    public int nextInt(int origin, int bound) {
+        if (origin >= bound)
+            throw new IllegalArgumentException(BadRange);
+        return internalNextInt(origin, bound);
+    }
+
+    /**
+     * Returns a pseudorandom {@code long} value.
+     *
+     * @return a pseudorandom {@code long} value
+     */
+    public long nextLong() {
+        return mix64(nextSeed());
+    }
+
+    /**
+     * Returns a pseudorandom {@code long} value between zero (inclusive)
+     * and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code long} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public long nextLong(long bound) {
+        if (bound <= 0)
+            throw new IllegalArgumentException(BadBound);
+        // Specialize internalNextLong for origin 0
+        long r = mix64(nextSeed());
+        long m = bound - 1;
+        if ((bound & m) == 0L) // power of two
+            r &= m;
+        else { // reject over-represented candidates
+            for (long u = r >>> 1;
+                 u + m - (r = u % bound) < 0L;
+                 u = mix64(nextSeed()) >>> 1)
+                ;
+        }
+        return r;
+    }
+
+    /**
+     * Returns a pseudorandom {@code long} value between the specified
+     * origin (inclusive) and the specified bound (exclusive).
+     *
+     * @param origin the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return a pseudorandom {@code long} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
+     */
+    public long nextLong(long origin, long bound) {
+        if (origin >= bound)
+            throw new IllegalArgumentException(BadRange);
+        return internalNextLong(origin, bound);
+    }
+
+    /**
+     * Returns a pseudorandom {@code double} value between zero
+     * (inclusive) and one (exclusive).
+     *
+     * @return a pseudorandom {@code double} value between zero
+     *         (inclusive) and one (exclusive)
+     */
+    public double nextDouble() {
+        return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
+    }
+
+    /**
+     * Returns a pseudorandom {@code double} value between 0.0
+     * (inclusive) and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code double} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public double nextDouble(double bound) {
+        if (!(bound > 0.0))
+            throw new IllegalArgumentException(BadBound);
+        double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
+        return (result < bound) ?  result : // correct for rounding
+            Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+    }
+
+    /**
+     * Returns a pseudorandom {@code double} value between the specified
+     * origin (inclusive) and bound (exclusive).
+     *
+     * @param origin the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return a pseudorandom {@code double} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
+     */
+    public double nextDouble(double origin, double bound) {
+        if (!(origin < bound))
+            throw new IllegalArgumentException(BadRange);
+        return internalNextDouble(origin, bound);
+    }
+
+    /**
+     * Returns a pseudorandom {@code boolean} value.
+     *
+     * @return a pseudorandom {@code boolean} value
+     */
+    public boolean nextBoolean() {
+        return mix32(nextSeed()) < 0;
+    }
+
+    // stream methods, coded in a way intended to better isolate for
+    // maintenance purposes the small differences across forms.
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number
+     * of pseudorandom {@code int} values from this generator and/or
+     * one split from it.
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of pseudorandom {@code int} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     */
+    public IntStream ints(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (this, 0L, streamSize, Integer.MAX_VALUE, 0),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code int}
+     * values from this generator and/or one split from it.
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * ints(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code int} values
+     */
+    public IntStream ints() {
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number
+     * of pseudorandom {@code int} values from this generator and/or one split
+     * from it; each value conforms to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code int} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero, or {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public IntStream ints(long streamSize, int randomNumberOrigin,
+                          int randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * int} values from this generator and/or one split from it; each value
+     * conforms to the given origin (inclusive) and bound (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code int} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number
+     * of pseudorandom {@code long} values from this generator and/or
+     * one split from it.
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of pseudorandom {@code long} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     */
+    public LongStream longs(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (this, 0L, streamSize, Long.MAX_VALUE, 0L),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * long} values from this generator and/or one split from it.
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * longs(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code long} values
+     */
+    public LongStream longs() {
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code long} values from this generator and/or one split
+     * from it; each value conforms to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code long} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero, or {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public LongStream longs(long streamSize, long randomNumberOrigin,
+                            long randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * long} values from this generator and/or one split from it; each value
+     * conforms to the given origin (inclusive) and bound (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code long} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code double} values from this generator and/or one split
+     * from it; each value is between zero (inclusive) and one (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of {@code double} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     */
+    public DoubleStream doubles(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * double} values from this generator and/or one split from it; each value
+     * is between zero (inclusive) and one (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * doubles(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code double} values
+     */
+    public DoubleStream doubles() {
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code double} values from this generator and/or one split
+     * from it; each value conforms to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code double} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public DoubleStream doubles(long streamSize, double randomNumberOrigin,
+                                double randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        if (!(randomNumberOrigin < randomNumberBound))
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * double} values from this generator and/or one split from it; each value
+     * conforms to the given origin (inclusive) and bound (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code double} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+        if (!(randomNumberOrigin < randomNumberBound))
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Spliterator for int streams.  We multiplex the four int
+     * versions into one class by treating a bound less than origin as
+     * unbounded, and also by treating "infinite" as equivalent to
+     * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
+     * approach. The long and double versions of this class are
+     * identical except for types.
+     */
+    static final class RandomIntsSpliterator implements Spliterator.OfInt {
+        final SplittableRandom rng;
+        long index;
+        final long fence;
+        final int origin;
+        final int bound;
+        RandomIntsSpliterator(SplittableRandom rng, long index, long fence,
+                              int origin, int bound) {
+            this.rng = rng; this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomIntsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomIntsSpliterator(rng.split(), i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rng.internalNextInt(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                SplittableRandom r = rng;
+                int o = origin, b = bound;
+                do {
+                    consumer.accept(r.internalNextInt(o, b));
+                } while (++i < f);
+            }
+        }
+    }
+
+    /**
+     * Spliterator for long streams.
+     */
+    static final class RandomLongsSpliterator implements Spliterator.OfLong {
+        final SplittableRandom rng;
+        long index;
+        final long fence;
+        final long origin;
+        final long bound;
+        RandomLongsSpliterator(SplittableRandom rng, long index, long fence,
+                               long origin, long bound) {
+            this.rng = rng; this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomLongsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomLongsSpliterator(rng.split(), i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rng.internalNextLong(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                SplittableRandom r = rng;
+                long o = origin, b = bound;
+                do {
+                    consumer.accept(r.internalNextLong(o, b));
+                } while (++i < f);
+            }
+        }
+
+    }
+
+    /**
+     * Spliterator for double streams.
+     */
+    static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
+        final SplittableRandom rng;
+        long index;
+        final long fence;
+        final double origin;
+        final double bound;
+        RandomDoublesSpliterator(SplittableRandom rng, long index, long fence,
+                                 double origin, double bound) {
+            this.rng = rng; this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomDoublesSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomDoublesSpliterator(rng.split(), i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rng.internalNextDouble(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                SplittableRandom r = rng;
+                double o = origin, b = bound;
+                do {
+                    consumer.accept(r.internalNextDouble(o, b));
+                } while (++i < f);
+            }
+        }
+    }
+
+}
--- a/src/share/classes/java/util/TimSort.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/TimSort.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Google Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -176,7 +177,7 @@
          */
         int stackLen = (len <    120  ?  5 :
                         len <   1542  ? 10 :
-                        len < 119151  ? 19 : 40);
+                        len < 119151  ? 24 : 40);
         runBase = new int[stackLen];
         runLen = new int[stackLen];
     }
--- a/src/share/classes/java/util/TreeMap.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/TreeMap.java	Fri Sep 06 15:09:44 2013 -0700
@@ -973,6 +973,27 @@
     }
 
     @Override
+    public boolean replace(K key, V oldValue, V newValue) {
+        Entry<K,V> p = getEntry(key);
+        if (p!=null && Objects.equals(oldValue, p.value)) {
+            p.value = newValue;
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public V replace(K key, V value) {
+        Entry<K,V> p = getEntry(key);
+        if (p!=null) {
+            V oldValue = p.value;
+            p.value = value;
+            return oldValue;
+        }
+        return null;
+    }
+
+    @Override
     public void forEach(BiConsumer<? super K, ? super V> action) {
         Objects.requireNonNull(action);
         int expectedModCount = modCount;
--- a/src/share/classes/java/util/concurrent/ThreadLocalRandom.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/concurrent/ThreadLocalRandom.java	Fri Sep 06 15:09:44 2013 -0700
@@ -37,11 +37,16 @@
 
 import java.io.ObjectStreamField;
 import java.util.Random;
+import java.util.Spliterator;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
 import java.util.stream.DoubleStream;
 import java.util.stream.IntStream;
 import java.util.stream.LongStream;
+import java.util.stream.StreamSupport;
 
 /**
  * A random number generator isolated to the current thread.  Like the
@@ -64,6 +69,10 @@
  * <p>This class also provides additional commonly used bounded random
  * generation methods.
  *
+ * <p>Instances of {@code ThreadLocalRandom} are not cryptographically
+ * secure.  Consider instead using {@link java.security.SecureRandom}
+ * in security-sensitive applications.
+ *
  * @since 1.7
  * @author Doug Lea
  */
@@ -85,28 +94,26 @@
      * application-level overhead and footprint of most concurrent
      * programs.
      *
+     * Even though this class subclasses java.util.Random, it uses the
+     * same basic algorithm as java.util.SplittableRandom.  (See its
+     * internal documentation for explanations, which are not repeated
+     * here.)  Because ThreadLocalRandoms are not splittable
+     * though, we use only a single 64bit gamma.
+     *
      * Because this class is in a different package than class Thread,
      * field access methods use Unsafe to bypass access control rules.
-     * The base functionality of Random methods is conveniently
-     * isolated in method next(bits), that just reads and writes the
-     * Thread field rather than its own field.  However, to conform to
-     * the requirements of the Random superclass constructor, the
-     * common static ThreadLocalRandom maintains an "initialized"
-     * field for the sake of rejecting user calls to setSeed while
-     * still allowing a call from constructor.  Note that
-     * serialization is completely unnecessary because there is only a
-     * static singleton.  But we generate a serial form containing
-     * "rnd" and "initialized" fields to ensure compatibility across
-     * versions.
+     * To conform to the requirements of the Random superclass
+     * constructor, the common static ThreadLocalRandom maintains an
+     * "initialized" field for the sake of rejecting user calls to
+     * setSeed while still allowing a call from constructor.  Note
+     * that serialization is completely unnecessary because there is
+     * only a static singleton.  But we generate a serial form
+     * containing "rnd" and "initialized" fields to ensure
+     * compatibility across versions.
      *
-     * Per-thread initialization is similar to that in the no-arg
-     * Random constructor, but we avoid correlation among not only
-     * initial seeds of those created in different threads, but also
-     * those created using class Random itself; while at the same time
-     * not changing any statistical properties.  So we use the same
-     * underlying multiplicative sequence, but start the sequence far
-     * away from the base version, and then merge (xor) current time
-     * and per-thread probe bits to generate initial values.
+     * Implementations of non-core methods are mostly the same as in
+     * SplittableRandom, that were in part derived from a previous
+     * version of this class.
      *
      * The nextLocalGaussian ThreadLocal supports the very rarely used
      * nextGaussian method by providing a holder for the second of a
@@ -115,24 +122,51 @@
      * but we provide identical statistical properties.
      */
 
-    // same constants as Random, but must be redeclared because private
-    private static final long multiplier = 0x5DEECE66DL;
-    private static final long addend = 0xBL;
-    private static final long mask = (1L << 48) - 1;
-    private static final int PROBE_INCREMENT = 0x61c88647;
-
-    /** Generates the basis for per-thread initial seed values */
-    private static final AtomicLong seedGenerator =
-        new AtomicLong(1269533684904616924L);
-
     /** Generates per-thread initialization/probe field */
     private static final AtomicInteger probeGenerator =
-        new AtomicInteger(0xe80f8647);
+        new AtomicInteger();
+
+    /**
+     * The next seed for default constructors.
+     */
+    private static final AtomicLong seeder =
+        new AtomicLong(mix64(System.currentTimeMillis()) ^
+                       mix64(System.nanoTime()));
+
+    /**
+     * The seed increment
+     */
+    private static final long GAMMA = 0x9e3779b97f4a7c15L;
+
+    /**
+     * The increment for generating probe values
+     */
+    private static final int PROBE_INCREMENT = 0x9e3779b9;
+
+    /**
+     * The increment of seeder per new instance
+     */
+    private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
+
+    // Constants from SplittableRandom
+    private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
+    private static final float  FLOAT_UNIT  = 1.0f / (1 << 24);
 
     /** Rarely-used holder for the second of a pair of Gaussians */
     private static final ThreadLocal<Double> nextLocalGaussian =
         new ThreadLocal<Double>();
 
+    private static long mix64(long z) {
+        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+        z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
+        return z ^ (z >>> 33);
+    }
+
+    private static int mix32(long z) {
+        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+        return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
+    }
+
     /**
      * Field used only during singleton initialization.
      * True when constructor completes.
@@ -155,16 +189,11 @@
      * rely on (static) atomic generators to initialize the values.
      */
     static final void localInit() {
-        int p = probeGenerator.getAndAdd(PROBE_INCREMENT);
+        int p = probeGenerator.addAndGet(PROBE_INCREMENT);
         int probe = (p == 0) ? 1 : p; // skip 0
-        long current, next;
-        do { // same sequence as j.u.Random but different initial value
-            current = seedGenerator.get();
-            next = current * 181783497276652981L;
-        } while (!seedGenerator.compareAndSet(current, next));
-        long r = next ^ ((long)probe << 32) ^ System.nanoTime();
+        long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
         Thread t = Thread.currentThread();
-        UNSAFE.putLong(t, SEED, r);
+        UNSAFE.putLong(t, SEED, seed);
         UNSAFE.putInt(t, PROBE, probe);
     }
 
@@ -191,124 +220,264 @@
             throw new UnsupportedOperationException();
     }
 
-    protected int next(int bits) {
+    final long nextSeed() {
         Thread t; long r; // read and update per-thread seed
-        UNSAFE.putLong
-            (t = Thread.currentThread(), SEED,
-             r = (UNSAFE.getLong(t, SEED) * multiplier + addend) & mask);
-        return (int) (r >>> (48-bits));
+        UNSAFE.putLong(t = Thread.currentThread(), SEED,
+                       r = UNSAFE.getLong(t, SEED) + GAMMA);
+        return r;
+    }
+
+    // We must define this, but never use it.
+    protected int next(int bits) {
+        return (int)(mix64(nextSeed()) >>> (64 - bits));
+    }
+
+    // IllegalArgumentException messages
+    static final String BadBound = "bound must be positive";
+    static final String BadRange = "bound must be greater than origin";
+    static final String BadSize  = "size must be non-negative";
+
+    /**
+     * The form of nextLong used by LongStream Spliterators.  If
+     * origin is greater than bound, acts as unbounded form of
+     * nextLong, else as bounded form.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final long internalNextLong(long origin, long bound) {
+        long r = mix64(nextSeed());
+        if (origin < bound) {
+            long n = bound - origin, m = n - 1;
+            if ((n & m) == 0L)  // power of two
+                r = (r & m) + origin;
+            else if (n > 0L) {  // reject over-represented candidates
+                for (long u = r >>> 1;            // ensure nonnegative
+                     u + m - (r = u % n) < 0L;    // rejection check
+                     u = mix64(nextSeed()) >>> 1) // retry
+                    ;
+                r += origin;
+            }
+            else {              // range not representable as long
+                while (r < origin || r >= bound)
+                    r = mix64(nextSeed());
+            }
+        }
+        return r;
     }
 
     /**
-     * Returns a pseudorandom, uniformly distributed value between the
-     * given least value (inclusive) and bound (exclusive).
+     * The form of nextInt used by IntStream Spliterators.
+     * Exactly the same as long version, except for types.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final int internalNextInt(int origin, int bound) {
+        int r = mix32(nextSeed());
+        if (origin < bound) {
+            int n = bound - origin, m = n - 1;
+            if ((n & m) == 0)
+                r = (r & m) + origin;
+            else if (n > 0) {
+                for (int u = r >>> 1;
+                     u + m - (r = u % n) < 0;
+                     u = mix32(nextSeed()) >>> 1)
+                    ;
+                r += origin;
+            }
+            else {
+                while (r < origin || r >= bound)
+                    r = mix32(nextSeed());
+            }
+        }
+        return r;
+    }
+
+    /**
+     * The form of nextDouble used by DoubleStream Spliterators.
      *
-     * @param least the least value returned
-     * @param bound the upper bound (exclusive)
-     * @throws IllegalArgumentException if least greater than or equal
-     * to bound
-     * @return the next value
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final double internalNextDouble(double origin, double bound) {
+        double r = (nextLong() >>> 11) * DOUBLE_UNIT;
+        if (origin < bound) {
+            r = r * (bound - origin) + origin;
+            if (r >= bound) // correct for rounding
+                r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+        }
+        return r;
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value.
+     *
+     * @return a pseudorandom {@code int} value
      */
-    public int nextInt(int least, int bound) {
-        if (least >= bound)
-            throw new IllegalArgumentException();
-        return nextInt(bound - least) + least;
+    public int nextInt() {
+        return mix32(nextSeed());
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value between zero (inclusive)
+     * and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code int} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public int nextInt(int bound) {
+        if (bound <= 0)
+            throw new IllegalArgumentException(BadBound);
+        int r = mix32(nextSeed());
+        int m = bound - 1;
+        if ((bound & m) == 0) // power of two
+            r &= m;
+        else { // reject over-represented candidates
+            for (int u = r >>> 1;
+                 u + m - (r = u % bound) < 0;
+                 u = mix32(nextSeed()) >>> 1)
+                ;
+        }
+        return r;
     }
 
     /**
-     * Returns a pseudorandom, uniformly distributed value
-     * between 0 (inclusive) and the specified value (exclusive).
+     * Returns a pseudorandom {@code int} value between the specified
+     * origin (inclusive) and the specified bound (exclusive).
      *
-     * @param n the bound on the random number to be returned.  Must be
-     *        positive.
-     * @return the next value
-     * @throws IllegalArgumentException if n is not positive
+     * @param origin the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return a pseudorandom {@code int} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
      */
-    public long nextLong(long n) {
-        if (n <= 0)
-            throw new IllegalArgumentException("n must be positive");
-        // Divide n by two until small enough for nextInt. On each
-        // iteration (at most 31 of them but usually much less),
-        // randomly choose both whether to include high bit in result
-        // (offset) and whether to continue with the lower vs upper
-        // half (which makes a difference only if odd).
-        long offset = 0;
-        while (n >= Integer.MAX_VALUE) {
-            int bits = next(2);
-            long half = n >>> 1;
-            long nextn = ((bits & 2) == 0) ? half : n - half;
-            if ((bits & 1) == 0)
-                offset += n - nextn;
-            n = nextn;
-        }
-        return offset + nextInt((int) n);
+    public int nextInt(int origin, int bound) {
+        if (origin >= bound)
+            throw new IllegalArgumentException(BadRange);
+        return internalNextInt(origin, bound);
     }
 
-    @Override
-    public IntStream ints() {
-        return IntStream.generate(() -> current().nextInt());
+    /**
+     * Returns a pseudorandom {@code long} value.
+     *
+     * @return a pseudorandom {@code long} value
+     */
+    public long nextLong() {
+        return mix64(nextSeed());
     }
 
-    @Override
-    public LongStream longs() {
-        return LongStream.generate(() -> current().nextLong());
-    }
-
-    @Override
-    public DoubleStream doubles() {
-        return DoubleStream.generate(() -> current().nextDouble());
-    }
-
-    @Override
-    public DoubleStream gaussians() {
-        return DoubleStream.generate(() -> current().nextGaussian());
+    /**
+     * Returns a pseudorandom {@code long} value between zero (inclusive)
+     * and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code long} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public long nextLong(long bound) {
+        if (bound <= 0)
+            throw new IllegalArgumentException(BadBound);
+        long r = mix64(nextSeed());
+        long m = bound - 1;
+        if ((bound & m) == 0L) // power of two
+            r &= m;
+        else { // reject over-represented candidates
+            for (long u = r >>> 1;
+                 u + m - (r = u % bound) < 0L;
+                 u = mix64(nextSeed()) >>> 1)
+                ;
+        }
+        return r;
     }
 
     /**
-     * Returns a pseudorandom, uniformly distributed value between the
-     * given least value (inclusive) and bound (exclusive).
+     * Returns a pseudorandom {@code long} value between the specified
+     * origin (inclusive) and the specified bound (exclusive).
      *
-     * @param least the least value returned
+     * @param origin the least value returned
      * @param bound the upper bound (exclusive)
-     * @return the next value
-     * @throws IllegalArgumentException if least greater than or equal
-     * to bound
+     * @return a pseudorandom {@code long} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
      */
-    public long nextLong(long least, long bound) {
-        if (least >= bound)
-            throw new IllegalArgumentException();
-        return nextLong(bound - least) + least;
+    public long nextLong(long origin, long bound) {
+        if (origin >= bound)
+            throw new IllegalArgumentException(BadRange);
+        return internalNextLong(origin, bound);
+    }
+
+    /**
+     * Returns a pseudorandom {@code double} value between zero
+     * (inclusive) and one (exclusive).
+     *
+     * @return a pseudorandom {@code double} value between zero
+     *         (inclusive) and one (exclusive)
+     */
+    public double nextDouble() {
+        return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
     }
 
     /**
-     * Returns a pseudorandom, uniformly distributed {@code double} value
-     * between 0 (inclusive) and the specified value (exclusive).
+     * Returns a pseudorandom {@code double} value between 0.0
+     * (inclusive) and the specified bound (exclusive).
      *
-     * @param n the bound on the random number to be returned.  Must be
-     *        positive.
-     * @return the next value
-     * @throws IllegalArgumentException if n is not positive
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code double} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
      */
-    public double nextDouble(double n) {
-        if (n <= 0)
-            throw new IllegalArgumentException("n must be positive");
-        return nextDouble() * n;
+    public double nextDouble(double bound) {
+        if (!(bound > 0.0))
+            throw new IllegalArgumentException(BadBound);
+        double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
+        return (result < bound) ?  result : // correct for rounding
+            Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
     }
 
     /**
-     * Returns a pseudorandom, uniformly distributed value between the
-     * given least value (inclusive) and bound (exclusive).
+     * Returns a pseudorandom {@code double} value between the specified
+     * origin (inclusive) and bound (exclusive).
      *
-     * @param least the least value returned
+     * @param origin the least value returned
      * @param bound the upper bound (exclusive)
-     * @return the next value
-     * @throws IllegalArgumentException if least greater than or equal
-     * to bound
+     * @return a pseudorandom {@code double} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
      */
-    public double nextDouble(double least, double bound) {
-        if (least >= bound)
-            throw new IllegalArgumentException();
-        return nextDouble() * (bound - least) + least;
+    public double nextDouble(double origin, double bound) {
+        if (!(origin < bound))
+            throw new IllegalArgumentException(BadRange);
+        return internalNextDouble(origin, bound);
+    }
+
+    /**
+     * Returns a pseudorandom {@code boolean} value.
+     *
+     * @return a pseudorandom {@code boolean} value
+     */
+    public boolean nextBoolean() {
+        return mix32(nextSeed()) < 0;
+    }
+
+    /**
+     * Returns a pseudorandom {@code float} value between zero
+     * (inclusive) and one (exclusive).
+     *
+     * @return a pseudorandom {@code float} value between zero
+     *         (inclusive) and one (exclusive)
+     */
+    public float nextFloat() {
+        return (mix32(nextSeed()) >>> 8) * FLOAT_UNIT;
     }
 
     public double nextGaussian() {
@@ -329,6 +498,445 @@
         return v1 * multiplier;
     }
 
+    // stream methods, coded in a way intended to better isolate for
+    // maintenance purposes the small differences across forms.
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code int} values.
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of pseudorandom {@code int} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @since 1.8
+     */
+    public IntStream ints(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (0L, streamSize, Integer.MAX_VALUE, 0),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code int}
+     * values.
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * ints(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code int} values
+     * @since 1.8
+     */
+    public IntStream ints() {
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number
+     * of pseudorandom {@code int} values, each conforming to the given
+     * origin (inclusive) and bound (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code int} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero, or {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public IntStream ints(long streamSize, int randomNumberOrigin,
+                          int randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (0L, streamSize, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * int} values, each conforming to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code int} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code long} values.
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of pseudorandom {@code long} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @since 1.8
+     */
+    public LongStream longs(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (0L, streamSize, Long.MAX_VALUE, 0L),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code long}
+     * values.
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * longs(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code long} values
+     * @since 1.8
+     */
+    public LongStream longs() {
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code long}, each conforming to the given origin
+     * (inclusive) and bound (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code long} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero, or {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public LongStream longs(long streamSize, long randomNumberOrigin,
+                            long randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (0L, streamSize, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * long} values, each conforming to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code long} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code double} values, each between zero
+     * (inclusive) and one (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of {@code double} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @since 1.8
+     */
+    public DoubleStream doubles(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (0L, streamSize, Double.MAX_VALUE, 0.0),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * double} values, each between zero (inclusive) and one
+     * (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * doubles(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code double} values
+     * @since 1.8
+     */
+    public DoubleStream doubles() {
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code double} values, each conforming to the given origin
+     * (inclusive) and bound (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code double} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public DoubleStream doubles(long streamSize, double randomNumberOrigin,
+                                double randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BadSize);
+        if (!(randomNumberOrigin < randomNumberBound))
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (0L, streamSize, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * double} values, each conforming to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code double} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     * @since 1.8
+     */
+    public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+        if (!(randomNumberOrigin < randomNumberBound))
+            throw new IllegalArgumentException(BadRange);
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Spliterator for int streams.  We multiplex the four int
+     * versions into one class by treating a bound less than origin as
+     * unbounded, and also by treating "infinite" as equivalent to
+     * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
+     * approach. The long and double versions of this class are
+     * identical except for types.
+     */
+    static final class RandomIntsSpliterator implements Spliterator.OfInt {
+        long index;
+        final long fence;
+        final int origin;
+        final int bound;
+        RandomIntsSpliterator(long index, long fence,
+                              int origin, int bound) {
+            this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomIntsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomIntsSpliterator(i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(ThreadLocalRandom.current().internalNextInt(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                int o = origin, b = bound;
+                ThreadLocalRandom rng = ThreadLocalRandom.current();
+                do {
+                    consumer.accept(rng.internalNextInt(o, b));
+                } while (++i < f);
+            }
+        }
+    }
+
+    /**
+     * Spliterator for long streams.
+     */
+    static final class RandomLongsSpliterator implements Spliterator.OfLong {
+        long index;
+        final long fence;
+        final long origin;
+        final long bound;
+        RandomLongsSpliterator(long index, long fence,
+                               long origin, long bound) {
+            this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomLongsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomLongsSpliterator(i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(ThreadLocalRandom.current().internalNextLong(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                long o = origin, b = bound;
+                ThreadLocalRandom rng = ThreadLocalRandom.current();
+                do {
+                    consumer.accept(rng.internalNextLong(o, b));
+                } while (++i < f);
+            }
+        }
+
+    }
+
+    /**
+     * Spliterator for double streams.
+     */
+    static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
+        long index;
+        final long fence;
+        final double origin;
+        final double bound;
+        RandomDoublesSpliterator(long index, long fence,
+                                 double origin, double bound) {
+            this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomDoublesSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomDoublesSpliterator(i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(ThreadLocalRandom.current().internalNextDouble(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                double o = origin, b = bound;
+                ThreadLocalRandom rng = ThreadLocalRandom.current();
+                do {
+                    consumer.accept(rng.internalNextDouble(o, b));
+                } while (++i < f);
+            }
+        }
+    }
+
+
     // Within-package utilities
 
     /*
@@ -401,23 +1009,26 @@
      */
     private static final ObjectStreamField[] serialPersistentFields = {
             new ObjectStreamField("rnd", long.class),
-            new ObjectStreamField("initialized", boolean.class)
+            new ObjectStreamField("initialized", boolean.class),
     };
 
     /**
      * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      */
-    private void writeObject(java.io.ObjectOutputStream out)
+    private void writeObject(java.io.ObjectOutputStream s)
         throws java.io.IOException {
 
-        java.io.ObjectOutputStream.PutField fields = out.putFields();
+        java.io.ObjectOutputStream.PutField fields = s.putFields();
         fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
         fields.put("initialized", true);
-        out.writeFields();
+        s.writeFields();
     }
 
     /**
      * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
+     * @return the {@link #current() current} thread's {@code ThreadLocalRandom}
      */
     private Object readResolve() {
         return current();
--- a/src/share/classes/java/util/concurrent/locks/StampedLock.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/concurrent/locks/StampedLock.java	Fri Sep 06 15:09:44 2013 -0700
@@ -226,7 +226,11 @@
      * incoming reader arrives while read lock is held but there is a
      * queued writer, this incoming reader is queued.  (This rule is
      * responsible for some of the complexity of method acquireRead,
-     * but without it, the lock becomes highly unfair.)
+     * but without it, the lock becomes highly unfair.) Method release
+     * does not (and sometimes cannot) itself wake up cowaiters. This
+     * is done by the primary thread, but helped by any other threads
+     * with nothing better to do in methods acquireRead and
+     * acquireWrite.
      *
      * These rules apply to threads actually queued. All tryLock forms
      * opportunistically try to acquire locks regardless of preference
@@ -267,11 +271,14 @@
     /** Number of processors, for spin control */
     private static final int NCPU = Runtime.getRuntime().availableProcessors();
 
-    /** Maximum number of retries before blocking on acquisition */
+    /** Maximum number of retries before enqueuing on acquisition */
     private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0;
 
+    /** Maximum number of retries before blocking at head on acquisition */
+    private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 0;
+
     /** Maximum number of retries before re-blocking */
-    private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 12 : 0;
+    private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 16 : 0;
 
     /** The period for yielding when waiting for overflow spinlock */
     private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1
@@ -415,8 +422,8 @@
      * @return a stamp that can be used to unlock or convert mode
      */
     public long readLock() {
-        long s, next;  // bypass acquireRead on fully unlocked case only
-        return ((((s = state) & ABITS) == 0L &&
+        long s = state, next;  // bypass acquireRead on common uncontended case
+        return ((whead == wtail && (s & ABITS) < RFULL &&
                  U.compareAndSwapLong(this, STATE, s, next = s + RUNIT)) ?
                 next : acquireRead(false, 0L));
     }
@@ -1012,17 +1019,8 @@
                     if (t.status <= 0)
                         q = t;
             }
-            if (q != null) {
-                for (WNode r = q;;) {  // release co-waiters too
-                    if ((w = r.thread) != null) {
-                        r.thread = null;
-                        U.unpark(w);
-                    }
-                    if ((r = q.cowait) == null)
-                        break;
-                    U.compareAndSwapObject(q, WCOWAIT, r, r.cowait);
-                }
-            }
+            if (q != null && (w = q.thread) != null)
+                U.unpark(w);
         }
     }
 
@@ -1038,22 +1036,22 @@
     private long acquireWrite(boolean interruptible, long deadline) {
         WNode node = null, p;
         for (int spins = -1;;) { // spin while enqueuing
-            long s, ns;
-            if (((s = state) & ABITS) == 0L) {
+            long m, s, ns;
+            if ((m = (s = state) & ABITS) == 0L) {
                 if (U.compareAndSwapLong(this, STATE, s, ns = s + WBIT))
                     return ns;
             }
+            else if (spins < 0)
+                spins = (m == WBIT && wtail == whead) ? SPINS : 0;
             else if (spins > 0) {
                 if (LockSupport.nextSecondarySeed() >= 0)
                     --spins;
             }
             else if ((p = wtail) == null) { // initialize queue
-                WNode h = new WNode(WMODE, null);
-                if (U.compareAndSwapObject(this, WHEAD, null, h))
-                    wtail = h;
+                WNode hd = new WNode(WMODE, null);
+                if (U.compareAndSwapObject(this, WHEAD, null, hd))
+                    wtail = hd;
             }
-            else if (spins < 0)
-                spins = (p == whead) ? SPINS : 0;
             else if (node == null)
                 node = new WNode(WMODE, p);
             else if (node.prev != p)
@@ -1064,14 +1062,18 @@
             }
         }
 
-        for (int spins = SPINS;;) {
-            WNode np, pp; int ps; long s, ns; Thread w;
-            while ((np = node.prev) != p && np != null)
-                (p = np).next = node;   // stale
-            if (whead == p) {
+        for (int spins = -1;;) {
+            WNode h, np, pp; int ps;
+            if ((h = whead) == p) {
+                if (spins < 0)
+                    spins = HEAD_SPINS;
+                else if (spins < MAX_HEAD_SPINS)
+                    spins <<= 1;
                 for (int k = spins;;) { // spin at head
+                    long s, ns;
                     if (((s = state) & ABITS) == 0L) {
-                        if (U.compareAndSwapLong(this, STATE, s, ns = s+WBIT)) {
+                        if (U.compareAndSwapLong(this, STATE, s,
+                                                 ns = s + WBIT)) {
                             whead = node;
                             node.prev = null;
                             return ns;
@@ -1081,33 +1083,45 @@
                              --k <= 0)
                         break;
                 }
-                if (spins < MAX_HEAD_SPINS)
-                    spins <<= 1;
             }
-            if ((ps = p.status) == 0)
-                U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
-            else if (ps == CANCELLED) {
-                if ((pp = p.prev) != null) {
-                    node.prev = pp;
-                    pp.next = node;
+            else if (h != null) { // help release stale waiters
+                WNode c; Thread w;
+                while ((c = h.cowait) != null) {
+                    if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) &&
+                        (w = c.thread) != null)
+                        U.unpark(w);
                 }
             }
-            else {
-                long time; // 0 argument to park means no timeout
-                if (deadline == 0L)
-                    time = 0L;
-                else if ((time = deadline - System.nanoTime()) <= 0L)
-                    return cancelWaiter(node, node, false);
-                Thread wt = Thread.currentThread();
-                U.putObject(wt, PARKBLOCKER, this); // emulate LockSupport.park
-                node.thread = wt;
-                if (node.prev == p && p.status == WAITING && // recheck
-                    (p != whead || (state & ABITS) != 0L))
-                    U.park(false, time);
-                node.thread = null;
-                U.putObject(wt, PARKBLOCKER, null);
-                if (interruptible && Thread.interrupted())
-                    return cancelWaiter(node, node, true);
+            if (whead == h) {
+                if ((np = node.prev) != p) {
+                    if (np != null)
+                        (p = np).next = node;   // stale
+                }
+                else if ((ps = p.status) == 0)
+                    U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
+                else if (ps == CANCELLED) {
+                    if ((pp = p.prev) != null) {
+                        node.prev = pp;
+                        pp.next = node;
+                    }
+                }
+                else {
+                    long time; // 0 argument to park means no timeout
+                    if (deadline == 0L)
+                        time = 0L;
+                    else if ((time = deadline - System.nanoTime()) <= 0L)
+                        return cancelWaiter(node, node, false);
+                    Thread wt = Thread.currentThread();
+                    U.putObject(wt, PARKBLOCKER, this);
+                    node.thread = wt;
+                    if (p.status < 0 && (p != h || (state & ABITS) != 0L) &&
+                        whead == h && node.prev == p)
+                        U.park(false, time);  // emulate LockSupport.park
+                    node.thread = null;
+                    U.putObject(wt, PARKBLOCKER, null);
+                    if (interruptible && Thread.interrupted())
+                        return cancelWaiter(node, node, true);
+                }
             }
         }
     }
@@ -1122,138 +1136,159 @@
      * @return next state, or INTERRUPTED
      */
     private long acquireRead(boolean interruptible, long deadline) {
-        WNode node = null, group = null, p;
+        WNode node = null, p;
         for (int spins = -1;;) {
-            for (;;) {
-                long s, m, ns; WNode h, q; Thread w; // anti-barging guard
-                if (group == null && (h = whead) != null &&
-                    (q = h.next) != null && q.mode != RMODE)
-                    break;
-                if ((m = (s = state) & ABITS) < RFULL ?
-                    U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
-                    (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
-                    if (group != null) {  // help release others
-                        for (WNode r = group;;) {
-                            if ((w = r.thread) != null) {
-                                r.thread = null;
-                                U.unpark(w);
+            WNode h;
+            if ((h = whead) == (p = wtail)) {
+                for (long m, s, ns;;) {
+                    if ((m = (s = state) & ABITS) < RFULL ?
+                        U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
+                        (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L))
+                        return ns;
+                    else if (m >= WBIT) {
+                        if (spins > 0) {
+                            if (LockSupport.nextSecondarySeed() >= 0)
+                                --spins;
+                        }
+                        else {
+                            if (spins == 0) {
+                                WNode nh = whead, np = wtail;
+                                if ((nh == h && np == p) || (h = nh) != (p = np))
+                                    break;
                             }
-                            if ((r = group.cowait) == null)
-                                break;
-                            U.compareAndSwapObject(group, WCOWAIT, r, r.cowait);
+                            spins = SPINS;
                         }
                     }
-                    return ns;
                 }
-                if (m >= WBIT)
-                    break;
+            }
+            if (p == null) { // initialize queue
+                WNode hd = new WNode(WMODE, null);
+                if (U.compareAndSwapObject(this, WHEAD, null, hd))
+                    wtail = hd;
             }
-            if (spins > 0) {
-                if (LockSupport.nextSecondarySeed() >= 0)
-                    --spins;
-            }
-            else if ((p = wtail) == null) {
-                WNode h = new WNode(WMODE, null);
-                if (U.compareAndSwapObject(this, WHEAD, null, h))
-                    wtail = h;
+            else if (node == null)
+                node = new WNode(RMODE, p);
+            else if (h == p || p.mode != RMODE) {
+                if (node.prev != p)
+                    node.prev = p;
+                else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
+                    p.next = node;
+                    break;
+                }
             }
-            else if (spins < 0)
-                spins = (p == whead) ? SPINS : 0;
-            else if (node == null)
-                node = new WNode(WMODE, p);
-            else if (node.prev != p)
-                node.prev = p;
-            else if (p.mode == RMODE && p != whead) {
-                WNode pp = p.prev;  // become co-waiter with group p
-                if (pp != null && p == wtail &&
-                    U.compareAndSwapObject(p, WCOWAIT,
-                                           node.cowait = p.cowait, node)) {
-                    node.thread = Thread.currentThread();
-                    for (long time;;) {
+            else if (!U.compareAndSwapObject(p, WCOWAIT,
+                                             node.cowait = p.cowait, node))
+                node.cowait = null;
+            else {
+                for (;;) {
+                    WNode pp, c; Thread w;
+                    if ((h = whead) != null && (c = h.cowait) != null &&
+                        U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) &&
+                        (w = c.thread) != null) // help release
+                        U.unpark(w);
+                    if (h == (pp = p.prev) || h == p || pp == null) {
+                        long m, s, ns;
+                        do {
+                            if ((m = (s = state) & ABITS) < RFULL ?
+                                U.compareAndSwapLong(this, STATE, s,
+                                                     ns = s + RUNIT) :
+                                (m < WBIT &&
+                                 (ns = tryIncReaderOverflow(s)) != 0L))
+                                return ns;
+                        } while (m < WBIT);
+                    }
+                    if (whead == h && p.prev == pp) {
+                        long time;
+                        if (pp == null || h == p || p.status > 0) {
+                            node = null; // throw away
+                            break;
+                        }
                         if (deadline == 0L)
                             time = 0L;
                         else if ((time = deadline - System.nanoTime()) <= 0L)
                             return cancelWaiter(node, p, false);
-                        if (node.thread == null)
-                            break;
-                        if (p.prev != pp || p.status == CANCELLED ||
-                            p == whead || p.prev != pp) {
-                            node.thread = null;
-                            break;
-                        }
                         Thread wt = Thread.currentThread();
                         U.putObject(wt, PARKBLOCKER, this);
-                        if (node.thread == null) // must recheck
-                            break;
-                        U.park(false, time);
+                        node.thread = wt;
+                        if ((h != pp || (state & ABITS) == WBIT) &&
+                            whead == h && p.prev == pp)
+                            U.park(false, time);
+                        node.thread = null;
                         U.putObject(wt, PARKBLOCKER, null);
                         if (interruptible && Thread.interrupted())
                             return cancelWaiter(node, p, true);
                     }
-                    group = p;
                 }
-                node = null; // throw away
-            }
-            else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
-                p.next = node;
-                break;
             }
         }
 
-        for (int spins = SPINS;;) {
-            WNode np, pp, r; int ps; long m, s, ns; Thread w;
-            while ((np = node.prev) != p && np != null)
-                (p = np).next = node;
-            if (whead == p) {
-                for (int k = spins;;) {
-                    if ((m = (s = state) & ABITS) != WBIT) {
-                        if (m < RFULL ?
-                            U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT):
-                            (ns = tryIncReaderOverflow(s)) != 0L) {
-                            whead = node;
-                            node.prev = null;
-                            while ((r = node.cowait) != null) {
-                                if (U.compareAndSwapObject(node, WCOWAIT,
-                                                           r, r.cowait) &&
-                                    (w = r.thread) != null) {
-                                    r.thread = null;
-                                    U.unpark(w); // release co-waiter
-                                }
-                            }
-                            return ns;
+        for (int spins = -1;;) {
+            WNode h, np, pp; int ps;
+            if ((h = whead) == p) {
+                if (spins < 0)
+                    spins = HEAD_SPINS;
+                else if (spins < MAX_HEAD_SPINS)
+                    spins <<= 1;
+                for (int k = spins;;) { // spin at head
+                    long m, s, ns;
+                    if ((m = (s = state) & ABITS) < RFULL ?
+                        U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
+                        (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
+                        WNode c; Thread w;
+                        whead = node;
+                        node.prev = null;
+                        while ((c = node.cowait) != null) {
+                            if (U.compareAndSwapObject(node, WCOWAIT,
+                                                       c, c.cowait) &&
+                                (w = c.thread) != null)
+                                U.unpark(w);
                         }
+                        return ns;
                     }
-                    else if (LockSupport.nextSecondarySeed() >= 0 &&
-                             --k <= 0)
+                    else if (m >= WBIT &&
+                             LockSupport.nextSecondarySeed() >= 0 && --k <= 0)
                         break;
                 }
-                if (spins < MAX_HEAD_SPINS)
-                    spins <<= 1;
             }
-            if ((ps = p.status) == 0)
-                U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
-            else if (ps == CANCELLED) {
-                if ((pp = p.prev) != null) {
-                    node.prev = pp;
-                    pp.next = node;
+            else if (h != null) {
+                WNode c; Thread w;
+                while ((c = h.cowait) != null) {
+                    if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) &&
+                        (w = c.thread) != null)
+                        U.unpark(w);
                 }
             }
-            else {
-                long time;
-                if (deadline == 0L)
-                    time = 0L;
-                else if ((time = deadline - System.nanoTime()) <= 0L)
-                    return cancelWaiter(node, node, false);
-                Thread wt = Thread.currentThread();
-                U.putObject(wt, PARKBLOCKER, this);
-                node.thread = wt;
-                if (node.prev == p && p.status == WAITING &&
-                    (p != whead || (state & ABITS) != WBIT))
-                    U.park(false, time);
-                node.thread = null;
-                U.putObject(wt, PARKBLOCKER, null);
-                if (interruptible && Thread.interrupted())
-                    return cancelWaiter(node, node, true);
+            if (whead == h) {
+                if ((np = node.prev) != p) {
+                    if (np != null)
+                        (p = np).next = node;   // stale
+                }
+                else if ((ps = p.status) == 0)
+                    U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
+                else if (ps == CANCELLED) {
+                    if ((pp = p.prev) != null) {
+                        node.prev = pp;
+                        pp.next = node;
+                    }
+                }
+                else {
+                    long time;
+                    if (deadline == 0L)
+                        time = 0L;
+                    else if ((time = deadline - System.nanoTime()) <= 0L)
+                        return cancelWaiter(node, node, false);
+                    Thread wt = Thread.currentThread();
+                    U.putObject(wt, PARKBLOCKER, this);
+                    node.thread = wt;
+                    if (p.status < 0 &&
+                        (p != h || (state & ABITS) == WBIT) &&
+                        whead == h && node.prev == p)
+                        U.park(false, time);
+                    node.thread = null;
+                    U.putObject(wt, PARKBLOCKER, null);
+                    if (interruptible && Thread.interrupted())
+                        return cancelWaiter(node, node, true);
+                }
             }
         }
     }
@@ -1278,22 +1313,19 @@
         if (node != null && group != null) {
             Thread w;
             node.status = CANCELLED;
-            node.thread = null;
             // unsplice cancelled nodes from group
             for (WNode p = group, q; (q = p.cowait) != null;) {
-                if (q.status == CANCELLED)
-                    U.compareAndSwapObject(p, WNEXT, q, q.next);
+                if (q.status == CANCELLED) {
+                    U.compareAndSwapObject(p, WCOWAIT, q, q.cowait);
+                    p = group; // restart
+                }
                 else
                     p = q;
             }
             if (group == node) {
-                WNode r; // detach and wake up uncancelled co-waiters
-                while ((r = node.cowait) != null) {
-                    if (U.compareAndSwapObject(node, WCOWAIT, r, r.cowait) &&
-                        (w = r.thread) != null) {
-                        r.thread = null;
-                        U.unpark(w);
-                    }
+                for (WNode r = group.cowait; r != null; r = r.cowait) {
+                    if ((w = r.thread) != null)
+                        U.unpark(w);       // wake up uncancelled co-waiters
                 }
                 for (WNode pred = node.prev; pred != null; ) { // unsplice
                     WNode succ, pp;        // find valid successor
--- a/src/share/classes/java/util/jar/JarVerifier.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/jar/JarVerifier.java	Fri Sep 06 15:09:44 2013 -0700
@@ -32,6 +32,7 @@
 import java.security.cert.CertificateException;
 import java.util.zip.ZipEntry;
 
+import sun.misc.JarIndex;
 import sun.security.util.ManifestDigester;
 import sun.security.util.ManifestEntryVerifier;
 import sun.security.util.SignatureFileVerifier;
@@ -139,7 +140,8 @@
                     return;
                 }
 
-                if (uname.equals(JarFile.MANIFEST_NAME)) {
+                if (uname.equals(JarFile.MANIFEST_NAME) ||
+                        uname.equals(JarIndex.INDEX_NAME)) {
                     return;
                 }
 
--- a/src/share/classes/java/util/logging/Logger.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/logging/Logger.java	Fri Sep 06 15:09:44 2013 -0700
@@ -457,13 +457,15 @@
      *                          of the subsystem, such as java.net
      *                          or javax.swing
      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
-     *                          messages for this logger. May be <CODE>null</CODE> if none of
-     *                          the messages require localization.
+     *                          messages for this logger. May be {@code null}
+     *                          if none of the messages require localization.
      * @return a suitable Logger
      * @throws MissingResourceException if the resourceBundleName is non-null and
      *             no corresponding resource can be found.
      * @throws IllegalArgumentException if the Logger already exists and uses
-     *             a different resource bundle name.
+     *             a different resource bundle name; or if
+     *             {@code resourceBundleName} is {@code null} but the named
+     *             logger has a resource bundle set.
      * @throws NullPointerException if the name is null.
      */
 
@@ -1731,10 +1733,6 @@
     // Synchronized to prevent races in setting the fields.
     private synchronized void setupResourceInfo(String name,
                                                 Class<?> callersClass) {
-        if (name == null) {
-            return;
-        }
-
         if (resourceBundleName != null) {
             // this Logger already has a ResourceBundle
 
@@ -1748,6 +1746,10 @@
                 resourceBundleName + " != " + name);
         }
 
+        if (name == null) {
+            return;
+        }
+
         setCallersClassLoaderRef(callersClass);
         if (findResourceBundle(name, true) == null) {
             // We've failed to find an expected ResourceBundle.
--- a/src/share/classes/java/util/regex/Pattern.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/regex/Pattern.java	Fri Sep 06 15:09:44 2013 -0700
@@ -219,7 +219,7 @@
  *
  * <tr><th>&nbsp;</th></tr>
  * <tr align="left"><th colspan="2" id="unicode">Classes for Unicode scripts, blocks, categories and binary properties</th></tr>
- * * <tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td>
  *     <td headers="matches">A Latin&nbsp;script character (<a href="#usc">script</a>)</td></tr>
  * <tr><td valign="top" headers="construct unicode">{@code \p{InGreek}}</td>
  *     <td headers="matches">A character in the Greek&nbsp;block (<a href="#ubc">block</a>)</td></tr>
@@ -4456,16 +4456,16 @@
                             groups[groupIndex+1] = i;
                             groups[groupIndex] = i - k;
                         }
-                        i = i - k;
                         return true;
                     }
                     // backing off
+                    i = i - k;
                     if (capture) {
                         groups[groupIndex+1] = i;
                         groups[groupIndex] = i - k;
                     }
-                    i = i - k;
                     j--;
+
                 }
                 break;
             }
@@ -4883,7 +4883,6 @@
             int k = matcher.groups[groupIndex+1];
 
             int groupSize = k - j;
-
             // If the referenced group didn't match, neither can this
             if (j < 0)
                 return false;
@@ -4893,7 +4892,6 @@
                 matcher.hitEnd = true;
                 return false;
             }
-
             // Check each new char to make sure it matches what the group
             // referenced matched last time around
             for (int index=0; index<groupSize; index++)
--- a/src/share/classes/java/util/stream/Collectors.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/stream/Collectors.java	Fri Sep 06 15:09:44 2013 -0700
@@ -137,6 +137,11 @@
         return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
     }
 
+    @SuppressWarnings("unchecked")
+    private static <I, R> Function<I, R> castingIdentity() {
+        return i -> (R) i;
+    }
+
     /**
      * Simple implementation class for {@code Collector}.
      *
@@ -166,7 +171,7 @@
                       BiConsumer<A, T> accumulator,
                       BinaryOperator<A> combiner,
                       Set<Characteristics> characteristics) {
-            this(supplier, accumulator, combiner, i -> (R) i, characteristics);
+            this(supplier, accumulator, combiner, castingIdentity(), characteristics);
         }
 
         @Override
@@ -209,7 +214,7 @@
      */
     public static <T, C extends Collection<T>>
     Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
-        return new CollectorImpl<>(collectionFactory, Collection::add,
+        return new CollectorImpl<>(collectionFactory, Collection<T>::add,
                                    (r1, r2) -> { r1.addAll(r2); return r1; },
                                    CH_ID);
     }
@@ -1046,30 +1051,23 @@
     public static <T, D, A>
     Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
                                                     Collector<? super T, A, D> downstream) {
-        @SuppressWarnings("unchecked")
-        BiConsumer<D, ? super T> downstreamAccumulator = (BiConsumer<D, ? super T>) downstream.accumulator();
-        BiConsumer<Map<Boolean, A>, T> accumulator = (result, t) -> {
-            Partition<D> asPartition = ((Partition<D>) result);
-            downstreamAccumulator.accept(predicate.test(t) ? asPartition.forTrue : asPartition.forFalse, t);
-        };
+        BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
+        BiConsumer<Partition<A>, T> accumulator = (result, t) ->
+                downstreamAccumulator.accept(predicate.test(t) ? result.forTrue : result.forFalse, t);
         BinaryOperator<A> op = downstream.combiner();
-        BinaryOperator<Map<Boolean, A>> merger = (m1, m2) -> {
-            Partition<A> left = (Partition<A>) m1;
-            Partition<A> right = (Partition<A>) m2;
-            return new Partition<>(op.apply(left.forTrue, right.forTrue),
-                                   op.apply(left.forFalse, right.forFalse));
-        };
-        Supplier<Map<Boolean, A>> supplier = () -> new Partition<>(downstream.supplier().get(),
-                                                                   downstream.supplier().get());
+        BinaryOperator<Partition<A>> merger = (left, right) ->
+                new Partition<>(op.apply(left.forTrue, right.forTrue),
+                                op.apply(left.forFalse, right.forFalse));
+        Supplier<Partition<A>> supplier = () ->
+                new Partition<>(downstream.supplier().get(),
+                                downstream.supplier().get());
         if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
             return new CollectorImpl<>(supplier, accumulator, merger, CH_ID);
         }
         else {
-            Function<Map<Boolean, A>, Map<Boolean, D>> finisher = (Map<Boolean, A> par) -> {
-                Partition<A> asAPartition = (Partition<A>) par;
-                return new Partition<>(downstream.finisher().apply(asAPartition.forTrue),
-                                       downstream.finisher().apply(asAPartition.forFalse));
-            };
+            Function<Partition<A>, Map<Boolean, D>> finisher = par ->
+                    new Partition<>(downstream.finisher().apply(par.forTrue),
+                                    downstream.finisher().apply(par.forFalse));
             return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID);
         }
     }
--- a/src/share/classes/java/util/stream/DistinctOps.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/stream/DistinctOps.java	Fri Sep 06 15:09:44 2013 -0700
@@ -101,7 +101,7 @@
                 if (StreamOpFlag.DISTINCT.isKnown(flags)) {
                     return sink;
                 } else if (StreamOpFlag.SORTED.isKnown(flags)) {
-                    return new Sink.ChainedReference<T>(sink) {
+                    return new Sink.ChainedReference<T, T>(sink) {
                         boolean seenNull;
                         T lastSeen;
 
@@ -132,7 +132,7 @@
                         }
                     };
                 } else {
-                    return new Sink.ChainedReference<T>(sink) {
+                    return new Sink.ChainedReference<T, T>(sink) {
                         Set<T> seen;
 
                         @Override
--- a/src/share/classes/java/util/stream/DoublePipeline.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/stream/DoublePipeline.java	Fri Sep 06 15:09:44 2013 -0700
@@ -191,7 +191,7 @@
                                        StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedDouble(sink) {
+                return new Sink.ChainedDouble<Double>(sink) {
                     @Override
                     public void accept(double t) {
                         downstream.accept(mapper.applyAsDouble(t));
@@ -208,9 +208,8 @@
                                                             StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Double> opWrapSink(int flags, Sink<U> sink) {
-                return new Sink.ChainedDouble(sink) {
+                return new Sink.ChainedDouble<U>(sink) {
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(double t) {
                         downstream.accept(mapper.apply(t));
                     }
@@ -226,7 +225,7 @@
                                                    StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Double> opWrapSink(int flags, Sink<Integer> sink) {
-                return new Sink.ChainedDouble(sink) {
+                return new Sink.ChainedDouble<Integer>(sink) {
                     @Override
                     public void accept(double t) {
                         downstream.accept(mapper.applyAsInt(t));
@@ -243,7 +242,7 @@
                                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Double> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedDouble(sink) {
+                return new Sink.ChainedDouble<Long>(sink) {
                     @Override
                     public void accept(double t) {
                         downstream.accept(mapper.applyAsLong(t));
@@ -259,7 +258,7 @@
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedDouble(sink) {
+                return new Sink.ChainedDouble<Double>(sink) {
                     @Override
                     public void begin(long size) {
                         downstream.begin(-1);
@@ -296,7 +295,7 @@
                                        StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedDouble(sink) {
+                return new Sink.ChainedDouble<Double>(sink) {
                     @Override
                     public void begin(long size) {
                         downstream.begin(-1);
@@ -319,7 +318,7 @@
                                        0) {
             @Override
             Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedDouble(sink) {
+                return new Sink.ChainedDouble<Double>(sink) {
                     @Override
                     public void accept(double t) {
                         consumer.accept(t);
--- a/src/share/classes/java/util/stream/IntPipeline.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/stream/IntPipeline.java	Fri Sep 06 15:09:44 2013 -0700
@@ -189,9 +189,8 @@
                                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<Long>(sink) {
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(int t) {
                         downstream.accept((long) t);
                     }
@@ -206,9 +205,8 @@
                                                        StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<Double>(sink) {
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(int t) {
                         downstream.accept((double) t);
                     }
@@ -229,7 +227,7 @@
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<Integer>(sink) {
                     @Override
                     public void accept(int t) {
                         downstream.accept(mapper.applyAsInt(t));
@@ -246,9 +244,8 @@
                                                              StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<U>(sink) {
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(int t) {
                         downstream.accept(mapper.apply(t));
                     }
@@ -264,7 +261,7 @@
                                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<Long>(sink) {
                     @Override
                     public void accept(int t) {
                         downstream.accept(mapper.applyAsLong(t));
@@ -281,7 +278,7 @@
                                                        StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<Double>(sink) {
                     @Override
                     public void accept(int t) {
                         downstream.accept(mapper.applyAsDouble(t));
@@ -297,7 +294,7 @@
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<Integer>(sink) {
                     @Override
                     public void begin(long size) {
                         downstream.begin(-1);
@@ -334,7 +331,7 @@
                                         StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<Integer>(sink) {
                     @Override
                     public void begin(long size) {
                         downstream.begin(-1);
@@ -357,7 +354,7 @@
                                         0) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<Integer>(sink) {
                     @Override
                     public void accept(int t) {
                         consumer.accept(t);
--- a/src/share/classes/java/util/stream/LongPipeline.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/stream/LongPipeline.java	Fri Sep 06 15:09:44 2013 -0700
@@ -186,7 +186,7 @@
                                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedLong(sink) {
+                return new Sink.ChainedLong<Double>(sink) {
                     @Override
                     public void accept(long t) {
                         downstream.accept((double) t);
@@ -208,9 +208,8 @@
                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedLong(sink) {
+                return new Sink.ChainedLong<Long>(sink) {
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(long t) {
                         downstream.accept(mapper.applyAsLong(t));
                     }
@@ -226,9 +225,8 @@
                                                           StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<U> sink) {
-                return new Sink.ChainedLong(sink) {
+                return new Sink.ChainedLong<U>(sink) {
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(long t) {
                         downstream.accept(mapper.apply(t));
                     }
@@ -244,9 +242,8 @@
                                                  StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Integer> sink) {
-                return new Sink.ChainedLong(sink) {
+                return new Sink.ChainedLong<Integer>(sink) {
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(long t) {
                         downstream.accept(mapper.applyAsInt(t));
                     }
@@ -262,7 +259,7 @@
                                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedLong(sink) {
+                return new Sink.ChainedLong<Double>(sink) {
                     @Override
                     public void accept(long t) {
                         downstream.accept(mapper.applyAsDouble(t));
@@ -278,7 +275,7 @@
                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedLong(sink) {
+                return new Sink.ChainedLong<Long>(sink) {
                     @Override
                     public void begin(long size) {
                         downstream.begin(-1);
@@ -315,7 +312,7 @@
                                      StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedLong(sink) {
+                return new Sink.ChainedLong<Long>(sink) {
                     @Override
                     public void begin(long size) {
                         downstream.begin(-1);
@@ -338,7 +335,7 @@
                                      0) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedLong(sink) {
+                return new Sink.ChainedLong<Long>(sink) {
                     @Override
                     public void accept(long t) {
                         consumer.accept(t);
--- a/src/share/classes/java/util/stream/ReferencePipeline.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/stream/ReferencePipeline.java	Fri Sep 06 15:09:44 2013 -0700
@@ -163,17 +163,16 @@
                                      StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
                     @Override
                     public void begin(long size) {
                         downstream.begin(-1);
                     }
 
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(P_OUT u) {
                         if (predicate.test(u))
-                            downstream.accept((Object) u);
+                            downstream.accept(u);
                     }
                 };
             }
@@ -188,7 +187,7 @@
                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, R>(sink) {
                     @Override
                     public void accept(P_OUT u) {
                         downstream.accept(mapper.apply(u));
@@ -205,7 +204,7 @@
                                               StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, Integer>(sink) {
                     @Override
                     public void accept(P_OUT u) {
                         downstream.accept(mapper.applyAsInt(u));
@@ -222,7 +221,7 @@
                                       StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, Long>(sink) {
                     @Override
                     public void accept(P_OUT u) {
                         downstream.accept(mapper.applyAsLong(u));
@@ -239,7 +238,7 @@
                                         StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, Double>(sink) {
                     @Override
                     public void accept(P_OUT u) {
                         downstream.accept(mapper.applyAsDouble(u));
@@ -257,14 +256,13 @@
                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, R>(sink) {
                     @Override
                     public void begin(long size) {
                         downstream.begin(-1);
                     }
 
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(P_OUT u) {
                         // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
                         Stream<? extends R> result = mapper.apply(u);
@@ -284,7 +282,7 @@
                                               StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, Integer>(sink) {
                     IntConsumer downstreamAsInt = downstream::accept;
                     @Override
                     public void begin(long size) {
@@ -311,7 +309,7 @@
                                                      StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, Double>(sink) {
                     DoubleConsumer downstreamAsDouble = downstream::accept;
                     @Override
                     public void begin(long size) {
@@ -338,7 +336,7 @@
                                                    StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, Long>(sink) {
                     LongConsumer downstreamAsLong = downstream::accept;
                     @Override
                     public void begin(long size) {
@@ -364,9 +362,8 @@
                                      0) {
             @Override
             Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
-                return new Sink.ChainedReference<P_OUT>(sink) {
+                return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
                     @Override
-                    @SuppressWarnings("unchecked")
                     public void accept(P_OUT u) {
                         tee.accept(u);
                         downstream.accept(u);
@@ -495,6 +492,7 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public final <R, A> R collect(Collector<? super P_OUT, A, ? extends R> collector) {
         A container;
         if (isParallel()
--- a/src/share/classes/java/util/stream/Sink.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/stream/Sink.java	Fri Sep 06 15:09:44 2013 -0700
@@ -241,11 +241,10 @@
      * implementation of the {@code accept()} method must call the correct
      * {@code accept()} method on the downstream {@code Sink}.
      */
-    static abstract class ChainedReference<T> implements Sink<T> {
-        @SuppressWarnings("rawtypes")
-        protected final Sink downstream;
+    static abstract class ChainedReference<T, E_OUT> implements Sink<T> {
+        protected final Sink<? super E_OUT> downstream;
 
-        public ChainedReference(Sink downstream) {
+        public ChainedReference(Sink<? super E_OUT> downstream) {
             this.downstream = Objects.requireNonNull(downstream);
         }
 
@@ -274,11 +273,10 @@
      * The implementation of the {@code accept()} method must call the correct
      * {@code accept()} method on the downstream {@code Sink}.
      */
-    static abstract class ChainedInt implements Sink.OfInt {
-        @SuppressWarnings("rawtypes")
-        protected final Sink downstream;
+    static abstract class ChainedInt<E_OUT> implements Sink.OfInt {
+        protected final Sink<? super E_OUT> downstream;
 
-        public ChainedInt(Sink downstream) {
+        public ChainedInt(Sink<? super E_OUT> downstream) {
             this.downstream = Objects.requireNonNull(downstream);
         }
 
@@ -307,11 +305,10 @@
      * The implementation of the {@code accept()} method must call the correct
      * {@code accept()} method on the downstream {@code Sink}.
      */
-    static abstract class ChainedLong implements Sink.OfLong {
-        @SuppressWarnings("rawtypes")
-        protected final Sink downstream;
+    static abstract class ChainedLong<E_OUT> implements Sink.OfLong {
+        protected final Sink<? super E_OUT> downstream;
 
-        public ChainedLong(Sink downstream) {
+        public ChainedLong(Sink<? super E_OUT> downstream) {
             this.downstream = Objects.requireNonNull(downstream);
         }
 
@@ -340,11 +337,10 @@
      * The implementation of the {@code accept()} method must call the correct
      * {@code accept()} method on the downstream {@code Sink}.
      */
-    static abstract class ChainedDouble implements Sink.OfDouble {
-        @SuppressWarnings("rawtypes")
-        protected final Sink downstream;
+    static abstract class ChainedDouble<E_OUT> implements Sink.OfDouble {
+        protected final Sink<? super E_OUT> downstream;
 
-        public ChainedDouble(Sink downstream) {
+        public ChainedDouble(Sink<? super E_OUT> downstream) {
             this.downstream = Objects.requireNonNull(downstream);
         }
 
--- a/src/share/classes/java/util/stream/SliceOps.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/stream/SliceOps.java	Fri Sep 06 15:09:44 2013 -0700
@@ -96,6 +96,11 @@
         }
     }
 
+    @SuppressWarnings("unchecked")
+    private static <T> IntFunction<T[]> castingArray() {
+        return size -> (T[]) new Object[size];
+    }
+
     /**
      * Appends a "slice" operation to the provided stream.  The slice operation
      * may be may be skip-only, limit-only, or skip-and-limit.
@@ -107,12 +112,12 @@
      *        is to be imposed
      */
     public static <T> Stream<T> makeRef(AbstractPipeline<?, T, ?> upstream,
-                                       long skip, long limit) {
+                                        long skip, long limit) {
         if (skip < 0)
             throw new IllegalArgumentException("Skip must be non-negative: " + skip);
 
-        return new ReferencePipeline.StatefulOp<T,T>(upstream, StreamShape.REFERENCE,
-                                                     flags(limit)) {
+        return new ReferencePipeline.StatefulOp<T, T>(upstream, StreamShape.REFERENCE,
+                                                      flags(limit)) {
             Spliterator<T> unorderedSkipLimitSpliterator(Spliterator<T> s,
                                                          long skip, long limit, long sizeIfKnown) {
                 if (skip <= sizeIfKnown) {
@@ -146,7 +151,7 @@
                     //     cancellation will be more aggressive cancelling later tasks
                     //     if the target slice size has been reached from a given task,
                     //     cancellation should also clear local results if any
-                    return new SliceTask<>(this, helper, spliterator, i -> (T[]) new Object[i], skip, limit).
+                    return new SliceTask<>(this, helper, spliterator, castingArray(), skip, limit).
                             invoke().spliterator();
                 }
             }
@@ -182,7 +187,7 @@
 
             @Override
             Sink<T> opWrapSink(int flags, Sink<T> sink) {
-                return new Sink.ChainedReference<T>(sink) {
+                return new Sink.ChainedReference<T, T>(sink) {
                     long n = skip;
                     long m = limit >= 0 ? limit : Long.MAX_VALUE;
 
@@ -291,7 +296,7 @@
 
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
-                return new Sink.ChainedInt(sink) {
+                return new Sink.ChainedInt<Integer>(sink) {
                     long n = skip;
                     long m = limit >= 0 ? limit : Long.MAX_VALUE;
 
@@ -400,7 +405,7 @@
 
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
-                return new Sink.ChainedLong(sink) {
+                return new Sink.ChainedLong<Long>(sink) {
                     long n = skip;
                     long m = limit >= 0 ? limit : Long.MAX_VALUE;
 
@@ -509,7 +514,7 @@
 
             @Override
             Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
-                return new Sink.ChainedDouble(sink) {
+                return new Sink.ChainedDouble<Double>(sink) {
                     long n = skip;
                     long m = limit >= 0 ? limit : Long.MAX_VALUE;
 
@@ -560,13 +565,13 @@
 
         private volatile boolean completed;
 
-        SliceTask(AbstractPipeline<?, P_OUT, ?> op,
+        SliceTask(AbstractPipeline<P_OUT, P_OUT, ?> op,
                   PipelineHelper<P_OUT> helper,
                   Spliterator<P_IN> spliterator,
                   IntFunction<P_OUT[]> generator,
                   long offset, long size) {
             super(helper, spliterator);
-            this.op = (AbstractPipeline<P_OUT, P_OUT, ?>) op;
+            this.op = op;
             this.generator = generator;
             this.targetOffset = offset;
             this.targetSize = size;
--- a/src/share/classes/java/util/stream/SortedOps.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/stream/SortedOps.java	Fri Sep 06 15:09:44 2013 -0700
@@ -129,7 +129,7 @@
         }
 
         @Override
-        public Sink<T> opWrapSink(int flags, Sink sink) {
+        public Sink<T> opWrapSink(int flags, Sink<T> sink) {
             Objects.requireNonNull(sink);
 
             // If the input is already naturally sorted and this operation
@@ -280,12 +280,12 @@
     /**
      * {@link ForkJoinTask} for implementing sort on SIZED reference streams.
      */
-    private static final class SizedRefSortingSink<T> extends Sink.ChainedReference<T> {
+    private static final class SizedRefSortingSink<T> extends Sink.ChainedReference<T, T> {
         private final Comparator<? super T> comparator;
         private T[] array;
         private int offset;
 
-        SizedRefSortingSink(Sink<T> sink, Comparator<? super T> comparator) {
+        SizedRefSortingSink(Sink<? super T> sink, Comparator<? super T> comparator) {
             super(sink);
             this.comparator = comparator;
         }
@@ -320,11 +320,11 @@
     /**
      * {@link Sink} for implementing sort on reference streams.
      */
-    private static final class RefSortingSink<T> extends Sink.ChainedReference<T> {
+    private static final class RefSortingSink<T> extends Sink.ChainedReference<T, T> {
         private final Comparator<? super T> comparator;
         private ArrayList<T> list;
 
-        RefSortingSink(Sink<T> sink, Comparator<? super T> comparator) {
+        RefSortingSink(Sink<? super T> sink, Comparator<? super T> comparator) {
             super(sink);
             this.comparator = comparator;
         }
@@ -352,11 +352,11 @@
     /**
      * {@link Sink} for implementing sort on SIZED int streams.
      */
-    private static final class SizedIntSortingSink extends Sink.ChainedInt {
+    private static final class SizedIntSortingSink extends Sink.ChainedInt<Integer> {
         private int[] array;
         private int offset;
 
-        SizedIntSortingSink(Sink downstream) {
+        SizedIntSortingSink(Sink<? super Integer> downstream) {
             super(downstream);
         }
 
@@ -386,10 +386,10 @@
     /**
      * {@link Sink} for implementing sort on int streams.
      */
-    private static final class IntSortingSink extends Sink.ChainedInt {
+    private static final class IntSortingSink extends Sink.ChainedInt<Integer> {
         private SpinedBuffer.OfInt b;
 
-        IntSortingSink(Sink sink) {
+        IntSortingSink(Sink<? super Integer> sink) {
             super(sink);
         }
 
@@ -417,11 +417,11 @@
     /**
      * {@link Sink} for implementing sort on SIZED long streams.
      */
-    private static final class SizedLongSortingSink extends Sink.ChainedLong {
+    private static final class SizedLongSortingSink extends Sink.ChainedLong<Long> {
         private long[] array;
         private int offset;
 
-        SizedLongSortingSink(Sink downstream) {
+        SizedLongSortingSink(Sink<? super Long> downstream) {
             super(downstream);
         }
 
@@ -451,10 +451,10 @@
     /**
      * {@link Sink} for implementing sort on long streams.
      */
-    private static final class LongSortingSink extends Sink.ChainedLong {
+    private static final class LongSortingSink extends Sink.ChainedLong<Long> {
         private SpinedBuffer.OfLong b;
 
-        LongSortingSink(Sink sink) {
+        LongSortingSink(Sink<? super Long> sink) {
             super(sink);
         }
 
@@ -482,11 +482,11 @@
     /**
      * {@link Sink} for implementing sort on SIZED double streams.
      */
-    private static final class SizedDoubleSortingSink extends Sink.ChainedDouble {
+    private static final class SizedDoubleSortingSink extends Sink.ChainedDouble<Double> {
         private double[] array;
         private int offset;
 
-        SizedDoubleSortingSink(Sink downstream) {
+        SizedDoubleSortingSink(Sink<? super Double> downstream) {
             super(downstream);
         }
 
@@ -516,10 +516,10 @@
     /**
      * {@link Sink} for implementing sort on double streams.
      */
-    private static final class DoubleSortingSink extends Sink.ChainedDouble {
+    private static final class DoubleSortingSink extends Sink.ChainedDouble<Double> {
         private SpinedBuffer.OfDouble b;
 
-        DoubleSortingSink(Sink sink) {
+        DoubleSortingSink(Sink<? super Double> sink) {
             super(sink);
         }
 
--- a/src/share/classes/java/util/zip/ZipOutputStream.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/java/util/zip/ZipOutputStream.java	Fri Sep 06 15:09:44 2013 -0700
@@ -663,6 +663,9 @@
         while (off + 4 <= len) {
             int tag = get16(extra, off);
             int sz = get16(extra, off + 2);
+            if (sz < 0 || (off + 4 + sz) > len) {
+                break;
+            }
             if (tag == EXTID_EXTT || tag == EXTID_ZIP64) {
                 skipped += (sz + 4);
             }
@@ -684,11 +687,18 @@
             while (off + 4 <= len) {
                 int tag = get16(extra, off);
                 int sz = get16(extra, off + 2);
+                if (sz < 0 || (off + 4 + sz) > len) {
+                    writeBytes(extra, off, len - off);
+                    return;
+                }
                 if (tag != EXTID_EXTT && tag != EXTID_ZIP64) {
                     writeBytes(extra, off, sz + 4);
                 }
                 off += (sz + 4);
             }
+            if (off < len) {
+                writeBytes(extra, off, len - off);
+            }
         }
     }
 
--- a/src/share/classes/javax/net/ssl/SNIHostName.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/javax/net/ssl/SNIHostName.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -293,6 +293,7 @@
      *         the <a href="{@docRoot}/java/util/regex/Pattern.html#sum">
      *         regular expression pattern</a>
      *         representing the hostname(s) to match
+     * @return a {@code SNIMatcher} object for {@code SNIHostName}s
      * @throws NullPointerException if {@code regex} is
      *         {@code null}
      * @throws java.util.regex.PatternSyntaxException if the regular expression's
--- a/src/share/classes/javax/net/ssl/X509KeyManager.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/javax/net/ssl/X509KeyManager.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
  * <UL>
  * <LI> determine the set of aliases that are available for negotiations
  *      based on the criteria presented,
- * <LI> select the <ITALIC> best alias </ITALIC> based on
+ * <LI> select the <i> best alias</i> based on
  *      the criteria presented, and
  * <LI> obtain the corresponding key material for given aliases.
  * </UL>
--- a/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java	Fri Sep 06 15:09:44 2013 -0700
@@ -197,8 +197,7 @@
      * {@code KerberosPrincipal} and the two
      * {@code KerberosPrincipal} instances are equivalent.
      * More formally two {@code KerberosPrincipal} instances are equal
-     * if the values returned by {@code getName()} are equal and the
-     * values returned by {@code getNameType()} are equal.
+     * if the values returned by {@code getName()} are equal.
      *
      * @param other the Object to compare to
      * @return true if the Object passed in represents the same principal
@@ -211,15 +210,10 @@
 
         if (! (other instanceof KerberosPrincipal)) {
             return false;
-        } else {
-            String myFullName = getName();
-            String otherFullName = ((KerberosPrincipal) other).getName();
-            if (nameType == ((KerberosPrincipal)other).nameType &&
-                myFullName.equals(otherFullName)) {
-                 return true;
-            }
         }
-        return false;
+        String myFullName = getName();
+        String otherFullName = ((KerberosPrincipal) other).getName();
+        return myFullName.equals(otherFullName);
     }
 
     /**
--- a/src/share/classes/sun/misc/Compare.java	Thu Sep 05 15:37:40 2013 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 1996, 1997, 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.
- */
-
-/**
- * Compare: an interface to enable users to define the result of
- *          a comparison of two objects.
- *
- * @author Sunita Mani
- */
-
-package sun.misc;
-
-public interface Compare {
-
-    /**
-     * doCompare
-     *
-     * @param  obj1 first object to compare.
-     * @param  obj2 second object to compare.
-     * @return -1 if obj1 < obj2, 0 if obj1 == obj2, 1 if obj1 > obj2.
-     */
-    public int doCompare(Object obj1, Object obj2);
-
-}
--- a/src/share/classes/sun/misc/Sort.java	Thu Sep 05 15:37:40 2013 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 1996, 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.
- */
-
-/**
- * Sort: a class that uses the quicksort algorithm to sort an
- *       array of objects.
- *
- * @author Sunita Mani
- */
-
-package sun.misc;
-
-public class Sort {
-
-    private static void swap(Object arr[], int i, int j) {
-        Object tmp;
-
-        tmp = arr[i];
-        arr[i] = arr[j];
-        arr[j] = tmp;
-    }
-
-    /**
-     * quicksort the array of objects.
-     *
-     * @param arr[] - an array of objects
-     * @param left - the start index - from where to begin sorting
-     * @param right - the last index.
-     * @param comp - an object that implemnts the Compare interface to resolve thecomparison.
-     */
-    public static void quicksort(Object arr[], int left, int right, Compare comp) {
-        int i, last;
-
-        if (left >= right) { /* do nothing if array contains fewer than two */
-            return;          /* two elements */
-        }
-        swap(arr, left, (left+right) / 2);
-        last = left;
-        for (i = left+1; i <= right; i++) {
-            if (comp.doCompare(arr[i], arr[left]) < 0) {
-                swap(arr, ++last, i);
-            }
-        }
-        swap(arr, left, last);
-        quicksort(arr, left, last-1, comp);
-        quicksort(arr, last+1, right, comp);
-    }
-
-    public static void quicksort(Object arr[], Compare comp) {
-        quicksort(arr, 0, arr.length-1, comp);
-    }
-}
--- a/src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -193,9 +193,4 @@
         if (!selch.isOpen() && !selch.isRegistered())
             ((SelChImpl)selch).kill();
     }
-
-    static {
-        Util.load();
-    }
-
 }
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1138,7 +1138,7 @@
         throws IOException;
 
     static {
-        Util.load();
+        IOUtil.load();
         initIDs();
     }
 
--- a/src/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1162,7 +1162,7 @@
     private static native long initIDs();
 
     static {
-        Util.load();
+        IOUtil.load();
         allocationGranularity = initIDs();
     }
 
--- a/src/share/classes/sun/nio/ch/IOUtil.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/nio/ch/IOUtil.java	Fri Sep 06 15:09:44 2013 -0700
@@ -347,9 +347,23 @@
 
     static native void initIDs();
 
+    /**
+     * Used to trigger loading of native libraries
+     */
+    public static void load() { }
+
     static {
-        // Note that IOUtil.initIDs is called from within Util.load.
-        Util.load();
+        java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<Void>() {
+                    public Void run() {
+                        System.loadLibrary("net");
+                        System.loadLibrary("nio");
+                        return null;
+                    }
+                });
+
+        initIDs();
+
         IOV_MAX = iovMax();
     }
 
--- a/src/share/classes/sun/nio/ch/Net.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/nio/ch/Net.java	Fri Sep 06 15:09:44 2013 -0700
@@ -582,7 +582,7 @@
     private static native void initIDs();
 
     static {
-        Util.load();
+        IOUtil.load();
         initIDs();
     }
 
--- a/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -416,7 +416,7 @@
     private static native void initIDs();
 
     static {
-        Util.load();
+        IOUtil.load();
         initIDs();
         nd = new SocketDispatcher();
     }
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1024,7 +1024,7 @@
         throws IOException;
 
     static {
-        Util.load();
+        IOUtil.load();
         nd = new SocketDispatcher();
     }
 
--- a/src/share/classes/sun/nio/ch/Util.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/nio/ch/Util.java	Fri Sep 06 15:09:44 2013 -0700
@@ -401,30 +401,4 @@
         return bugLevel.equals(bl);
     }
 
-
-
-    // -- Initialization --
-
-    private static boolean loaded = false;
-
-    public static void load() {
-        synchronized (Util.class) {
-            if (loaded)
-                return;
-            loaded = true;
-            java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction<Void>() {
-                    public Void run() {
-                        System.loadLibrary("net");
-                        System.loadLibrary("nio");
-                        return null;
-                    }
-                });
-
-            // IOUtil must be initialized; Its native methods are called from
-            // other places in native nio code so they must be set up.
-            IOUtil.initIDs();
-        }
-    }
-
 }
--- a/src/share/classes/sun/tools/jconsole/ConnectDialog.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/tools/jconsole/ConnectDialog.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -268,8 +268,13 @@
 
     public void revalidate() {
         // Adjust some colors
+        Color disabledForeground = UIManager.getColor("Label.disabledForeground");
+        if (disabledForeground == null) {
+            // fall back for Nimbus that doesn't support 'Label.disabledForeground'
+            disabledForeground = UIManager.getColor("Label.disabledText");
+        }
         hintTextColor =
-            ensureContrast(UIManager.getColor("Label.disabledForeground"),
+            ensureContrast(disabledForeground,
                            UIManager.getColor("Panel.background"));
         disabledTableCellColor =
             ensureContrast(new Color(0x808080),
--- a/src/share/classes/sun/tools/jconsole/JConsole.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/tools/jconsole/JConsole.java	Fri Sep 06 15:09:44 2013 -0700
@@ -858,6 +858,10 @@
                 try {
                     updateInterval = Integer.parseInt(arg.substring(10)) *
                         1000;
+                    if (updateInterval <= 0) {
+                        usage();
+                        return;
+                    }
                 } catch (NumberFormatException ex) {
                     usage();
                     return;
--- a/src/share/classes/sun/tools/jconsole/Messages.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/tools/jconsole/Messages.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -146,7 +146,6 @@
     public static String HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME;
     public static String HELP_ABOUT_DIALOG_MASTHEAD_TITLE;
     public static String HELP_ABOUT_DIALOG_TITLE;
-    public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK;
     public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL;
     public static String HELP_MENU_ABOUT_TITLE;
     public static String HELP_MENU_USER_GUIDE_TITLE;
@@ -272,6 +271,7 @@
     public static String THREADS;
     public static String THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME;
     public static String THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME;
+    public static String THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE;
     public static String THRESHOLD;
     public static String TILE;
     public static String TIME_RANGE_COLON;
--- a/src/share/classes/sun/tools/jconsole/Plotter.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/tools/jconsole/Plotter.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -337,6 +337,13 @@
     public void paintComponent(Graphics g) {
         super.paintComponent(g);
 
+        int width = getWidth()-rightMargin-leftMargin-10;
+        int height = getHeight()-topMargin-bottomMargin;
+        if (width <= 0 || height <= 0) {
+            // not enough room to paint anything
+            return;
+        }
+
         Color oldColor = g.getColor();
         Font  oldFont  = g.getFont();
         Color fg = getForeground();
--- a/src/share/classes/sun/tools/jconsole/ThreadTab.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/tools/jconsole/ThreadTab.java	Fri Sep 06 15:09:44 2013 -0700
@@ -595,6 +595,8 @@
 
             setBorder(thinEmptyBorder);
 
+            setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+            textArea.setText(Messages.THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE);
             addListSelectionListener(ThreadTab.this);
             setCellRenderer(new DefaultListCellRenderer() {
                 public Component getListCellRendererComponent(JList<?> list, Object value, int index,
--- a/src/share/classes/sun/tools/jconsole/VMPanel.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/tools/jconsole/VMPanel.java	Fri Sep 06 15:09:44 2013 -0700
@@ -153,9 +153,11 @@
     // in order to reserve space for the connect toggle.
     public void setUI(TabbedPaneUI ui) {
         Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets");
-        insets = (Insets) insets.clone();
-        insets.right += connectedIcon24.getIconWidth() + 8;
-        UIManager.put("TabbedPane.tabAreaInsets", insets);
+        if (insets != null) {
+            insets = (Insets) insets.clone();
+            insets.right += connectedIcon24.getIconWidth() + 8;
+            UIManager.put("TabbedPane.tabAreaInsets", insets);
+        }
         super.setUI(ui);
     }
 
--- a/src/share/classes/sun/tools/jconsole/resources/messages.properties	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/tools/jconsole/resources/messages.properties	Fri Sep 06 15:09:44 2013 -0700
@@ -104,7 +104,6 @@
 HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=Masthead Graphic
 HELP_ABOUT_DIALOG_MASTHEAD_TITLE=About JConsole
 HELP_ABOUT_DIALOG_TITLE=JConsole: About
-HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole &User Guide:<br>{0}
 HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
 HELP_MENU_ABOUT_TITLE=&About JConsole
 HELP_MENU_USER_GUIDE_TITLE=Online &User Guide
@@ -230,6 +229,7 @@
 THREADS=Threads
 THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=Thread Information
 THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=Chart for number of threads.
+THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE=[No thread selected]
 THRESHOLD=Threshold
 TILE=&Tile
 TIME_RANGE_COLON=&Time Range:
--- a/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties	Fri Sep 06 15:09:44 2013 -0700
@@ -104,7 +104,6 @@
 HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u30DE\u30B9\u30C8\u30D8\u30C3\u30C9\u56F3\u5F62
 HELP_ABOUT_DIALOG_MASTHEAD_TITLE=JConsole\u306B\u3064\u3044\u3066
 HELP_ABOUT_DIALOG_TITLE=JConsole: \u8A73\u7D30
-HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U):<br>{0}
 HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
 HELP_MENU_ABOUT_TITLE=JConsole\u306B\u3064\u3044\u3066(&A)
 HELP_MENU_USER_GUIDE_TITLE=\u30AA\u30F3\u30E9\u30A4\u30F3\u30FB\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U)
--- a/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties	Fri Sep 06 15:09:44 2013 -0700
@@ -104,7 +104,6 @@
 HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u62A5\u5934\u56FE
 HELP_ABOUT_DIALOG_MASTHEAD_TITLE=\u5173\u4E8E JConsole
 HELP_ABOUT_DIALOG_TITLE=JConsole: \u5173\u4E8E
-HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole \u7528\u6237\u6307\u5357(&U):<br>{0}
 HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
 HELP_MENU_ABOUT_TITLE=\u5173\u4E8E JConsole(&A)
 HELP_MENU_USER_GUIDE_TITLE=\u8054\u673A\u7528\u6237\u6307\u5357(&U)
--- a/src/share/lib/security/java.security-linux	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/lib/security/java.security-linux	Fri Sep 06 15:09:44 2013 -0700
@@ -181,6 +181,7 @@
                com.sun.imageio.,\
                com.sun.istack.internal.,\
                com.sun.jmx.,\
+               com.sun.media.sound.,\
                com.sun.proxy.,\
                com.sun.org.apache.bcel.internal.,\
                com.sun.org.apache.regexp.internal.,\
@@ -225,6 +226,7 @@
                    com.sun.imageio.,\
                    com.sun.istack.internal.,\
                    com.sun.jmx.,\
+                   com.sun.media.sound.,\
                    com.sun.proxy.,\
                    com.sun.org.apache.bcel.internal.,\
                    com.sun.org.apache.regexp.internal.,\
--- a/src/share/lib/security/java.security-macosx	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/lib/security/java.security-macosx	Fri Sep 06 15:09:44 2013 -0700
@@ -182,6 +182,7 @@
                com.sun.imageio.,\
                com.sun.istack.internal.,\
                com.sun.jmx.,\
+               com.sun.media.sound.,\
                com.sun.proxy.,\
                com.sun.org.apache.bcel.internal.,\
                com.sun.org.apache.regexp.internal.,\
@@ -226,6 +227,7 @@
                    com.sun.imageio.,\
                    com.sun.istack.internal.,\
                    com.sun.jmx.,\
+                   com.sun.media.sound.,\
                    com.sun.proxy.,\
                    com.sun.org.apache.bcel.internal.,\
                    com.sun.org.apache.regexp.internal.,\
--- a/src/share/lib/security/java.security-solaris	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/lib/security/java.security-solaris	Fri Sep 06 15:09:44 2013 -0700
@@ -183,6 +183,7 @@
                com.sun.imageio.,\
                com.sun.istack.internal.,\
                com.sun.jmx.,\
+               com.sun.media.sound.,\
                com.sun.proxy.,\
                com.sun.org.apache.bcel.internal.,\
                com.sun.org.apache.regexp.internal.,\
@@ -226,6 +227,7 @@
                    com.sun.imageio.,\
                    com.sun.istack.internal.,\
                    com.sun.jmx.,\
+                   com.sun.media.sound.,\
                    com.sun.proxy.,\
                    com.sun.org.apache.bcel.internal.,\
                    com.sun.org.apache.regexp.internal.,\
--- a/src/share/lib/security/java.security-windows	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/lib/security/java.security-windows	Fri Sep 06 15:09:44 2013 -0700
@@ -182,6 +182,7 @@
                com.sun.imageio.,\
                com.sun.istack.internal.,\
                com.sun.jmx.,\
+               com.sun.media.sound.,\
                com.sun.proxy.,\
                com.sun.org.apache.bcel.internal.,\
                com.sun.org.apache.regexp.internal.,\
@@ -226,6 +227,7 @@
                    com.sun.imageio.,\
                    com.sun.istack.internal.,\
                    com.sun.jmx.,\
+                   com.sun.media.sound.,\
                    com.sun.proxy.,\
                    com.sun.org.apache.bcel.internal.,\
                    com.sun.org.apache.regexp.internal.,\
--- a/src/share/native/common/check_code.c	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/share/native/common/check_code.c	Fri Sep 06 15:09:44 2013 -0700
@@ -90,6 +90,12 @@
 #include "classfile_constants.h"
 #include "opcodes.in_out"
 
+#ifdef __APPLE__
+/* use setjmp/longjmp versions that do not save/restore the signal mask */
+#define setjmp _setjmp
+#define longjmp _longjmp
+#endif
+
 #define MAX_ARRAY_DIMENSIONS 255
 /* align byte code */
 #ifndef ALIGN_UP
--- a/src/solaris/classes/sun/nio/ch/DatagramDispatcher.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/DatagramDispatcher.java	Fri Sep 06 15:09:44 2013 -0700
@@ -36,7 +36,7 @@
 class DatagramDispatcher extends NativeDispatcher
 {
     static {
-        Util.load();
+        IOUtil.load();
     }
 
     int read(FileDescriptor fd, long address, int len) throws IOException {
--- a/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Fri Sep 06 15:09:44 2013 -0700
@@ -316,4 +316,8 @@
     private native int poll0(long pollAddress, int numfds, long timeout,
                              int wfd);
     private static native void interrupt(int fd);
+
+    static {
+        IOUtil.load();
+    }
 }
--- a/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -196,9 +196,4 @@
         }
         return this;
     }
-
-    static {
-        Util.load();
-    }
-
 }
--- a/src/solaris/classes/sun/nio/ch/EPoll.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/EPoll.java	Fri Sep 06 15:09:44 2013 -0700
@@ -113,6 +113,6 @@
         throws IOException;
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 }
--- a/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java	Fri Sep 06 15:09:44 2013 -0700
@@ -318,6 +318,7 @@
     }
 
     static {
+        IOUtil.load();
         init();
     }
 
--- a/src/solaris/classes/sun/nio/ch/EPollPort.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/EPollPort.java	Fri Sep 06 15:09:44 2013 -0700
@@ -318,6 +318,6 @@
     private static native void close0(int fd);
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 }
--- a/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -196,8 +196,4 @@
         }
         return this;
     }
-
-    static {
-        Util.load();
-    }
 }
--- a/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -31,7 +31,7 @@
 {
 
     static {
-        Util.load();
+        IOUtil.load();
         init();
     }
 
--- a/src/solaris/classes/sun/nio/ch/InheritedChannel.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/InheritedChannel.java	Fri Sep 06 15:09:44 2013 -0700
@@ -235,6 +235,6 @@
     private static native int peerPort0(int fd);
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 }
--- a/src/solaris/classes/sun/nio/ch/KQueue.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/KQueue.java	Fri Sep 06 15:09:44 2013 -0700
@@ -115,6 +115,6 @@
         throws IOException;
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 }
--- a/src/solaris/classes/sun/nio/ch/KQueuePort.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/KQueuePort.java	Fri Sep 06 15:09:44 2013 -0700
@@ -326,6 +326,6 @@
     private static native void close0(int fd);
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 }
--- a/src/solaris/classes/sun/nio/ch/NativeThread.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/NativeThread.java	Fri Sep 06 15:09:44 2013 -0700
@@ -54,7 +54,7 @@
     private static native void init();
 
     static {
-        Util.load();
+        IOUtil.load();
         init();
     }
 
--- a/src/solaris/classes/sun/nio/ch/PollArrayWrapper.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/PollArrayWrapper.java	Fri Sep 06 15:09:44 2013 -0700
@@ -126,4 +126,7 @@
 
     private static native void interrupt(int fd);
 
+    static {
+        IOUtil.load();
+    }
 }
--- a/src/solaris/classes/sun/nio/ch/SinkChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/SinkChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -37,7 +37,7 @@
 {
 
     // Used to make native read and write calls
-    private static NativeDispatcher nd;
+    private static final NativeDispatcher nd = new FileDispatcherImpl();
 
     // The file descriptor associated with this channel
     FileDescriptor fd;
@@ -206,10 +206,4 @@
            throw new IndexOutOfBoundsException();
         return write(Util.subsequence(srcs, offset, length));
     }
-
-    static {
-        Util.load();
-        nd = new FileDispatcherImpl();
-    }
-
 }
--- a/src/solaris/classes/sun/nio/ch/SolarisEventPort.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/SolarisEventPort.java	Fri Sep 06 15:09:44 2013 -0700
@@ -260,6 +260,6 @@
 
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 }
--- a/src/solaris/classes/sun/nio/ch/SourceChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/SourceChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -37,7 +37,7 @@
 {
 
     // Used to make native read and write calls
-    private static NativeDispatcher nd;
+    private static final NativeDispatcher nd = new FileDispatcherImpl();
 
     // The file descriptor associated with this channel
     FileDescriptor fd;
@@ -206,10 +206,4 @@
             }
         }
     }
-
-    static {
-        Util.load();
-        nd = new FileDispatcherImpl();
-    }
-
 }
--- a/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -345,7 +345,7 @@
         throws IOException;
 
     static {
-        Util.load();
+        IOUtil.load();
         initIDs();
     }
 }
--- a/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -748,6 +748,6 @@
     private static native void checkConnect(int fdVal) throws IOException;
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 }
--- a/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1106,7 +1106,7 @@
             boolean ready) throws IOException;
 
     static {
-        Util.load();   /* loads nio & net native libraries */
+        IOUtil.load();   /* loads nio & net native libraries */
         java.security.AccessController.doPrivileged(
             new java.security.PrivilegedAction<Void>() {
                 public Void run() {
--- a/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -995,7 +995,7 @@
     }
 
     static {
-        Util.load();   /* loads nio & net native libraries */
+        IOUtil.load();   /* loads nio & net native libraries */
         java.security.AccessController.doPrivileged(
             new java.security.PrivilegedAction<Void>() {
                 public Void run() {
--- a/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -426,7 +426,7 @@
         FileDescriptor newfd, InetSocketAddress[] isaa) throws IOException;
 
     static {
-        Util.load();   // loads nio & net native libraries
+        IOUtil.load();   // loads nio & net native libraries
         java.security.AccessController.doPrivileged(
             new java.security.PrivilegedAction<Void>() {
                 public Void run() {
--- a/src/windows/classes/sun/nio/ch/DatagramDispatcher.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/DatagramDispatcher.java	Fri Sep 06 15:09:44 2013 -0700
@@ -36,7 +36,7 @@
 class DatagramDispatcher extends NativeDispatcher
 {
     static {
-        Util.load();
+        IOUtil.load();
     }
 
     int read(FileDescriptor fd, long address, int len) throws IOException {
--- a/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -32,7 +32,7 @@
 class FileDispatcherImpl extends FileDispatcher
 {
     static {
-        Util.load();
+        IOUtil.load();
     }
 
     /**
--- a/src/windows/classes/sun/nio/ch/FileKey.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/FileKey.java	Fri Sep 06 15:09:44 2013 -0700
@@ -73,6 +73,7 @@
     private static native void initIDs();
 
     static {
+        IOUtil.load();
         initIDs();
     }
 }
--- a/src/windows/classes/sun/nio/ch/Iocp.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/Iocp.java	Fri Sep 06 15:09:44 2013 -0700
@@ -443,7 +443,7 @@
     private static native String getErrorMessage(int error);
 
     static {
-        Util.load();
+        IOUtil.load();
         initIDs();
 
         // thread agnostic I/O on Vista/2008 or newer
--- a/src/windows/classes/sun/nio/ch/PipeImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/PipeImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -56,7 +56,6 @@
     private static final Random rnd;
 
     static {
-        Util.load();
         byte[] someBytes = new byte[8];
         boolean resultOK = IOUtil.randomBytes(someBytes);
         if (resultOK) {
--- a/src/windows/classes/sun/nio/ch/SocketDispatcher.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/SocketDispatcher.java	Fri Sep 06 15:09:44 2013 -0700
@@ -36,7 +36,7 @@
 {
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 
     int read(FileDescriptor fd, long address, int len) throws IOException {
--- a/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -750,6 +750,6 @@
     private static native void close0(long handle);
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 }
--- a/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -363,7 +363,7 @@
     private static native void closesocket0(long socket) throws IOException;
 
     static {
-        Util.load();
+        IOUtil.load();
         initIDs();
     }
 }
--- a/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -919,7 +919,7 @@
     private static native void closesocket0(long socket) throws IOException;
 
     static {
-        Util.load();
+        IOUtil.load();
         initIDs();
     }
 }
--- a/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java	Fri Sep 06 15:09:44 2013 -0700
@@ -611,6 +611,6 @@
     }
 
     static {
-        Util.load();
+        IOUtil.load();
     }
 }
--- a/test/ProblemList.txt	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/ProblemList.txt	Fri Sep 06 15:09:44 2013 -0700
@@ -208,7 +208,7 @@
 # jdk_io
 
 # 7160013
-java/io/File/MaxPathLength.java                                 windows-all
+#java/io/File/MaxPathLength.java                                 windows-all
 
 ############################################################################
 
@@ -336,12 +336,6 @@
 # Filed 6653793
 com/sun/jdi/RedefineCrossEvent.java                             generic-all
 
-# Filed 6987312
-com/sun/jdi/DoubleAgentTest.java                                generic-all
-
-# Filed 7020857
-com/sun/jdi/FieldWatchpoints.java                               generic-all
-
 # Filed 6402201
 com/sun/jdi/ProcessAttachTest.sh                                generic-all
 
--- a/test/TEST.ROOT	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/TEST.ROOT	Fri Sep 06 15:09:44 2013 -0700
@@ -9,3 +9,6 @@
 
 # Tests that cannot run concurrently
 exclusiveAccess.dirs=java/rmi/Naming java/util/Currency java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi
+
+# Group definitions
+groups=TEST.groups [closed/TEST.groups]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/TEST.groups	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,214 @@
+#  Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.
+#
+#  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.
+#
+
+jdk_lang = \
+    java/lang \
+    -java/lang/management \
+    -java/lang/instrument \
+    sun/invoke \
+    sun/misc \
+    sun/reflect \
+    vm
+
+jdk_util = \
+    java/util \
+    sun/util
+
+jdk_math = \
+    java/math
+
+jdk_io = \
+    java/io
+
+jdk_nio = \
+    java/nio \
+    sun/nio
+
+jdk_net = \
+    java/net \
+    com/sun/net \
+    com/oracle/net \
+    sun/net
+
+jdk_time = \
+    java/time
+
+jdk_rmi = \
+    java/rmi \
+    javax/rmi/ssl \
+    sun/rmi
+
+jdk_security1 = \
+    java/security
+
+jdk_security2 = \
+    javax/crypto \
+    javax/xml/crypto \
+    com/sun/crypto
+
+jdk_security3 = \
+    javax/security  \
+    com/sun/security \
+    com/sun/org/apache/xml/internal/security \
+    com/oracle/security \
+    sun/security \
+    lib/security
+
+jdk_security = \
+    :jdk_security1 \
+    :jdk_security2 \
+    :jdk_security3
+
+jdk_text = \
+    java/text \
+    sun/text
+
+jdk_management = \
+    java/lang/management \
+    com/sun/management \
+    sun/management
+
+jdk_instrument = \
+    java/lang/instrument
+
+jdk_jmx = \
+    javax/management \
+    com/sun/jmx
+
+jdk_jdi = \
+    com/sun/jdi
+
+#
+# Tool (and tool API) tests are split into core and svc groups
+#
+core_tools = \
+    tools \
+    com/sun/tools/extcheck \
+    sun/tools/java \
+    sun/tools/native2ascii \
+    sun/tools/jrunscript
+
+svc_tools = \
+    com/sun/tools/attach \
+    com/sun/tracing \
+    sun/tools \
+    -sun/tools/java \
+    -sun/tools/native2ascii \
+    -sun/tools/jrunscript \
+    sun/jvmstat \
+    demo/jvmti
+
+jdk_tools = \
+    :core_tools \
+    :svc_tools
+
+#
+# Catch-all for other areas with a small number of tests
+#
+jdk_other = \
+    java/sql \
+    javax/sql \
+    javax/naming \
+    javax/script \
+    javax/smartcardio \
+    javax/xml \
+    -javax/xml/crypto \
+    jdk/asm \
+    jdk/lambda \
+    com/sun/jndi \
+    com/sun/corba \
+    lib/testlibrary \
+    demo/zipfs \
+    sample
+
+#
+# SCTP is its own group as it is highly sensitive to kernel/network config
+#
+jdk_sctp = \
+    com/sun/nio/sctp
+
+
+#
+# core group to run all core area tests
+#
+jdk_core = \
+    :jdk_lang \
+    :jdk_util \
+    :jdk_math \
+    :jdk_io \
+    :jdk_nio \
+    :jdk_net \
+    :jdk_rmi \
+    :jdk_time \
+    :jdk_security \
+    :jdk_text \
+    :core_tools \
+    :jdk_other
+
+#
+# svc group to run all serviceability area tests
+#
+jdk_svc = \
+    :jdk_management \
+    :jdk_instrument \
+    :jdk_jmx \
+    :jdk_jdi \
+    :svc_tools
+
+#############################
+
+#
+# Client area groups
+#
+
+jdk_awt = \
+    java/awt \
+    com/sun/awt \
+    com/apple/eawt \
+    sun/awt
+
+jdk_2d = \
+    javax/print \
+    sun/pisces  \
+    sun/java2d
+
+jdk_beans = \
+    java/beans
+
+jdk_swing = \
+    javax/accessibility \
+    javax/swing \
+    com/sun/java/swing
+
+jdk_sound = \
+    javax/sound
+
+jdk_imageio = \
+    javax/imageio
+
+jdk_desktop = \
+    :jdk_awt \
+    :jdk_2d \
+    :jdk_beans \
+    :jdk_swing \
+    :jdk_sound \
+    :jdk_imageio
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/io/BufferedInputStream/LargeCopyWithMark.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 7129312
+ * @summary BufferedInputStream calculates negative array size with large
+ *          streams and mark
+ * @library /lib/testlibrary
+ * @run main/othervm LargeCopyWithMark
+ */
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import static jdk.testlibrary.ProcessTools.*;
+
+
+public class LargeCopyWithMark {
+
+    public static void main(String[] args) throws Exception {
+        if (! System.getProperty("os.arch").contains("64")) {
+            System.out.println("Test runs on 64 bit platforms");
+            return;
+        }
+        ProcessBuilder pb = createJavaProcessBuilder("-Xmx4G",
+                "-ea:LargeCopyWithMark$Child",
+                "LargeCopyWithMark$Child");
+        int res = pb.inheritIO().start().waitFor();
+        if (res != 0) {
+            throw new AssertionError("Test failed: exit code = " + res);
+        }
+    }
+
+    public static class Child {
+        static final int BUFF_SIZE = 8192;
+        static final int BIS_BUFF_SIZE = Integer.MAX_VALUE / 2 + 100;
+        static final long BYTES_TO_COPY = 2L * Integer.MAX_VALUE;
+
+        static {
+            assert BIS_BUFF_SIZE * 2 < 0 : "doubling must overflow";
+        }
+
+        public static void main(String[] args) throws Exception {
+            byte[] buff = new byte[BUFF_SIZE];
+
+            try (InputStream myis = new MyInputStream(BYTES_TO_COPY);
+                 InputStream bis = new BufferedInputStream(myis, BIS_BUFF_SIZE);
+                 OutputStream myos = new MyOutputStream()) {
+
+                // will require a buffer bigger than BIS_BUFF_SIZE
+                bis.mark(BIS_BUFF_SIZE + 100);
+
+                for (;;) {
+                    int count = bis.read(buff, 0, BUFF_SIZE);
+                    if (count == -1)
+                        break;
+                    myos.write(buff, 0, count);
+                }
+            } catch (java.lang.NegativeArraySizeException e) {
+                e.printStackTrace();
+                System.exit(11);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}
+
+class MyInputStream extends InputStream {
+    private long bytesLeft;
+    public MyInputStream(long bytesLeft) {
+        this.bytesLeft = bytesLeft;
+    }
+    @Override public int read() throws IOException {
+        return 0;
+    }
+    @Override public int read(byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+    @Override public int read(byte[] b, int off, int len) throws IOException {
+        if (bytesLeft <= 0)
+            return -1;
+        long result = Math.min(bytesLeft, (long)len);
+        bytesLeft -= result;
+        return (int)result;
+    }
+    @Override public int available() throws IOException {
+        return (bytesLeft > 0) ? 1 : 0;
+    }
+}
+
+class MyOutputStream extends OutputStream {
+    @Override public void write(int b) throws IOException {}
+    @Override public void write(byte[] b) throws IOException {}
+    @Override public void write(byte[] b, int off, int len) throws IOException {}
+}
--- a/test/java/io/File/MaxPathLength.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/io/File/MaxPathLength.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
  */
 
 import java.io.*;
+import java.nio.file.Files;
 
 public class MaxPathLength {
     private static String sep = File.separator;
@@ -87,10 +88,8 @@
             System.err.println("Warning: Test directory structure exists already!");
             return;
         }
-        boolean couldMakeTestDirectory = dirFile.mkdirs();
-        if (!couldMakeTestDirectory) {
-            throw new RuntimeException ("Could not create test directory structure");
-        }
+        Files.createDirectories(dirFile.toPath());
+
         try {
             if (tryAbsolute)
                 dirFile = new File(dirFile.getCanonicalPath());
--- a/test/java/io/pathNames/General.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/io/pathNames/General.java	Fri Sep 06 15:09:44 2013 -0700
@@ -28,6 +28,7 @@
 
 import java.io.*;
 import java.util.*;
+import java.nio.file.*;
 
 
 public class General {
@@ -57,7 +58,7 @@
         for (int i = 0; i < dl.length; i++) {
             File f = new File(subdir, dl[i]);
             File df = new File(dir, f.getPath());
-            if (df.exists() && df.isFile()) {
+            if (Files.isRegularFile(df.toPath(), LinkOption.NOFOLLOW_LINKS)) {
                 return f.getPath();
             }
         }
@@ -65,7 +66,7 @@
             File f = (subdir.length() == 0) ? new File(dl[i])
                                             : new File(subdir, dl[i]);
             File df = new File(dir, f.getPath());
-            if (df.exists() && df.isDirectory()) {
+            if (Files.isDirectory(df.toPath(), LinkOption.NOFOLLOW_LINKS)) {
                 String[] dl2 = df.list();
                 if (dl2 != null) {
                     String ff = findSomeFile(dir, f.getPath(), dl2);
@@ -90,7 +91,7 @@
         }
         for (int i = 0; i < dl.length; i++) {
             File f = new File(dir, dl[i]);
-            if (f.isFile()) {
+            if (Files.isRegularFile(f.toPath(), LinkOption.NOFOLLOW_LINKS)) {
                 return dl[i];
             }
         }
@@ -127,7 +128,7 @@
         }
         for (int i = 0; i < dl.length; i++) {
             File f = new File(d, dl[i]);
-            if (f.isDirectory()) {
+            if (Files.isDirectory(f.toPath(), LinkOption.NOFOLLOW_LINKS)) {
                 String[] dl2 = f.list();
                 if (dl2 == null || dl2.length >= 250) {
                     /* Heuristic to avoid scanning huge directories */
@@ -314,7 +315,7 @@
 
         /* Normal name */
         if (f.exists()) {
-            if (f.isDirectory() && f.list() != null) {
+            if (Files.isDirectory(f.toPath(), LinkOption.NOFOLLOW_LINKS) && f.list() != null) {
                 if ((n = findSomeFile(ans, create)) != null)
                     checkSlashes(d, create, ans + n, ask + n);
                 if ((n = findSomeDir(ans, create)) != null)
--- a/test/java/lang/SecurityManager/CheckPackageAccess.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/lang/SecurityManager/CheckPackageAccess.java	Fri Sep 06 15:09:44 2013 -0700
@@ -23,7 +23,7 @@
 
 /*
  *  @test
- *  @bug 6741606 7146431 8000450
+ *  @bug 6741606 7146431 8000450 8019830
  *  @summary Make sure all restricted packages listed in the package.access
  *           property in the java.security file are blocked
  *  @run main/othervm CheckPackageAccess
@@ -54,6 +54,7 @@
         "com.sun.imageio.",
         "com.sun.istack.internal.",
         "com.sun.jmx.",
+        "com.sun.media.sound.",
         "com.sun.proxy.",
         "com.sun.org.apache.bcel.internal.",
         "com.sun.org.apache.regexp.internal.",
--- a/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -28,6 +28,9 @@
  */
 
 import java.lang.annotation.Retention;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -66,17 +69,6 @@
         }
     }
 
-    static void dumpState(Task task) {
-        System.err.println(
-            "Task[" + task.getName() + "].state: " +
-            task.getState() + " ..."
-        );
-        for (StackTraceElement ste : task.getStackTrace()) {
-            System.err.println("\tat " + ste);
-        }
-        System.err.println();
-    }
-
     public static void main(String[] args) throws Exception {
         CountDownLatch prepareLatch = new CountDownLatch(2);
         AtomicInteger goLatch = new AtomicInteger(1);
@@ -88,18 +80,22 @@
         prepareLatch.await();
         // let them go
         goLatch.set(0);
-        // attempt to join them
-        taskA.join(5000L);
-        taskB.join(5000L);
-
-        if (taskA.isAlive() || taskB.isAlive()) {
-            dumpState(taskA);
-            dumpState(taskB);
-            throw new IllegalStateException(
-                taskA.getState() == Thread.State.BLOCKED &&
-                taskB.getState() == Thread.State.BLOCKED
-                ? "deadlock detected"
-                : "unexpected condition");
+        // obtain ThreadMXBean
+        ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
+        // wait for threads to finish or dead-lock
+        while (taskA.isAlive() || taskB.isAlive()) {
+            // attempt to join threads
+            taskA.join(500L);
+            taskB.join(500L);
+            // detect dead-lock
+            long[] deadlockedIds = threadBean.findMonitorDeadlockedThreads();
+            if (deadlockedIds != null && deadlockedIds.length > 0) {
+                StringBuilder sb = new StringBuilder("deadlock detected:\n\n");
+                for (ThreadInfo ti : threadBean.getThreadInfo(deadlockedIds, Integer.MAX_VALUE)) {
+                    sb.append(ti);
+                }
+                throw new IllegalStateException(sb.toString());
+            }
         }
     }
 }
--- a/test/java/lang/annotation/TypeAnnotationReflection.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/lang/annotation/TypeAnnotationReflection.java	Fri Sep 06 15:09:44 2013 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8004698 8007073
+ * @bug 8004698 8007073 8022343
  * @summary Unit test for type annotations
  */
 
@@ -58,7 +58,7 @@
     }
 
     private static void testSuper() throws Exception {
-        check(Object.class.getAnnotatedSuperclass().getAnnotations().length == 0);
+        check(Object.class.getAnnotatedSuperclass() == null);
         check(Class.class.getAnnotatedSuperclass().getAnnotations().length == 0);
 
         AnnotatedType a;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8022343
+ * @summary make sure Class.getAnnotatedSuperclass() returns null when specified to do so
+ */
+
+public class GetAnnotatedSuperclass {
+    private static final Class<?>[] testData = {
+        Object.class,
+        If.class,
+        Object[].class,
+        void.class,
+        int.class,
+    };
+
+    public static void main(String[] args) throws Exception {
+        int failed = 0;
+        for (Class<?> toTest : testData) {
+            Object res = toTest.getAnnotatedSuperclass();
+
+            if (res != null) {
+                failed++;
+                System.out.println(toTest + ".getAnnotatedSuperclass() returns: "
+                        + res + ", should be null");
+            }
+        }
+
+        if (failed != 0)
+            throw new RuntimeException("Test failed, check log for details");
+    }
+
+    interface If {}
+}
--- a/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java	Fri Sep 06 15:09:44 2013 -0700
@@ -33,10 +33,10 @@
  * @author  Mandy Chung
  *
  * @build ResetPeakMemoryUsage MemoryUtil
- * @run main/othervm -XX:+UseSerialGC -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage
- * @run main/othervm -XX:+UseConcMarkSweepGC -Xmn8m ResetPeakMemoryUsage
- * @run main/othervm -XX:+UseParallelGC -Xmn8m ResetPeakMemoryUsage
- * @run main/othervm -XX:+UseG1GC -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+PrintGCDetails -XX:+UseSerialGC -Xms256m -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -Xms256m -Xmn8m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+PrintGCDetails -XX:+UseParallelGC -Xms256m -Xmn8m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+PrintGCDetails -XX:+UseG1GC -Xms256m -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage
  */
 
 import java.lang.management.*;
--- a/test/java/math/BigDecimal/IntegralDivisionTests.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/math/BigDecimal/IntegralDivisionTests.java	Fri Sep 06 15:09:44 2013 -0700
@@ -22,7 +22,7 @@
  */
 /*
  * @test
- * @bug 4904082 4917089 6337226
+ * @bug 4904082 4917089 6337226 6378503
  * @summary Tests that integral division and related methods return the proper result and scale.
  * @author Joseph D. Darcy
  */
@@ -47,6 +47,9 @@
             {new BigDecimal("400e1"),   new BigDecimal("5"),    new BigDecimal("80e1")},
             {new BigDecimal("400e1"),   new BigDecimal("4.999999999"),  new BigDecimal("8e2")},
             {new BigDecimal("40e2"),    new BigDecimal("5"),    new BigDecimal("8e2")},
+            {BigDecimal.valueOf(1, Integer.MIN_VALUE),
+                BigDecimal.valueOf(1, -(Integer.MAX_VALUE & 0x7fffff00)),
+                BigDecimal.valueOf(1, -256)},
         };
 
         for(BigDecimal [] testCase: moreTestCases) {
--- a/test/java/nio/file/WatchService/SensitivityModifier.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/nio/file/WatchService/SensitivityModifier.java	Fri Sep 06 15:09:44 2013 -0700
@@ -54,60 +54,66 @@
     @SuppressWarnings("unchecked")
     static void doTest(Path top) throws Exception {
         FileSystem fs = top.getFileSystem();
-        WatchService watcher = fs.newWatchService();
+        try (WatchService watcher = fs.newWatchService()) {
 
-        // create directories and files
-        int nDirs = 5 + rand.nextInt(20);
-        int nFiles = 50 + rand.nextInt(50);
-        Path[] dirs = new Path[nDirs];
-        Path[] files = new Path[nFiles];
-        for (int i=0; i<nDirs; i++) {
-            dirs[i] = Files.createDirectory(top.resolve("dir" + i));
-        }
-        for (int i=0; i<nFiles; i++) {
-            Path dir = dirs[rand.nextInt(nDirs)];
-            files[i] = Files.createFile(dir.resolve("file" + i));
-        }
+            // create directories and files
+            int nDirs = 5 + rand.nextInt(20);
+            int nFiles = 50 + rand.nextInt(50);
+            Path[] dirs = new Path[nDirs];
+            Path[] files = new Path[nFiles];
+            for (int i=0; i<nDirs; i++) {
+                dirs[i] = Files.createDirectory(top.resolve("dir" + i));
+            }
+            for (int i=0; i<nFiles; i++) {
+                Path dir = dirs[rand.nextInt(nDirs)];
+                files[i] = Files.createFile(dir.resolve("file" + i));
+            }
 
-        // register the directories (random sensitivity)
-        register(dirs, watcher);
+            // register the directories (random sensitivity)
+            register(dirs, watcher);
 
-        // sleep a bit here to ensure that modification to the first file
-        // can be detected by polling implementations (ie: last modified time
-        // may not change otherwise).
-        try { Thread.sleep(1000); } catch (InterruptedException e) { }
+            // sleep a bit here to ensure that modification to the first file
+            // can be detected by polling implementations (ie: last modified time
+            // may not change otherwise).
+            try { Thread.sleep(1000); } catch (InterruptedException e) { }
 
-        // modify files and check that events are received
-        for (int i=0; i<10; i++) {
-            Path file = files[rand.nextInt(nFiles)];
-            System.out.println("Modify: " + file);
-            try (OutputStream out = Files.newOutputStream(file)) {
-                out.write(new byte[100]);
+            // modify files and check that events are received
+            for (int i=0; i<10; i++) {
+                Path file = files[rand.nextInt(nFiles)];
+                System.out.println("Modify: " + file);
+                try (OutputStream out = Files.newOutputStream(file)) {
+                    out.write(new byte[100]);
+                }
+
+                System.out.println("Waiting for event(s)...");
+                boolean eventReceived = false;
+                WatchKey key = watcher.take();
+                do {
+                    for (WatchEvent<?> event: key.pollEvents()) {
+                        if (event.kind() != ENTRY_MODIFY)
+                            throw new RuntimeException("Unexpected event: " + event);
+                        Path name = ((WatchEvent<Path>)event).context();
+                        if (name.equals(file.getFileName())) {
+                            eventReceived = true;
+                            break;
+                        }
+                    }
+                    key.reset();
+                    key = watcher.poll(1, TimeUnit.SECONDS);
+                } while (key != null && !eventReceived);
+
+                // we should have received at least one ENTRY_MODIFY event
+                if (eventReceived) {
+                    System.out.println("Event OK");
+                } else {
+                    throw new RuntimeException("No ENTRY_MODIFY event received for " + file);
+                }
+
+                // re-register the directories to force changing their sensitivity
+                // level
+                register(dirs, watcher);
             }
-            System.out.println("Waiting for event...");
-            WatchKey key = watcher.take();
-            WatchEvent<?> event = key.pollEvents().iterator().next();
-            if (event.kind() != ENTRY_MODIFY)
-                throw new RuntimeException("Unexpected event: " + event);
-            Path name = ((WatchEvent<Path>)event).context();
-            if (!name.equals(file.getFileName()))
-                throw new RuntimeException("Unexpected context: " + name);
-            System.out.println("Event OK");
-
-            // drain events (to avoid interference)
-            do {
-                key.pollEvents();
-                key.reset();
-                key = watcher.poll(1, TimeUnit.SECONDS);
-            } while (key != null);
-
-            // re-register the directories to force changing their sensitivity
-            // level
-            register(dirs, watcher);
         }
-
-        // done
-        watcher.close();
     }
 
     public static void main(String[] args) throws Exception {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Arrays/TimSortStackSize.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8011944
+ * @summary Test TimSort stack size
+ */
+import java.util.Arrays;
+import java.util.ArrayDeque;
+
+public class TimSortStackSize {
+
+    public static void main(String[] args) {
+        testComparableTimSort();
+        testTimSort();
+    }
+
+    static void testComparableTimSort() {
+        System.out.printf("testComparableTimSort()%n");
+        Arrays.sort(genData());
+    }
+
+    static void testTimSort() {
+        System.out.printf("testTimSort()%n");
+        Arrays.sort(genData(), Integer::compare);
+    }
+
+    private static final int MIN = 16;
+
+    private static final int BOUND1 = 2 * MIN + 1;
+    private static final int BOUND2 = BOUND1 + MIN + 2;
+    private static final int BOUND3 = BOUND1 + 1 + BOUND2;
+    private static final int BOUND4 = BOUND2 + 1 + BOUND3;
+    private static final int BOUND5 = BOUND3 + 1 + BOUND4;
+
+    static int build(int size, int B, ArrayDeque<Integer> chunks) {
+        chunks.addFirst(B);
+        if (size < BOUND1) {
+            chunks.addFirst(size);
+            return size;
+        }
+
+        int asize = (size + 2) / 2;
+        if (size >= BOUND2 && asize < BOUND1) {
+            asize = BOUND1;
+        } else if (size >= BOUND3 && asize < BOUND2) {
+            asize = BOUND2;
+        } else if (size >= BOUND4 && asize < BOUND3) {
+            asize = BOUND3;
+        } else if (size >= BOUND5 && asize < BOUND4) {
+            asize = BOUND4;
+        }
+        if (size - asize >= B) {
+            throw new AssertionError(" " + size + " , " + asize + " , " + B);
+        }
+        return build(asize, size - asize, chunks);
+    }
+
+    static Integer[] genData() {
+        ArrayDeque<Integer> chunks = new ArrayDeque<Integer>();
+        chunks.addFirst(MIN);
+
+        int B = MIN + 4;
+        int A = B + MIN + 1;
+
+        for (int i = 0; i < 8; i++) {
+            int eps = build(A, B, chunks);
+            B = B + A + 1;
+            A = B + eps + 1;
+        }
+        chunks.addFirst(B);
+        chunks.addFirst(A);
+        int total = 0;
+        for (Integer len : chunks) {
+            total += len;
+        }
+        int pow = MIN;
+        while (pow < total) {
+            pow += pow;
+        }
+        chunks.addLast(pow - total);
+        System.out.println(" Total: " + total);
+        Integer[] array = new Integer[pow];
+        int off = 0;
+        int pos = 0;
+        for (Integer len : chunks) {
+            for (int i = 0; i < len; i++) {
+                array[pos++] = Integer.valueOf(i == 0 ? 0 : 1);
+            }
+            off++;
+        }
+        return array;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Collections/Wrappers.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ * @run testng Wrappers
+ * @summary Ensure Collections wrapping classes provide non-default implementations
+ */
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+
+import static org.testng.Assert.assertFalse;
+
+@Test(groups = "unit")
+public class Wrappers {
+    static Object[][] collections;
+
+    @DataProvider(name="collections")
+    public static Object[][] collectionCases() {
+        if (collections != null) {
+            return collections;
+        }
+
+        List<Object[]> cases = new ArrayList<>();
+        LinkedList<Integer> seedList = new LinkedList<>();
+        ArrayList<Integer> seedRandomAccess = new ArrayList<>();
+        TreeSet<Integer> seedSet = new TreeSet<>();
+        TreeMap<Integer, Integer> seedMap = new TreeMap<>();
+
+        for (int i = 1; i <= 10; i++) {
+            seedList.add(i);
+            seedRandomAccess.add(i);
+            seedSet.add(i);
+            seedMap.put(i, i);
+        }
+
+        cases.add(new Object[] { Collections.unmodifiableCollection(seedList) });
+        cases.add(new Object[] { Collections.unmodifiableList(seedList) });
+        cases.add(new Object[] { Collections.unmodifiableList(seedRandomAccess) });
+        cases.add(new Object[] { Collections.unmodifiableSet(seedSet) });
+        cases.add(new Object[] { Collections.unmodifiableSortedSet(seedSet) });
+        cases.add(new Object[] { Collections.unmodifiableNavigableSet(seedSet) });
+
+        // As sets from map also need to be unmodifiable, thus a wrapping
+        // layer exist and should not have default methods
+        cases.add(new Object[] { Collections.unmodifiableMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.unmodifiableMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.unmodifiableMap(seedMap).values() });
+        cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).values() });
+        cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).values() });
+
+        // Synchronized
+        cases.add(new Object[] { Collections.synchronizedCollection(seedList) });
+        cases.add(new Object[] { Collections.synchronizedList(seedList) });
+        cases.add(new Object[] { Collections.synchronizedList(seedRandomAccess) });
+        cases.add(new Object[] { Collections.synchronizedSet(seedSet) });
+        cases.add(new Object[] { Collections.synchronizedSortedSet(seedSet) });
+        cases.add(new Object[] { Collections.synchronizedNavigableSet(seedSet) });
+
+        // As sets from map also need to be synchronized on the map, thus a
+        // wrapping layer exist and should not have default methods
+        cases.add(new Object[] { Collections.synchronizedMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.synchronizedMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.synchronizedMap(seedMap).values() });
+        cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).values() });
+        cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).values() });
+
+        // Checked
+        cases.add(new Object[] { Collections.checkedCollection(seedList, Integer.class) });
+        cases.add(new Object[] { Collections.checkedList(seedList, Integer.class) });
+        cases.add(new Object[] { Collections.checkedList(seedRandomAccess, Integer.class) });
+        cases.add(new Object[] { Collections.checkedSet(seedSet, Integer.class) });
+        cases.add(new Object[] { Collections.checkedSortedSet(seedSet, Integer.class) });
+        cases.add(new Object[] { Collections.checkedNavigableSet(seedSet, Integer.class) });
+        cases.add(new Object[] { Collections.checkedQueue(seedList, Integer.class) });
+
+        // asLifoQueue is another wrapper
+        cases.add(new Object[] { Collections.asLifoQueue(seedList) });
+
+        collections = cases.toArray(new Object[0][]);
+        return collections;
+    }
+
+    static Method[] defaultMethods;
+
+    static {
+        List<Method> list = new ArrayList<>();
+        Method[] methods = Collection.class.getMethods();
+        for (Method m: methods) {
+            if (m.isDefault()) {
+                list.add(m);
+            }
+        }
+        defaultMethods = list.toArray(new Method[0]);
+    }
+
+    @Test(dataProvider = "collections")
+    public static void testAllDefaultMethodsOverridden(Collection c) throws NoSuchMethodException {
+        Class cls = c.getClass();
+        for (Method m: defaultMethods) {
+            Method m2 = cls.getMethod(m.getName(), m.getParameterTypes());
+            // default had been override
+            assertFalse(m2.isDefault(), cls.getCanonicalName());
+        }
+    }
+}
+
--- a/test/java/util/Comparator/BasicTest.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/util/Comparator/BasicTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -90,7 +90,7 @@
         Thing[] things = new Thing[intValues.length];
         for (int i=0; i<intValues.length; i++)
             things[i] = new Thing(intValues[i], 0L, 0.0, null);
-        Comparator<Thing> comp = Comparator.comparing(new ToIntFunction<Thing>() {
+        Comparator<Thing> comp = Comparator.comparingInt(new ToIntFunction<Thing>() {
             @Override
             public int applyAsInt(Thing thing) {
                 return thing.getIntField();
@@ -104,7 +104,7 @@
         Thing[] things = new Thing[longValues.length];
         for (int i=0; i<longValues.length; i++)
             things[i] = new Thing(0, longValues[i], 0.0, null);
-        Comparator<Thing> comp = Comparator.comparing(new ToLongFunction<Thing>() {
+        Comparator<Thing> comp = Comparator.comparingLong(new ToLongFunction<Thing>() {
             @Override
             public long applyAsLong(Thing thing) {
                 return thing.getLongField();
@@ -118,7 +118,7 @@
         Thing[] things = new Thing[doubleValues.length];
         for (int i=0; i<doubleValues.length; i++)
             things[i] = new Thing(0, 0L, doubleValues[i], null);
-        Comparator<Thing> comp = Comparator.comparing(new ToDoubleFunction<Thing>() {
+        Comparator<Thing> comp = Comparator.comparingDouble(new ToDoubleFunction<Thing>() {
             @Override
             public double applyAsDouble(Thing thing) {
                 return thing.getDoubleField();
@@ -211,8 +211,8 @@
     };
 
     public void testComparatorDefaultMethods() {
-        Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
-        Comparator<People> cmp2 = Comparator.comparing((Function<People, String>) People::getLastName);
+        Comparator<People> cmp = Comparator.comparing(People::getFirstName);
+        Comparator<People> cmp2 = Comparator.comparing(People::getLastName);
         // reverseOrder
         assertComparison(cmp.reversed(), people[1], people[0]);
         // thenComparing(Comparator)
@@ -222,20 +222,20 @@
         assertComparison(cmp.thenComparing(People::getLastName), people[0], people[1]);
         assertComparison(cmp.thenComparing(People::getLastName), people[4], people[0]);
         // thenComparing(ToIntFunction)
-        assertComparison(cmp.thenComparing(People::getAge), people[0], people[1]);
-        assertComparison(cmp.thenComparing(People::getAge), people[1], people[5]);
+        assertComparison(cmp.thenComparingInt(People::getAge), people[0], people[1]);
+        assertComparison(cmp.thenComparingInt(People::getAge), people[1], people[5]);
         // thenComparing(ToLongFunction)
-        assertComparison(cmp.thenComparing(People::getAgeAsLong), people[0], people[1]);
-        assertComparison(cmp.thenComparing(People::getAgeAsLong), people[1], people[5]);
+        assertComparison(cmp.thenComparingLong(People::getAgeAsLong), people[0], people[1]);
+        assertComparison(cmp.thenComparingLong(People::getAgeAsLong), people[1], people[5]);
         // thenComparing(ToDoubleFunction)
-        assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[0], people[1]);
-        assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[1], people[5]);
+        assertComparison(cmp.thenComparingDouble(People::getAgeAsDouble), people[0], people[1]);
+        assertComparison(cmp.thenComparingDouble(People::getAgeAsDouble), people[1], people[5]);
     }
 
 
     public void testNullsFirst() {
         Comparator<String> strcmp = Comparator.nullsFirst(Comparator.naturalOrder());
-        Comparator<People> cmp = Comparator.<People, String>comparing(People::getLastName, strcmp)
+        Comparator<People> cmp = Comparator.comparing(People::getLastName, strcmp)
                                            .thenComparing(People::getFirstName, strcmp);
         // Mary.null vs Mary.Cook - solve by last name
         assertComparison(cmp, people[6], people[5]);
@@ -243,7 +243,7 @@
         assertComparison(cmp, people[7], people[6]);
 
         // More than one thenComparing
-        strcmp = Comparator.nullsFirst(Comparator.comparing((ToIntFunction<String>) String::length)
+        strcmp = Comparator.nullsFirst(Comparator.comparingInt(String::length)
                                                  .thenComparing(String.CASE_INSENSITIVE_ORDER));
         assertComparison(strcmp, null, "abc");
         assertComparison(strcmp, "ab", "abc");
@@ -273,7 +273,7 @@
 
     public void testNullsLast() {
         Comparator<String> strcmp = Comparator.nullsLast(Comparator.naturalOrder());
-        Comparator<People> cmp = Comparator.<People, String>comparing(People::getLastName, strcmp)
+        Comparator<People> cmp = Comparator.comparing(People::getLastName, strcmp)
                                            .thenComparing(People::getFirstName, strcmp);
         // Mary.null vs Mary.Cook - solve by last name
         assertComparison(cmp, people[5], people[6]);
@@ -281,7 +281,7 @@
         assertComparison(cmp, people[7], people[6]);
 
         // More than one thenComparing
-        strcmp = Comparator.nullsLast(Comparator.comparing((ToIntFunction<String>) String::length)
+        strcmp = Comparator.nullsLast(Comparator.comparingInt(String::length)
                                                 .thenComparing(String.CASE_INSENSITIVE_ORDER));
         assertComparison(strcmp, "abc", null);
         assertComparison(strcmp, "ab", "abc");
@@ -341,28 +341,28 @@
         } catch (NullPointerException npe) {}
 
         try {
-            Comparator<People> cmp = Comparator.comparing((Function<People, String>) null, Comparator.<String>naturalOrder());
+            Comparator<People> cmp = Comparator.comparing(null, Comparator.<String>naturalOrder());
             fail("comparing(null, cmp) should throw NPE");
         } catch (NullPointerException npe) {}
         try {
-            Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName, null);
+            Comparator<People> cmp = Comparator.comparing(People::getFirstName, null);
             fail("comparing(f, null) should throw NPE");
         } catch (NullPointerException npe) {}
 
         try {
-            Comparator<People> cmp = Comparator.comparing((Function<People, String>) null);
+            Comparator<People> cmp = Comparator.comparing(null);
             fail("comparing(null) should throw NPE");
         } catch (NullPointerException npe) {}
         try {
-            Comparator<People> cmp = Comparator.comparing((ToIntFunction<People>) null);
+            Comparator<People> cmp = Comparator.comparingInt(null);
             fail("comparing(null) should throw NPE");
         } catch (NullPointerException npe) {}
         try {
-            Comparator<People> cmp = Comparator.comparing((ToLongFunction<People>) null);
+            Comparator<People> cmp = Comparator.comparingLong(null);
             fail("comparing(null) should throw NPE");
         } catch (NullPointerException npe) {}
         try {
-            Comparator<People> cmp = Comparator.comparing((ToDoubleFunction<People>) null);
+            Comparator<People> cmp = Comparator.comparingDouble(null);
             fail("comparing(null) should throw NPE");
         } catch (NullPointerException npe) {}
     }
--- a/test/java/util/Map/EntryComparators.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/util/Map/EntryComparators.java	Fri Sep 06 15:09:44 2013 -0700
@@ -115,8 +115,8 @@
         // Comparator<People> cmp = Comparator.naturalOrder(); // Should fail to compiler as People is not comparable
         // We can use simple comparator, but those have been tested above.
         // Thus choose to do compose for some level of interation.
-        Comparator<People> cmp1 = Comparator.comparing((Function<People, String>) People::getFirstName);
-        Comparator<People> cmp2 = Comparator.comparing((Function<People, String>) People::getLastName);
+        Comparator<People> cmp1 = Comparator.comparing(People::getFirstName);
+        Comparator<People> cmp2 = Comparator.comparing(People::getLastName);
         Comparator<People> cmp = cmp1.thenComparing(cmp2);
 
         assertPairComparison(people[0], people[0], people[1], people[1],
--- a/test/java/util/Random/RandomStreamTest.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/util/Random/RandomStreamTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -82,13 +82,6 @@
         assertEquals(destination.size(), count);
     }
 
-    @Test(dataProvider = "suppliers")
-    public void testRandomGaussianStream(final Random random, final int count) {
-        final List<Double> destination = new ArrayList<>(count);
-        random.gaussians().limit(count).forEach(destination::add);
-        assertEquals(destination.size(), count);
-    }
-
     @Test
     public void testIntStream() {
         final long seed = System.currentTimeMillis();
@@ -132,20 +125,6 @@
     }
 
     @Test
-    public void testGaussianStream() {
-        final long seed = System.currentTimeMillis();
-        final Random r1 = new Random(seed);
-        final double[] a = new double[SIZE];
-        for (int i=0; i < SIZE; i++) {
-            a[i] = r1.nextGaussian();
-        }
-
-        final Random r2 = new Random(seed); // same seed
-        final double[] b = r2.gaussians().limit(SIZE).toArray();
-        assertEquals(a, b);
-    }
-
-    @Test
     public void testThreadLocalIntStream() throws InterruptedException, ExecutionException, TimeoutException {
         ThreadLocalRandom tlr = ThreadLocalRandom.current();
         testRandomResultSupplierConcurrently(() -> tlr.ints().limit(SIZE).boxed().collect(toList()));
@@ -163,12 +142,6 @@
         testRandomResultSupplierConcurrently(() -> tlr.doubles().limit(SIZE).boxed().collect(toList()));
     }
 
-    @Test
-    public void testThreadLocalGaussianStream() throws InterruptedException, ExecutionException, TimeoutException {
-        ThreadLocalRandom tlr = ThreadLocalRandom.current();
-        testRandomResultSupplierConcurrently(() -> tlr.gaussians().limit(SIZE).boxed().collect(toList()));
-    }
-
     <T> void testRandomResultSupplierConcurrently(Supplier<T> s) throws InterruptedException, ExecutionException, TimeoutException {
         // Produce 10 completable future tasks
         final int tasks = 10;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Random/RandomTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiConsumer;
+
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @run testng RandomTest
+ * @summary test methods on Random
+ */
+@Test
+public class RandomTest {
+
+    // Note: this test was adapted from the 166 TCK ThreadLocalRandomTest test
+    // and modified to be a TestNG test
+
+    /*
+     * Testing coverage notes:
+     *
+     * We don't test randomness properties, but only that repeated
+     * calls, up to NCALLS tries, produce at least one different
+     * result.  For bounded versions, we sample various intervals
+     * across multiples of primes.
+     */
+
+    // max numbers of calls to detect getting stuck on one value
+    static final int NCALLS = 10000;
+
+    // max sampled int bound
+    static final int MAX_INT_BOUND = (1 << 28);
+
+    // max sampled long bound
+    static final long MAX_LONG_BOUND = (1L << 42);
+
+    // Number of replications for other checks
+    static final int REPS = 20;
+
+    /**
+     * Repeated calls to nextInt produce at least two distinct results
+     */
+    public void testNextInt() {
+        Random r = new Random();
+        int f = r.nextInt();
+        int i = 0;
+        while (i < NCALLS && r.nextInt() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextLong produce at least two distinct results
+     */
+    public void testNextLong() {
+        Random r = new Random();
+        long f = r.nextLong();
+        int i = 0;
+        while (i < NCALLS && r.nextLong() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextBoolean produce at least two distinct results
+     */
+    public void testNextBoolean() {
+        Random r = new Random();
+        boolean f = r.nextBoolean();
+        int i = 0;
+        while (i < NCALLS && r.nextBoolean() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextFloat produce at least two distinct results
+     */
+    public void testNextFloat() {
+        Random r = new Random();
+        float f = r.nextFloat();
+        int i = 0;
+        while (i < NCALLS && r.nextFloat() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextDouble produce at least two distinct results
+     */
+    public void testNextDouble() {
+        Random r = new Random();
+        double f = r.nextDouble();
+        int i = 0;
+        while (i < NCALLS && r.nextDouble() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextGaussian produce at least two distinct results
+     */
+    public void testNextGaussian() {
+        Random r = new Random();
+        double f = r.nextGaussian();
+        int i = 0;
+        while (i < NCALLS && r.nextGaussian() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * nextInt(negative) throws IllegalArgumentException
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNextIntBoundedNeg() {
+        Random r = new Random();
+        int f = r.nextInt(-17);
+    }
+
+    /**
+     * nextInt(bound) returns 0 <= value < bound; repeated calls produce at
+     * least two distinct results
+     */
+    public void testNextIntBounded() {
+        Random r = new Random();
+        // sample bound space across prime number increments
+        for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
+            int f = r.nextInt(bound);
+            assertTrue(0 <= f && f < bound);
+            int i = 0;
+            int j;
+            while (i < NCALLS &&
+                   (j = r.nextInt(bound)) == f) {
+                assertTrue(0 <= j && j < bound);
+                ++i;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * Invoking sized ints, long, doubles, with negative sizes throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamSize() {
+        Random r = new Random();
+        executeAndCatchIAE(() -> r.ints(-1L));
+        executeAndCatchIAE(() -> r.ints(-1L, 2, 3));
+        executeAndCatchIAE(() -> r.longs(-1L));
+        executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L));
+        executeAndCatchIAE(() -> r.doubles(-1L));
+        executeAndCatchIAE(() -> r.doubles(-1L, .5, .6));
+    }
+
+    /**
+     * Invoking bounded ints, long, doubles, with illegal bounds throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamBounds() {
+        Random r = new Random();
+        executeAndCatchIAE(() -> r.ints(2, 1));
+        executeAndCatchIAE(() -> r.ints(10, 42, 42));
+        executeAndCatchIAE(() -> r.longs(-1L, -1L));
+        executeAndCatchIAE(() -> r.longs(10, 1L, -2L));
+
+        testDoubleBadOriginBound((o, b) -> r.doubles(10, o, b));
+    }
+
+    // An arbitrary finite double value
+    static final double FINITE = Math.PI;
+
+    void testDoubleBadOriginBound(BiConsumer<Double, Double> bi) {
+        executeAndCatchIAE(() -> bi.accept(17.0, 2.0));
+        executeAndCatchIAE(() -> bi.accept(0.0, 0.0));
+        executeAndCatchIAE(() -> bi.accept(Double.NaN, FINITE));
+        executeAndCatchIAE(() -> bi.accept(FINITE, Double.NaN));
+        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
+
+        // Returns NaN
+//        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
+//        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
+
+        executeAndCatchIAE(() -> bi.accept(FINITE, Double.NEGATIVE_INFINITY));
+
+        // Returns Double.MAX_VALUE
+//        executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
+
+        executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
+        executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, FINITE));
+        executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
+    }
+
+    private void executeAndCatchIAE(Runnable r) {
+        executeAndCatch(IllegalArgumentException.class, r);
+    }
+
+    private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        }
+        catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught,
+                      String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+                                    expected.getName()));
+        Assert.assertTrue(expected.isInstance(caught),
+                          String.format("Exception thrown %s not an instance of %s",
+                                        caught.getClass().getName(), expected.getName()));
+    }
+
+    /**
+     * A sequential sized stream of ints generates the given number of values
+     */
+    public void testIntsCount() {
+        LongAdder counter = new LongAdder();
+        Random r = new Random();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.ints(size).forEach(x -> {
+                counter.increment();
+            });
+            assertEquals(counter.sum(), size);
+            size += 524959;
+        }
+    }
+
+    /**
+     * A sequential sized stream of longs generates the given number of values
+     */
+    public void testLongsCount() {
+        LongAdder counter = new LongAdder();
+        Random r = new Random();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.longs(size).forEach(x -> {
+                counter.increment();
+            });
+            assertEquals(counter.sum(), size);
+            size += 524959;
+        }
+    }
+
+    /**
+     * A sequential sized stream of doubles generates the given number of values
+     */
+    public void testDoublesCount() {
+        LongAdder counter = new LongAdder();
+        Random r = new Random();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.doubles(size).forEach(x -> {
+                counter.increment();
+            });
+            assertEquals(counter.sum(), size);
+            size += 524959;
+        }
+    }
+
+    /**
+     * Each of a sequential sized stream of bounded ints is within bounds
+     */
+    public void testBoundedInts() {
+        AtomicInteger fails = new AtomicInteger(0);
+        Random r = new Random();
+        long size = 12345L;
+        for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
+            for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
+                final int lo = least, hi = bound;
+                r.ints(size, lo, hi).
+                        forEach(x -> {
+                            if (x < lo || x >= hi)
+                                fails.getAndIncrement();
+                        });
+            }
+        }
+        assertEquals(fails.get(), 0);
+    }
+
+    /**
+     * Each of a sequential sized stream of bounded longs is within bounds
+     */
+    public void testBoundedLongs() {
+        AtomicInteger fails = new AtomicInteger(0);
+        Random r = new Random();
+        long size = 123L;
+        for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
+            for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+                final long lo = least, hi = bound;
+                r.longs(size, lo, hi).
+                        forEach(x -> {
+                            if (x < lo || x >= hi)
+                                fails.getAndIncrement();
+                        });
+            }
+        }
+        assertEquals(fails.get(), 0);
+    }
+
+    /**
+     * Each of a sequential sized stream of bounded doubles is within bounds
+     */
+    public void testBoundedDoubles() {
+        AtomicInteger fails = new AtomicInteger(0);
+        Random r = new Random();
+        long size = 456;
+        for (double least = 0.00011; least < 1.0e20; least *= 9) {
+            for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
+                final double lo = least, hi = bound;
+                r.doubles(size, lo, hi).
+                        forEach(x -> {
+                            if (x < lo || x >= hi)
+                                fails.getAndIncrement();
+                        });
+            }
+        }
+        assertEquals(fails.get(), 0);
+    }
+
+    /**
+     * A parallel unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCount() {
+        LongAdder counter = new LongAdder();
+        Random r = new Random();
+        long size = 100;
+        r.ints().limit(size).parallel().forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A parallel unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCount() {
+        LongAdder counter = new LongAdder();
+        Random r = new Random();
+        long size = 100;
+        r.longs().limit(size).parallel().forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A parallel unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCount() {
+        LongAdder counter = new LongAdder();
+        Random r = new Random();
+        long size = 100;
+        r.doubles().limit(size).parallel().forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A sequential unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCountSeq() {
+        LongAdder counter = new LongAdder();
+        Random r = new Random();
+        long size = 100;
+        r.ints().limit(size).forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A sequential unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCountSeq() {
+        LongAdder counter = new LongAdder();
+        Random r = new Random();
+        long size = 100;
+        r.longs().limit(size).forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A sequential unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCountSeq() {
+        LongAdder counter = new LongAdder();
+        Random r = new Random();
+        long size = 100;
+        r.doubles().limit(size).forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/SplittableRandom/SplittableRandomTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.SplittableRandom;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiConsumer;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+/**
+ * @test
+ * @run testng SplittableRandomTest
+ * @run testng/othervm -Djava.util.secureRandomSeed=true SplittableRandomTest
+ * @summary test methods on SplittableRandom
+ */
+@Test
+public class SplittableRandomTest {
+
+    // Note: this test was copied from the 166 TCK SplittableRandomTest test
+    // and modified to be a TestNG test
+
+    /*
+     * Testing coverage notes:
+     *
+     * 1. Many of the test methods are adapted from ThreadLocalRandomTest.
+     *
+     * 2. These tests do not check for random number generator quality.
+     * But we check for minimal API compliance by requiring that
+     * repeated calls to nextX methods, up to NCALLS tries, produce at
+     * least two distinct results. (In some possible universe, a
+     * "correct" implementation might fail, but the odds are vastly
+     * less than that of encountering a hardware failure while running
+     * the test.) For bounded nextX methods, we sample various
+     * intervals across multiples of primes. In other tests, we repeat
+     * under REPS different values.
+     */
+
+    // max numbers of calls to detect getting stuck on one value
+    static final int NCALLS = 10000;
+
+    // max sampled int bound
+    static final int MAX_INT_BOUND = (1 << 28);
+
+    // max sampled long bound
+    static final long MAX_LONG_BOUND = (1L << 42);
+
+    // Number of replications for other checks
+    static final int REPS = 20;
+
+    /**
+     * Repeated calls to nextInt produce at least two distinct results
+     */
+    public void testNextInt() {
+        SplittableRandom sr = new SplittableRandom();
+        int f = sr.nextInt();
+        int i = 0;
+        while (i < NCALLS && sr.nextInt() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextLong produce at least two distinct results
+     */
+    public void testNextLong() {
+        SplittableRandom sr = new SplittableRandom();
+        long f = sr.nextLong();
+        int i = 0;
+        while (i < NCALLS && sr.nextLong() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextDouble produce at least two distinct results
+     */
+    public void testNextDouble() {
+        SplittableRandom sr = new SplittableRandom();
+        double f = sr.nextDouble();
+        int i = 0;
+        while (i < NCALLS && sr.nextDouble() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Two SplittableRandoms created with the same seed produce the
+     * same values for nextLong.
+     */
+    public void testSeedConstructor() {
+        for (long seed = 2; seed < MAX_LONG_BOUND; seed += 15485863)  {
+            SplittableRandom sr1 = new SplittableRandom(seed);
+            SplittableRandom sr2 = new SplittableRandom(seed);
+            for (int i = 0; i < REPS; ++i)
+                assertEquals(sr1.nextLong(), sr2.nextLong());
+        }
+    }
+
+    /**
+     * A SplittableRandom produced by split() of a default-constructed
+     * SplittableRandom generates a different sequence
+     */
+    public void testSplit1() {
+        SplittableRandom sr = new SplittableRandom();
+        for (int reps = 0; reps < REPS; ++reps) {
+            SplittableRandom sc = sr.split();
+            int i = 0;
+            while (i < NCALLS && sr.nextLong() == sc.nextLong())
+                ++i;
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * A SplittableRandom produced by split() of a seeded-constructed
+     * SplittableRandom generates a different sequence
+     */
+    public void testSplit2() {
+        SplittableRandom sr = new SplittableRandom(12345);
+        for (int reps = 0; reps < REPS; ++reps) {
+            SplittableRandom sc = sr.split();
+            int i = 0;
+            while (i < NCALLS && sr.nextLong() == sc.nextLong())
+                ++i;
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextInt(negative) throws IllegalArgumentException
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNextIntBoundedNeg() {
+        SplittableRandom sr = new SplittableRandom();
+        int f = sr.nextInt(-17);
+    }
+
+    /**
+     * nextInt(least >= bound) throws IllegalArgumentException
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNextIntBadBounds() {
+        SplittableRandom sr = new SplittableRandom();
+        int f = sr.nextInt(17, 2);
+    }
+
+    /**
+     * nextInt(bound) returns 0 <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextIntBounded() {
+        SplittableRandom sr = new SplittableRandom();
+        // sample bound space across prime number increments
+        for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
+            int f = sr.nextInt(bound);
+            assertTrue(0 <= f && f < bound);
+            int i = 0;
+            int j;
+            while (i < NCALLS &&
+                   (j = sr.nextInt(bound)) == f) {
+                assertTrue(0 <= j && j < bound);
+                ++i;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextInt(least, bound) returns least <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextIntBounded2() {
+        SplittableRandom sr = new SplittableRandom();
+        for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
+            for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
+                int f = sr.nextInt(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                int j;
+                while (i < NCALLS &&
+                       (j = sr.nextInt(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * nextLong(negative) throws IllegalArgumentException
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNextLongBoundedNeg() {
+        SplittableRandom sr = new SplittableRandom();
+        long f = sr.nextLong(-17);
+    }
+
+    /**
+     * nextLong(least >= bound) throws IllegalArgumentException
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNextLongBadBounds() {
+        SplittableRandom sr = new SplittableRandom();
+        long f = sr.nextLong(17, 2);
+    }
+
+    /**
+     * nextLong(bound) returns 0 <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextLongBounded() {
+        SplittableRandom sr = new SplittableRandom();
+        for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
+            long f = sr.nextLong(bound);
+            assertTrue(0 <= f && f < bound);
+            int i = 0;
+            long j;
+            while (i < NCALLS &&
+                   (j = sr.nextLong(bound)) == f) {
+                assertTrue(0 <= j && j < bound);
+                ++i;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextLong(least, bound) returns least <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextLongBounded2() {
+        SplittableRandom sr = new SplittableRandom();
+        for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
+            for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+                long f = sr.nextLong(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                long j;
+                while (i < NCALLS &&
+                       (j = sr.nextLong(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * nextDouble(bound) throws IllegalArgumentException
+     */
+    public void testNextDoubleBadBound() {
+        SplittableRandom sr = new SplittableRandom();
+        executeAndCatchIAE(() -> sr.nextDouble(0.0));
+        executeAndCatchIAE(() -> sr.nextDouble(-0.0));
+        executeAndCatchIAE(() -> sr.nextDouble(+0.0));
+        executeAndCatchIAE(() -> sr.nextDouble(-1.0));
+        executeAndCatchIAE(() -> sr.nextDouble(Double.NaN));
+        executeAndCatchIAE(() -> sr.nextDouble(Double.NEGATIVE_INFINITY));
+
+        // Returns Double.MAX_VALUE
+//        executeAndCatchIAE(() -> r.nextDouble(Double.POSITIVE_INFINITY));
+    }
+
+    /**
+     * nextDouble(origin, bound) throws IllegalArgumentException
+     */
+    public void testNextDoubleBadOriginBound() {
+        testDoubleBadOriginBound(new SplittableRandom()::nextDouble);
+    }
+
+    // An arbitrary finite double value
+    static final double FINITE = Math.PI;
+
+    void testDoubleBadOriginBound(BiConsumer<Double, Double> bi) {
+        executeAndCatchIAE(() -> bi.accept(17.0, 2.0));
+        executeAndCatchIAE(() -> bi.accept(0.0, 0.0));
+        executeAndCatchIAE(() -> bi.accept(Double.NaN, FINITE));
+        executeAndCatchIAE(() -> bi.accept(FINITE, Double.NaN));
+        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
+
+        // Returns NaN
+//        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
+//        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
+
+        executeAndCatchIAE(() -> bi.accept(FINITE, Double.NEGATIVE_INFINITY));
+
+        // Returns Double.MAX_VALUE
+//        executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
+
+        executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
+        executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, FINITE));
+        executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
+    }
+
+    /**
+     * nextDouble(least, bound) returns least <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextDoubleBounded2() {
+        SplittableRandom sr = new SplittableRandom();
+        for (double least = 0.0001; least < 1.0e20; least *= 8) {
+            for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
+                double f = sr.nextDouble(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                double j;
+                while (i < NCALLS &&
+                       (j = sr.nextDouble(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * Invoking sized ints, long, doubles, with negative sizes throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamSize() {
+        SplittableRandom r = new SplittableRandom();
+        executeAndCatchIAE(() -> r.ints(-1L));
+        executeAndCatchIAE(() -> r.ints(-1L, 2, 3));
+        executeAndCatchIAE(() -> r.longs(-1L));
+        executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L));
+        executeAndCatchIAE(() -> r.doubles(-1L));
+        executeAndCatchIAE(() -> r.doubles(-1L, .5, .6));
+    }
+
+    /**
+     * Invoking bounded ints, long, doubles, with illegal bounds throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamBounds() {
+        SplittableRandom r = new SplittableRandom();
+        executeAndCatchIAE(() -> r.ints(2, 1));
+        executeAndCatchIAE(() -> r.ints(10, 42, 42));
+        executeAndCatchIAE(() -> r.longs(-1L, -1L));
+        executeAndCatchIAE(() -> r.longs(10, 1L, -2L));
+
+        testDoubleBadOriginBound((o, b) -> r.doubles(10, o, b));
+    }
+
+    private void executeAndCatchIAE(Runnable r) {
+        executeAndCatch(IllegalArgumentException.class, r);
+    }
+
+    private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        }
+        catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught,
+                      String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+                                    expected.getName()));
+        Assert.assertTrue(expected.isInstance(caught),
+                          String.format("Exception thrown %s not an instance of %s",
+                                        caught.getClass().getName(), expected.getName()));
+    }
+
+    /**
+     * A parallel sized stream of ints generates the given number of values
+     */
+    public void testIntsCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.ints(size).parallel().forEach(x -> {counter.increment();});
+            assertEquals(counter.sum(), size);
+            size += 524959;
+        }
+    }
+
+    /**
+     * A parallel sized stream of longs generates the given number of values
+     */
+    public void testLongsCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.longs(size).parallel().forEach(x -> {counter.increment();});
+            assertEquals(counter.sum(), size);
+            size += 524959;
+        }
+    }
+
+    /**
+     * A parallel sized stream of doubles generates the given number of values
+     */
+    public void testDoublesCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.doubles(size).parallel().forEach(x -> {counter.increment();});
+            assertEquals(counter.sum(), size);
+            size += 524959;
+        }
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded ints is within bounds
+     */
+    public void testBoundedInts() {
+        AtomicInteger fails = new AtomicInteger(0);
+        SplittableRandom r = new SplittableRandom();
+        long size = 12345L;
+        for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
+            for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
+                final int lo = least, hi = bound;
+                r.ints(size, lo, hi).parallel().
+                    forEach(x -> {if (x < lo || x >= hi)
+                                fails.getAndIncrement(); });
+            }
+        }
+        assertEquals(fails.get(), 0);
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded longs is within bounds
+     */
+    public void testBoundedLongs() {
+        AtomicInteger fails = new AtomicInteger(0);
+        SplittableRandom r = new SplittableRandom();
+        long size = 123L;
+        for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
+            for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+                final long lo = least, hi = bound;
+                r.longs(size, lo, hi).parallel().
+                    forEach(x -> {if (x < lo || x >= hi)
+                                fails.getAndIncrement(); });
+            }
+        }
+        assertEquals(fails.get(), 0);
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded doubles is within bounds
+     */
+    public void testBoundedDoubles() {
+        AtomicInteger fails = new AtomicInteger(0);
+        SplittableRandom r = new SplittableRandom();
+        long size = 456;
+        for (double least = 0.00011; least < 1.0e20; least *= 9) {
+            for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
+                final double lo = least, hi = bound;
+                r.doubles(size, lo, hi).parallel().
+                    forEach(x -> {if (x < lo || x >= hi)
+                                fails.getAndIncrement(); });
+            }
+        }
+        assertEquals(fails.get(), 0);
+    }
+
+    /**
+     * A parallel unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.ints().limit(size).parallel().forEach(x -> {counter.increment();});
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A parallel unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.longs().limit(size).parallel().forEach(x -> {counter.increment();});
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A parallel unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.doubles().limit(size).parallel().forEach(x -> {counter.increment();});
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A sequential unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCountSeq() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.ints().limit(size).forEach(x -> {counter.increment();});
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A sequential unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCountSeq() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.longs().limit(size).forEach(x -> {counter.increment();});
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A sequential unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCountSeq() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.doubles().limit(size).forEach(x -> {counter.increment();});
+        assertEquals(counter.sum(), size);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,559 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiConsumer;
+
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @run testng ThreadLocalRandomTest
+ * @summary test methods on ThreadLocalRandom
+ */
+@Test
+public class ThreadLocalRandomTest {
+
+    // Note: this test was copied from the 166 TCK ThreadLocalRandomTest test
+    // and modified to be a TestNG test
+
+    /*
+     * Testing coverage notes:
+     *
+     * We don't test randomness properties, but only that repeated
+     * calls, up to NCALLS tries, produce at least one different
+     * result.  For bounded versions, we sample various intervals
+     * across multiples of primes.
+     */
+
+    // max numbers of calls to detect getting stuck on one value
+    static final int NCALLS = 10000;
+
+    // max sampled int bound
+    static final int MAX_INT_BOUND = (1 << 28);
+
+    // max sampled long bound
+    static final long MAX_LONG_BOUND = (1L << 42);
+
+    // Number of replications for other checks
+    static final int REPS = 20;
+
+    /**
+     * setSeed throws UnsupportedOperationException
+     */
+    @Test(expectedExceptions = UnsupportedOperationException.class)
+    public void testSetSeed() {
+        ThreadLocalRandom.current().setSeed(17);
+    }
+
+    /**
+     * Repeated calls to nextInt produce at least two distinct results
+     */
+    public void testNextInt() {
+        int f = ThreadLocalRandom.current().nextInt();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextInt() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextLong produce at least two distinct results
+     */
+    public void testNextLong() {
+        long f = ThreadLocalRandom.current().nextLong();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextLong() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextBoolean produce at least two distinct results
+     */
+    public void testNextBoolean() {
+        boolean f = ThreadLocalRandom.current().nextBoolean();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextBoolean() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextFloat produce at least two distinct results
+     */
+    public void testNextFloat() {
+        float f = ThreadLocalRandom.current().nextFloat();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextFloat() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextDouble produce at least two distinct results
+     */
+    public void testNextDouble() {
+        double f = ThreadLocalRandom.current().nextDouble();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextDouble() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextGaussian produce at least two distinct results
+     */
+    public void testNextGaussian() {
+        double f = ThreadLocalRandom.current().nextGaussian();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextGaussian() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * nextInt(negative) throws IllegalArgumentException
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNextIntBoundedNeg() {
+        int f = ThreadLocalRandom.current().nextInt(-17);
+    }
+
+    /**
+     * nextInt(least >= bound) throws IllegalArgumentException
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNextIntBadBounds() {
+        int f = ThreadLocalRandom.current().nextInt(17, 2);
+    }
+
+    /**
+     * nextInt(bound) returns 0 <= value < bound; repeated calls produce at
+     * least two distinct results
+     */
+    public void testNextIntBounded() {
+        // sample bound space across prime number increments
+        for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
+            int f = ThreadLocalRandom.current().nextInt(bound);
+            assertTrue(0 <= f && f < bound);
+            int i = 0;
+            int j;
+            while (i < NCALLS &&
+                   (j = ThreadLocalRandom.current().nextInt(bound)) == f) {
+                assertTrue(0 <= j && j < bound);
+                ++i;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextInt(least, bound) returns least <= value < bound; repeated calls
+     * produce at least two distinct results
+     */
+    public void testNextIntBounded2() {
+        for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
+            for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
+                int f = ThreadLocalRandom.current().nextInt(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                int j;
+                while (i < NCALLS &&
+                       (j = ThreadLocalRandom.current().nextInt(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * nextLong(negative) throws IllegalArgumentException
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNextLongBoundedNeg() {
+        long f = ThreadLocalRandom.current().nextLong(-17);
+    }
+
+    /**
+     * nextLong(least >= bound) throws IllegalArgumentException
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNextLongBadBounds() {
+        long f = ThreadLocalRandom.current().nextLong(17, 2);
+    }
+
+    /**
+     * nextLong(bound) returns 0 <= value < bound; repeated calls produce at
+     * least two distinct results
+     */
+    public void testNextLongBounded() {
+        for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
+            long f = ThreadLocalRandom.current().nextLong(bound);
+            assertTrue(0 <= f && f < bound);
+            int i = 0;
+            long j;
+            while (i < NCALLS &&
+                   (j = ThreadLocalRandom.current().nextLong(bound)) == f) {
+                assertTrue(0 <= j && j < bound);
+                ++i;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextLong(least, bound) returns least <= value < bound; repeated calls
+     * produce at least two distinct results
+     */
+    public void testNextLongBounded2() {
+        for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
+            for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+                long f = ThreadLocalRandom.current().nextLong(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                long j;
+                while (i < NCALLS &&
+                       (j = ThreadLocalRandom.current().nextLong(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * nextDouble(bound) throws IllegalArgumentException
+     */
+    public void testNextDoubleBadBound() {
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        executeAndCatchIAE(() -> r.nextDouble(0.0));
+        executeAndCatchIAE(() -> r.nextDouble(-0.0));
+        executeAndCatchIAE(() -> r.nextDouble(+0.0));
+        executeAndCatchIAE(() -> r.nextDouble(-1.0));
+        executeAndCatchIAE(() -> r.nextDouble(Double.NaN));
+        executeAndCatchIAE(() -> r.nextDouble(Double.NEGATIVE_INFINITY));
+
+        // Returns Double.MAX_VALUE
+//        executeAndCatchIAE(() -> r.nextDouble(Double.POSITIVE_INFINITY));
+    }
+
+    /**
+     * nextDouble(origin, bound) throws IllegalArgumentException
+     */
+    public void testNextDoubleBadOriginBound() {
+        testDoubleBadOriginBound(ThreadLocalRandom.current()::nextDouble);
+    }
+
+    // An arbitrary finite double value
+    static final double FINITE = Math.PI;
+
+    void testDoubleBadOriginBound(BiConsumer<Double, Double> bi) {
+        executeAndCatchIAE(() -> bi.accept(17.0, 2.0));
+        executeAndCatchIAE(() -> bi.accept(0.0, 0.0));
+        executeAndCatchIAE(() -> bi.accept(Double.NaN, FINITE));
+        executeAndCatchIAE(() -> bi.accept(FINITE, Double.NaN));
+        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
+
+        // Returns NaN
+//        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
+//        executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
+
+        executeAndCatchIAE(() -> bi.accept(FINITE, Double.NEGATIVE_INFINITY));
+
+        // Returns Double.MAX_VALUE
+//        executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
+
+        executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
+        executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, FINITE));
+        executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
+    }
+
+    /**
+     * nextDouble(least, bound) returns least <= value < bound; repeated calls
+     * produce at least two distinct results
+     */
+    public void testNextDoubleBounded2() {
+        for (double least = 0.0001; least < 1.0e20; least *= 8) {
+            for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
+                double f = ThreadLocalRandom.current().nextDouble(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                double j;
+                while (i < NCALLS &&
+                       (j = ThreadLocalRandom.current().nextDouble(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * Invoking sized ints, long, doubles, with negative sizes throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamSize() {
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        executeAndCatchIAE(() -> r.ints(-1L));
+        executeAndCatchIAE(() -> r.ints(-1L, 2, 3));
+        executeAndCatchIAE(() -> r.longs(-1L));
+        executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L));
+        executeAndCatchIAE(() -> r.doubles(-1L));
+        executeAndCatchIAE(() -> r.doubles(-1L, .5, .6));
+    }
+
+    /**
+     * Invoking bounded ints, long, doubles, with illegal bounds throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamBounds() {
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        executeAndCatchIAE(() -> r.ints(2, 1));
+        executeAndCatchIAE(() -> r.ints(10, 42, 42));
+        executeAndCatchIAE(() -> r.longs(-1L, -1L));
+        executeAndCatchIAE(() -> r.longs(10, 1L, -2L));
+
+        testDoubleBadOriginBound((o, b) -> r.doubles(10, o, b));
+    }
+
+    private void executeAndCatchIAE(Runnable r) {
+        executeAndCatch(IllegalArgumentException.class, r);
+    }
+
+    private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        }
+        catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught,
+                      String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+                                    expected.getName()));
+        Assert.assertTrue(expected.isInstance(caught),
+                          String.format("Exception thrown %s not an instance of %s",
+                                        caught.getClass().getName(), expected.getName()));
+    }
+
+    /**
+     * A parallel sized stream of ints generates the given number of values
+     */
+    public void testIntsCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.ints(size).parallel().forEach(x -> {
+                counter.increment();
+            });
+            assertEquals(counter.sum(), size);
+            size += 524959;
+        }
+    }
+
+    /**
+     * A parallel sized stream of longs generates the given number of values
+     */
+    public void testLongsCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.longs(size).parallel().forEach(x -> {
+                counter.increment();
+            });
+            assertEquals(counter.sum(), size);
+            size += 524959;
+        }
+    }
+
+    /**
+     * A parallel sized stream of doubles generates the given number of values
+     */
+    public void testDoublesCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.doubles(size).parallel().forEach(x -> {
+                counter.increment();
+            });
+            assertEquals(counter.sum(), size);
+            size += 524959;
+        }
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded ints is within bounds
+     */
+    public void testBoundedInts() {
+        AtomicInteger fails = new AtomicInteger(0);
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 12345L;
+        for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
+            for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
+                final int lo = least, hi = bound;
+                r.ints(size, lo, hi).parallel().
+                        forEach(x -> {
+                            if (x < lo || x >= hi)
+                                fails.getAndIncrement();
+                        });
+            }
+        }
+        assertEquals(fails.get(), 0);
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded longs is within bounds
+     */
+    public void testBoundedLongs() {
+        AtomicInteger fails = new AtomicInteger(0);
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 123L;
+        for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
+            for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+                final long lo = least, hi = bound;
+                r.longs(size, lo, hi).parallel().
+                        forEach(x -> {
+                            if (x < lo || x >= hi)
+                                fails.getAndIncrement();
+                        });
+            }
+        }
+        assertEquals(fails.get(), 0);
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded doubles is within bounds
+     */
+    public void testBoundedDoubles() {
+        AtomicInteger fails = new AtomicInteger(0);
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 456;
+        for (double least = 0.00011; least < 1.0e20; least *= 9) {
+            for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
+                final double lo = least, hi = bound;
+                r.doubles(size, lo, hi).parallel().
+                        forEach(x -> {
+                            if (x < lo || x >= hi)
+                                fails.getAndIncrement();
+                        });
+            }
+        }
+        assertEquals(fails.get(), 0);
+    }
+
+    /**
+     * A parallel unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.ints().limit(size).parallel().forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A parallel unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.longs().limit(size).parallel().forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A parallel unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.doubles().limit(size).parallel().forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A sequential unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCountSeq() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.ints().limit(size).forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A sequential unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCountSeq() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.longs().limit(size).forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+    /**
+     * A sequential unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCountSeq() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.doubles().limit(size).forEach(x -> {
+            counter.increment();
+        });
+        assertEquals(counter.sum(), size);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,88 @@
+/*
+ * 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
+ * @run main/othervm/timeout=60 ReadersUnlockAfterWriteUnlock
+ * @bug 8023234
+ * @summary StampedLock serializes readers on writer unlock
+ * @author Dmitry Chyuko
+ * @author Aleksey Shipilev
+ */
+
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.locks.StampedLock;
+
+public class ReadersUnlockAfterWriteUnlock {
+    static final int RNUM = 2;
+    static final StampedLock sl = new StampedLock();
+    static volatile boolean isDone;
+
+    static CyclicBarrier iterationStart = new CyclicBarrier(RNUM + 1);
+    static CyclicBarrier readersHaveLocks = new CyclicBarrier(RNUM);
+    static CyclicBarrier writerHasLock = new CyclicBarrier(RNUM + 1);
+
+    static class Reader extends Thread {
+        final String name;
+        Reader(String name) {
+            super();
+            this.name = name;
+        }
+        public void run() {
+            while (!isDone && !isInterrupted()) {
+                try {
+                    iterationStart.await();
+                    writerHasLock.await();
+                    long rs = sl.readLock();
+
+                    // single reader blocks here indefinitely if readers
+                    // are serialized
+                    readersHaveLocks.await();
+
+                    sl.unlockRead(rs);
+                } catch (Exception e) {
+                    throw new IllegalStateException(e);
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+        for (int r = 0 ; r < RNUM; ++r) {
+            new Reader("r" + r).start();
+        }
+        int i;
+        for (i = 0; i < 1024; ++i) {
+            try {
+                iterationStart.await();
+                long ws = sl.writeLock();
+                writerHasLock.await();
+                Thread.sleep(10);
+                sl.unlockWrite(ws);
+            } catch (Exception e) {
+                throw new IllegalStateException(e);
+            }
+        }
+        isDone = true;
+    }
+
+}
--- a/test/java/util/function/BinaryOperator/BasicTest.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/util/function/BinaryOperator/BasicTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -67,26 +67,26 @@
     };
 
     public void testMaxBy() {
-        Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
+        Comparator<People> cmp = Comparator.comparing(People::getFirstName);
         // lesser
         assertSame(maxBy(cmp).apply(people[0], people[1]), people[1]);
         // euqal
-        cmp = Comparator.comparing((Function<People, String>) People::getLastName);
+        cmp = Comparator.comparing(People::getLastName);
         assertSame(maxBy(cmp).apply(people[0], people[1]), people[0]);
         // greater
-        cmp = Comparator.comparing((ToIntFunction<People>) People::getAge);
+        cmp = Comparator.comparingInt(People::getAge);
         assertSame(maxBy(cmp).apply(people[0], people[1]), people[0]);
     }
 
-    public void testLesserOf() {
-        Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
+    public void testMinBy() {
+        Comparator<People> cmp = Comparator.comparing(People::getFirstName);
         // lesser
         assertSame(minBy(cmp).apply(people[0], people[1]), people[0]);
         // euqal
-        cmp = Comparator.comparing((Function<People, String>) People::getLastName);
+        cmp = Comparator.comparing(People::getLastName);
         assertSame(minBy(cmp).apply(people[0], people[1]), people[0]);
         // greater
-        cmp = Comparator.comparing((ToIntFunction<People>) People::getAge);
+        cmp = Comparator.comparingInt(People::getAge);
         assertSame(minBy(cmp).apply(people[0], people[1]), people[1]);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/logging/Logger/getLogger/TestLogger.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * @test
+ * @bug 8005899
+ * @build TestLogger testlogger.MyResource
+ * @run main/othervm TestLogger
+ * @run main/othervm -Dsecurity=on TestLogger
+ **/
+public class TestLogger {
+
+    public static final String RESOURCE_BUNDLE = "testlogger.MyResource";
+    public static final String ORG_LOGGER = "org";
+    public static final String FOO_LOGGER = ORG_LOGGER + ".foo.Foo";
+    public static final String BAR_LOGGER = ORG_LOGGER + ".bar.Bar";
+    public static final String GEE_LOGGER = ORG_LOGGER + ".gee.Gee";
+    public static final String GEE_GEE_LOGGER = GEE_LOGGER+".Gee";
+
+    public static void main(String[] args) {
+        final String security = System.getProperty("security", "off");
+        System.out.println("Security is " + security);
+        if ("on".equals(security)) {
+           System.setSecurityManager(new SecurityManager());
+        }
+
+        newLogger(FOO_LOGGER, RESOURCE_BUNDLE);
+        newLogger(FOO_LOGGER);
+        newLogger(BAR_LOGGER);
+        newLogger(BAR_LOGGER, RESOURCE_BUNDLE);
+        newLogger(GEE_LOGGER, null);
+        newLogger(GEE_LOGGER, RESOURCE_BUNDLE);
+        newLogger(ORG_LOGGER);
+        newLogger(GEE_GEE_LOGGER);
+
+        for (String log : new String[] { FOO_LOGGER, BAR_LOGGER, GEE_LOGGER }) {
+            if (!RESOURCE_BUNDLE.equals(Logger.getLogger(log).getResourceBundleName())) {
+                throw new RuntimeException("Shouldn't allow to reset the resource bundle for " + log);
+            }
+            try {
+                Logger logger = Logger.getLogger(log, null);
+                if (!RESOURCE_BUNDLE.equals(logger.getResourceBundleName())) {
+                    throw new RuntimeException("Shouldn't allow to reset the resource bundle for " + log);
+                }
+                throw new RuntimeException("Expected IllegalArgumentException not thrown for " + log);
+            } catch (IllegalArgumentException e) {
+                System.out.println("Got expected exception for " + log +": " + e);
+            }
+        }
+        for (String log : new String[] { ORG_LOGGER, GEE_GEE_LOGGER }) {
+            if (Logger.getLogger(log).getResourceBundleName() != null) {
+                throw new RuntimeException("Resource bundle is not null for log: "
+                           + Logger.getLogger(log).getResourceBundleName());
+            }
+            try {
+                Logger logger = Logger.getLogger(log, null);
+                if (logger.getResourceBundleName() != null) {
+                    throw new RuntimeException("Resource bundle is not null for log: "
+                               + logger.getResourceBundleName());
+                }
+                System.out.println("Success calling Logger.getLogger(\""+log+"\", null)");
+            } catch (IllegalArgumentException e) {
+                throw new RuntimeException("Unexpected exception for " + log +": " + e, e);
+            }
+        }
+    }
+
+    private static List<Logger> strongRefs = new ArrayList<>();
+    private static void newLogger(String name) {
+        strongRefs.add(Logger.getLogger(name));
+    }
+    private static void newLogger(String name, String resourceBundleName) {
+        strongRefs.add(Logger.getLogger(name, resourceBundleName));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/logging/Logger/getLogger/testlogger/MyResource.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 testlogger;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+/**
+ * A dummy resource bundle for testing purposes.
+ * @author danielfuchs
+ */
+public class MyResource extends ResourceBundle {
+    Map<String, Object> bundle = new HashMap<>();
+
+    @Override
+    protected Object handleGetObject(String key) {
+         bundle.put(key,"Localized: " + key);
+         return bundle.get(key);
+    }
+
+    @Override
+    public Enumeration<String> getKeys() {
+        final Hashtable<String, Object> h = new Hashtable<>(bundle);
+        return h.keys();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/regex/PatternTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 Unit tests for wrapping classes should delegate to default methods
+ * @library ../stream/bootlib
+ * @build java.util.stream.OpTestCase
+ * @run testng/othervm PatternTest
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.regex.Pattern;
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.TestData;
+
+@Test
+public class PatternTest extends OpTestCase {
+
+    @DataProvider(name = "Stream<String>")
+    public static Object[][] makeStreamTestData() {
+        List<Object[]> data = new ArrayList<>();
+
+        String description = "";
+        String input = "awgqwefg1fefw4vssv1vvv1";
+        Pattern pattern = Pattern.compile("4");
+        List<String> expected = new ArrayList<>();
+        expected.add("awgqwefg1fefw");
+        expected.add("vssv1vvv1");
+
+        // Must match the type signature of the consumer of this data, testStrings
+        // String, String, Pattern, List<String>
+        data.add(new Object[]{description, input, pattern, expected});
+
+        input = "afbfq\u00a3abgwgb\u00a3awngnwggw\u00a3a\u00a3ahjrnhneerh";
+        pattern = Pattern.compile("\u00a3a");
+        expected = new ArrayList<>();
+        expected.add("afbfq");
+        expected.add("bgwgb");
+        expected.add("wngnwggw");
+        expected.add("");
+        expected.add("hjrnhneerh");
+
+        data.add(new Object[]{description, input, pattern, expected});
+
+
+        input = "awgqwefg1fefw4vssv1vvv1";
+        pattern = Pattern.compile("1");
+        expected = new ArrayList<>();
+        expected.add("awgqwefg");
+        expected.add("fefw4vssv");
+        expected.add("vvv");
+
+        data.add(new Object[]{description, input, pattern, expected});
+
+
+        input = "a\u4ebafg1fefw\u4eba4\u9f9cvssv\u9f9c1v\u672c\u672cvv";
+        pattern = Pattern.compile("1");
+        expected = new ArrayList<>();
+        expected.add("a\u4ebafg");
+        expected.add("fefw\u4eba4\u9f9cvssv\u9f9c");
+        expected.add("v\u672c\u672cvv");
+
+        data.add(new Object[]{description, input, pattern, expected});
+
+
+        input = "1\u56da23\u56da456\u56da7890";
+        pattern = Pattern.compile("\u56da");
+        expected = new ArrayList<>();
+        expected.add("1");
+        expected.add("23");
+        expected.add("456");
+        expected.add("7890");
+
+        data.add(new Object[]{description, input, pattern, expected});
+
+
+        input = "1\u56da23\u9f9c\u672c\u672c\u56da456\u56da\u9f9c\u672c7890";
+        pattern = Pattern.compile("\u56da");
+        expected = new ArrayList<>();
+        expected.add("1");
+        expected.add("23\u9f9c\u672c\u672c");
+        expected.add("456");
+        expected.add("\u9f9c\u672c7890");
+
+        data.add(new Object[]{description, input, pattern, expected});
+
+
+        input = "";
+        pattern = Pattern.compile("\u56da");
+        expected = new ArrayList<>();
+
+        data.add(new Object[]{description, input, pattern, expected});
+
+
+        description = "Multiple separators";
+        input = "This is,testing: with\tdifferent separators.";
+        pattern = Pattern.compile("[ \t,:.]");
+        expected = new ArrayList<>();
+        expected.add("This");
+        expected.add("is");
+        expected.add("testing");
+        expected.add("");
+        expected.add("with");
+        expected.add("different");
+        expected.add("separators");
+
+        data.add(new Object[] {description, input, pattern, expected});
+        return data.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "Stream<String>")
+    public void testStrings(String description, String input, Pattern pattern, List<String> expected) {
+        Supplier<Stream<String>> ss =  () -> pattern.splitAsStream(input);
+        withData(TestData.Factory.ofSupplier(description, ss))
+                .stream(LambdaTestHelpers.identity())
+                .expectedResult(expected)
+                .exercise();
+    }
+}
--- a/test/java/util/regex/RegExTest.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/util/regex/RegExTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -33,7 +33,7 @@
  * 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
  * 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
  * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066
- * 7067045 7014640 7189363 8007395 8013252 8013254 8012646
+ * 7067045 7014640 7189363 8007395 8013252 8013254 8012646 8023647
  */
 
 import java.util.regex.*;
@@ -146,6 +146,7 @@
         linebreakTest();
         branchTest();
         groupCurlyNotFoundSuppTest();
+        groupCurlyBackoffTest();
         patternAsPredicate();
         if (failure) {
             throw new
@@ -3999,6 +4000,15 @@
         report("GroupCurly NotFoundSupp");
     }
 
+    // This test is for 8023647
+    private static void groupCurlyBackoffTest() throws Exception {
+        if (!"abc1c".matches("(\\w)+1\\1") ||
+            "abc11".matches("(\\w)+1\\1")) {
+            failCount++;
+        }
+        report("GroupCurly backoff");
+    }
+
     // This test is for 8012646
     private static void patternAsPredicate() throws Exception {
         Predicate<String> p = Pattern.compile("[a-z]+").asPredicate();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.util;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.SplittableRandom;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.DoubleStream;
+import java.util.stream.DoubleStreamTestScenario;
+import java.util.stream.IntStream;
+import java.util.stream.IntStreamTestScenario;
+import java.util.stream.LongStream;
+import java.util.stream.LongStreamTestScenario;
+import java.util.stream.OpTestCase;
+import java.util.stream.StreamSupport;
+import java.util.stream.TestData;
+
+@Test
+public class SplittableRandomTest extends OpTestCase {
+
+    static class RandomBoxedSpliterator<T> implements Spliterator<T> {
+        final SplittableRandom rng;
+        long index;
+        final long fence;
+        final Function<SplittableRandom, T> rngF;
+
+        RandomBoxedSpliterator(SplittableRandom rng, long index, long fence, Function<SplittableRandom, T> rngF) {
+            this.rng = rng;
+            this.index = index;
+            this.fence = fence;
+            this.rngF = rngF;
+        }
+
+        public RandomBoxedSpliterator<T> trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                   new RandomBoxedSpliterator<>(rng.split(), i, index = m, rngF);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        @Override
+        public boolean tryAdvance(Consumer<? super T> consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rngF.apply(rng));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+    }
+
+    static final int SIZE = 1 << 16;
+
+    // Ensure there is a range of a power of 2
+    static final int[] BOUNDS = {256};
+    static final int[] ORIGINS = {-16, 0, 16};
+
+    static <T extends Comparable<T>> ResultAsserter<Iterable<T>> randomAsserter(int size, T origin, T bound) {
+        return (act, exp, ord, par) -> {
+            int count = 0;
+            Set<Comparable<T>> values = new HashSet<>();
+            for (Comparable<T> t : act) {
+                if (origin.compareTo(bound) < 0) {
+                    assertTrue(t.compareTo(origin) >= 0);
+                    assertTrue(t.compareTo(bound) < 0);
+                }
+                values.add(t);
+                count++;
+            }
+            assertEquals(count, size);
+            // Assert that at least one different result is produced
+            // For the size of the data it is highly improbable that this
+            // will cause a false negative (i.e. a false failure)
+            assertTrue(values.size() > 1);
+        };
+    }
+
+    @DataProvider(name = "ints")
+    public static Object[][] intsDataProvider() {
+        List<Object[]> data = new ArrayList<>();
+
+        // Function to create a stream using a RandomBoxedSpliterator
+
+        Function<Function<SplittableRandom, Integer>, IntStream> rbsf =
+                sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false).
+                        mapToInt(i -> i);
+
+        // Unbounded
+
+        data.add(new Object[]{
+                TestData.Factory.ofIntSupplier(
+                        String.format("new SplittableRandom().ints().limit(%d)", SIZE),
+                        () -> new SplittableRandom().ints().limit(SIZE)),
+                randomAsserter(SIZE, Integer.MAX_VALUE, 0)
+        });
+
+        data.add(new Object[]{
+                TestData.Factory.ofIntSupplier(
+                        String.format("new SplittableRandom().ints(%d)", SIZE),
+                        () -> new SplittableRandom().ints(SIZE)),
+                randomAsserter(SIZE, Integer.MAX_VALUE, 0)
+        });
+
+        data.add(new Object[]{
+                TestData.Factory.ofIntSupplier(
+                        String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt())", SIZE),
+                        () -> rbsf.apply(sr -> sr.nextInt())),
+                randomAsserter(SIZE, Integer.MAX_VALUE, 0)
+        });
+
+        // Bounded
+
+        for (int b : BOUNDS) {
+            for (int o : ORIGINS) {
+                final int origin = o;
+                final int bound = b;
+
+                data.add(new Object[]{
+                        TestData.Factory.ofIntSupplier(
+                                String.format("new SplittableRandom().ints(%d, %d).limit(%d)", origin, bound, SIZE),
+                                () -> new SplittableRandom().ints(origin, bound).limit(SIZE)),
+                        randomAsserter(SIZE, origin, bound)
+                });
+
+                data.add(new Object[]{
+                        TestData.Factory.ofIntSupplier(
+                                String.format("new SplittableRandom().ints(%d, %d, %d)", SIZE, origin, bound),
+                                () -> new SplittableRandom().ints(SIZE, origin, bound)),
+                        randomAsserter(SIZE, origin, bound)
+                });
+
+                if (origin == 0) {
+                    data.add(new Object[]{
+                            TestData.Factory.ofIntSupplier(
+                                    String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d))", SIZE, bound),
+                                    () -> rbsf.apply(sr -> sr.nextInt(bound))),
+                            randomAsserter(SIZE, origin, bound)
+                    });
+                }
+
+                data.add(new Object[]{
+                        TestData.Factory.ofIntSupplier(
+                                String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d, %d))", SIZE, origin, bound),
+                                () -> rbsf.apply(sr -> sr.nextInt(origin, bound))),
+                        randomAsserter(SIZE, origin, bound)
+                });
+            }
+        }
+
+        return data.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "ints")
+    public void testInts(TestData.OfInt data, ResultAsserter<Iterable<Integer>> ra) {
+        withData(data).
+                stream(s -> s).
+                without(IntStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+                resultAsserter(ra).
+                exercise();
+    }
+
+    @DataProvider(name = "longs")
+    public static Object[][] longsDataProvider() {
+        List<Object[]> data = new ArrayList<>();
+
+        // Function to create a stream using a RandomBoxedSpliterator
+
+        Function<Function<SplittableRandom, Long>, LongStream> rbsf =
+                sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false).
+                        mapToLong(i -> i);
+
+        // Unbounded
+
+        data.add(new Object[]{
+                TestData.Factory.ofLongSupplier(
+                        String.format("new SplittableRandom().longs().limit(%d)", SIZE),
+                        () -> new SplittableRandom().longs().limit(SIZE)),
+                randomAsserter(SIZE, Long.MAX_VALUE, 0L)
+        });
+
+        data.add(new Object[]{
+                TestData.Factory.ofLongSupplier(
+                        String.format("new SplittableRandom().longs(%d)", SIZE),
+                        () -> new SplittableRandom().longs(SIZE)),
+                randomAsserter(SIZE, Long.MAX_VALUE, 0L)
+        });
+
+        data.add(new Object[]{
+                TestData.Factory.ofLongSupplier(
+                        String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong())", SIZE),
+                        () -> rbsf.apply(sr -> sr.nextLong())),
+                randomAsserter(SIZE, Long.MAX_VALUE, 0L)
+        });
+
+        // Bounded
+
+        for (int b : BOUNDS) {
+            for (int o : ORIGINS) {
+                final long origin = o;
+                final long bound = b;
+
+                data.add(new Object[]{
+                        TestData.Factory.ofLongSupplier(
+                                String.format("new SplittableRandom().longs(%d, %d).limit(%d)", origin, bound, SIZE),
+                                () -> new SplittableRandom().longs(origin, bound).limit(SIZE)),
+                        randomAsserter(SIZE, origin, bound)
+                });
+
+                data.add(new Object[]{
+                        TestData.Factory.ofLongSupplier(
+                                String.format("new SplittableRandom().longs(%d, %d, %d)", SIZE, origin, bound),
+                                () -> new SplittableRandom().longs(SIZE, origin, bound)),
+                        randomAsserter(SIZE, origin, bound)
+                });
+
+                if (origin == 0) {
+                    data.add(new Object[]{
+                            TestData.Factory.ofLongSupplier(
+                                    String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d))", SIZE, bound),
+                                    () -> rbsf.apply(sr -> sr.nextLong(bound))),
+                            randomAsserter(SIZE, origin, bound)
+                    });
+                }
+
+                data.add(new Object[]{
+                        TestData.Factory.ofLongSupplier(
+                                String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d, %d))", SIZE, origin, bound),
+                                () -> rbsf.apply(sr -> sr.nextLong(origin, bound))),
+                        randomAsserter(SIZE, origin, bound)
+                });
+            }
+        }
+
+        return data.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "longs")
+    public void testLongs(TestData.OfLong data, ResultAsserter<Iterable<Long>> ra) {
+        withData(data).
+                stream(s -> s).
+                without(LongStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+                resultAsserter(ra).
+                exercise();
+    }
+
+    @DataProvider(name = "doubles")
+    public static Object[][] doublesDataProvider() {
+        List<Object[]> data = new ArrayList<>();
+
+        // Function to create a stream using a RandomBoxedSpliterator
+
+        Function<Function<SplittableRandom, Double>, DoubleStream> rbsf =
+                sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false).
+                        mapToDouble(i -> i);
+
+        // Unbounded
+
+        data.add(new Object[]{
+                TestData.Factory.ofDoubleSupplier(
+                        String.format("new SplittableRandom().doubles().limit(%d)", SIZE),
+                        () -> new SplittableRandom().doubles().limit(SIZE)),
+                randomAsserter(SIZE, Double.MAX_VALUE, 0d)
+        });
+
+        data.add(new Object[]{
+                TestData.Factory.ofDoubleSupplier(
+                        String.format("new SplittableRandom().doubles(%d)", SIZE),
+                        () -> new SplittableRandom().doubles(SIZE)),
+                randomAsserter(SIZE, Double.MAX_VALUE, 0d)
+        });
+
+        data.add(new Object[]{
+                TestData.Factory.ofDoubleSupplier(
+                        String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble())", SIZE),
+                        () -> rbsf.apply(sr -> sr.nextDouble())),
+                randomAsserter(SIZE, Double.MAX_VALUE, 0d)
+        });
+
+        // Bounded
+
+        for (int b : BOUNDS) {
+            for (int o : ORIGINS) {
+                final double origin = o;
+                final double bound = b;
+
+                data.add(new Object[]{
+                        TestData.Factory.ofDoubleSupplier(
+                                String.format("new SplittableRandom().doubles(%f, %f).limit(%d)", origin, bound, SIZE),
+                                () -> new SplittableRandom().doubles(origin, bound).limit(SIZE)),
+                        randomAsserter(SIZE, origin, bound)
+                });
+
+                data.add(new Object[]{
+                        TestData.Factory.ofDoubleSupplier(
+                                String.format("new SplittableRandom().doubles(%d, %f, %f)", SIZE, origin, bound),
+                                () -> new SplittableRandom().doubles(SIZE, origin, bound)),
+                        randomAsserter(SIZE, origin, bound)
+                });
+
+                if (origin == 0) {
+                    data.add(new Object[]{
+                            TestData.Factory.ofDoubleSupplier(
+                                    String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f))", SIZE, bound),
+                                    () -> rbsf.apply(sr -> sr.nextDouble(bound))),
+                            randomAsserter(SIZE, origin, bound)
+                    });
+                }
+
+                data.add(new Object[]{
+                        TestData.Factory.ofDoubleSupplier(
+                                String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f, %f))", SIZE, origin, bound),
+                                () -> rbsf.apply(sr -> sr.nextDouble(origin, bound))),
+                        randomAsserter(SIZE, origin, bound)
+                });
+            }
+        }
+
+        return data.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "doubles")
+    public void testDoubles(TestData.OfDouble data, ResultAsserter<Iterable<Double>> ra) {
+        withData(data).
+                stream(s -> s).
+                without(DoubleStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+                resultAsserter(ra).
+                exercise();
+    }
+}
--- a/test/java/util/zip/TestExtraTime.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/java/util/zip/TestExtraTime.java	Fri Sep 06 15:09:44 2013 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 4759491 6303183 7012868 8015666
+ * @bug 4759491 6303183 7012868 8015666 8023713
  * @summary Test ZOS and ZIS timestamp in extra field correctly
  */
 
@@ -32,6 +32,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.FileTime;
+import java.util.Arrays;
 import java.util.TimeZone;
 import java.util.concurrent.TimeUnit;
 import java.util.zip.ZipEntry;
@@ -52,24 +53,26 @@
             FileTime ctime = FileTime.from(time - 300000, TimeUnit.MILLISECONDS);
             TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
 
-            test(mtime, null, null, null);
-            // ms-dos 1980 epoch problem
-            test(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null);
-            // non-default tz
-            test(mtime, null, null, tz);
+            for (byte[] extra : new byte[][] { null, new byte[] {1, 2, 3}}) {
+                test(mtime, null, null, null, extra);
+                // ms-dos 1980 epoch problem
+                test(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null, extra);
+                // non-default tz
+                test(mtime, null, null, tz, extra);
 
-            test(mtime, atime, null, null);
-            test(mtime, null, ctime, null);
-            test(mtime, atime, ctime, null);
+                test(mtime, atime, null, null, extra);
+                test(mtime, null, ctime, null, extra);
+                test(mtime, atime, ctime, null, extra);
 
-            test(mtime, atime, null, tz);
-            test(mtime, null, ctime, tz);
-            test(mtime, atime, ctime, tz);
+                test(mtime, atime, null, tz, extra);
+                test(mtime, null, ctime, tz, extra);
+                test(mtime, atime, ctime, tz, extra);
+            }
         }
     }
 
     static void test(FileTime mtime, FileTime atime, FileTime ctime,
-                     TimeZone tz) throws Throwable {
+                     TimeZone tz, byte[] extra) throws Throwable {
         System.out.printf("--------------------%nTesting: [%s]/[%s]/[%s]%n",
                           mtime, atime, ctime);
         TimeZone tz0 = TimeZone.getDefault();
@@ -78,8 +81,8 @@
         }
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ZipOutputStream zos = new ZipOutputStream(baos);
-        ZipEntry ze = new ZipEntry("TestExtreTime.java");
-
+        ZipEntry ze = new ZipEntry("TestExtraTime.java");
+        ze.setExtra(extra);
         ze.setLastModifiedTime(mtime);
         if (atime != null)
             ze.setLastAccessTime(atime);
@@ -87,6 +90,14 @@
             ze.setCreationTime(ctime);
         zos.putNextEntry(ze);
         zos.write(new byte[] { 1,2 ,3, 4});
+
+        // append an extra entry to help check if the length and data
+        // of the extra field are being correctly written (in previous
+        // entry).
+        if (extra != null) {
+            ze = new ZipEntry("TestExtraEntry");
+            zos.putNextEntry(ze);
+        }
         zos.close();
         if (tz != null) {
             TimeZone.setDefault(tz0);
@@ -96,23 +107,23 @@
                                  new ByteArrayInputStream(baos.toByteArray()));
         ze = zis.getNextEntry();
         zis.close();
-        check(mtime, atime, ctime, ze);
+        check(mtime, atime, ctime, ze, extra);
 
         // ZipFile
         Path zpath = Paths.get(System.getProperty("test.dir", "."),
-                               "TestExtraTimp.zip");
+                               "TestExtraTime.zip");
         Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
         ZipFile zf = new ZipFile(zpath.toFile());
-        ze = zf.getEntry("TestExtreTime.java");
+        ze = zf.getEntry("TestExtraTime.java");
         // ZipFile read entry from cen, which does not have a/ctime,
         // for now.
-        check(mtime, null, null, ze);
+        check(mtime, null, null, ze, extra);
         zf.close();
         Files.delete(zpath);
     }
 
     static void check(FileTime mtime, FileTime atime, FileTime ctime,
-                      ZipEntry ze) {
+                      ZipEntry ze, byte[] extra) {
         /*
         System.out.printf("    mtime [%tc]: [%tc]/[%tc]%n",
                           mtime.to(TimeUnit.MILLISECONDS),
@@ -130,5 +141,17 @@
             ctime.to(TimeUnit.SECONDS) !=
             ze.getCreationTime().to(TimeUnit.SECONDS))
             throw new RuntimeException("Timestamp: storing ctime failed!");
+        if (extra != null) {
+            // if extra data exists, the current implementation put it at
+            // the end of the extra data array (implementation detail)
+            byte[] extra1 = ze.getExtra();
+            if (extra1 == null || extra1.length < extra.length ||
+                !Arrays.equals(Arrays.copyOfRange(extra1,
+                                                  extra1.length - extra.length,
+                                                  extra1.length),
+                               extra)) {
+                throw new RuntimeException("Timestamp: storing extra field failed!");
+            }
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/KPEquals.java	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8015669
+ * @summary KerberosPrincipal::equals should ignore name-type
+ * @compile -XDignore.symbol.file KPEquals.java
+ * @run main/othervm KPEquals
+ */
+
+import sun.security.jgss.GSSUtil;
+
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KeyTab;
+
+public class KPEquals {
+
+    public static void main(String[] args) throws Exception {
+        new OneKDC(null).writeJAASConf();
+        Context c = Context.fromJAAS("client");
+        Context s = Context.fromThinAir();
+        KerberosPrincipal kp = new KerberosPrincipal(
+                OneKDC.SERVER + "@" + OneKDC.REALM,
+                KerberosPrincipal.KRB_NT_SRV_INST);
+        s.s().getPrincipals().add(kp);
+        for (KerberosKey k: KeyTab.getInstance(kp).getKeys(kp)) {
+            s.s().getPrivateCredentials().add(k);
+        }
+        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        Context.handshake(c, s);
+    }
+}
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,14 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug   4366807
  * @summary Need new APIs to get/set session timeout and session cache size.
  * @run main/othervm SessionCacheSizeTests
- *
- *     SunJSSE does not support dynamic system properties, no way to re-use
- *     system properties in samevm/agentvm mode.
  */
 
 import java.io.*;
@@ -113,7 +115,9 @@
         /*
          * Signal Client, we're ready for his connect.
          */
-        serverReady = true;
+        if (createdPorts == serverPorts.length) {
+            serverReady = true;
+        }
         int read = 0;
         int nConnections = 0;
         /*
@@ -310,7 +314,6 @@
      * Fork off the other side, then do your work.
      */
     SessionCacheSizeTests() throws Exception {
-
         /*
          * create the SSLServerSocket and SSLSocket factories
          */
@@ -323,46 +326,87 @@
         int serverConns = MAX_ACTIVE_CONNECTIONS / (serverPorts.length);
         int remainingConns = MAX_ACTIVE_CONNECTIONS % (serverPorts.length);
 
-        if (separateServerThread) {
-            for (int i = 0; i < serverPorts.length; i++) {
-
-                // distribute remaining connections among the available ports
-                if (i < remainingConns)
-                    startServer(serverPorts[i], (serverConns + 1), true);
-                else
-                    startServer(serverPorts[i], serverConns, true);
+        Exception startException = null;
+        try {
+            if (separateServerThread) {
+                for (int i = 0; i < serverPorts.length; i++) {
+                    // distribute remaining connections among the
+                    // available ports
+                    if (i < remainingConns)
+                        startServer(serverPorts[i], (serverConns + 1), true);
+                    else
+                        startServer(serverPorts[i], serverConns, true);
+                }
+                startClient(false);
+            } else {
+                startClient(true);
+                for (int i = 0; i < serverPorts.length; i++) {
+                    if (i < remainingConns)
+                        startServer(serverPorts[i], (serverConns + 1), false);
+                    else
+                        startServer(serverPorts[i], serverConns, false);
+                }
             }
-            startClient(false);
-        } else {
-            startClient(true);
-            for (int i = 0; i < serverPorts.length; i++) {
-                if (i < remainingConns)
-                    startServer(serverPorts[i], (serverConns + 1), false);
-                else
-                    startServer(serverPorts[i], serverConns, false);
-            }
+        } catch (Exception e) {
+            startException = e;
         }
 
         /*
          * Wait for other side to close down.
          */
         if (separateServerThread) {
-            serverThread.join();
+            if (serverThread != null) {
+                serverThread.join();
+            }
         } else {
-            clientThread.join();
+            if (clientThread != null) {
+                clientThread.join();
+            }
         }
 
         /*
          * When we get here, the test is pretty much over.
-         *
-         * If the main thread excepted, that propagates back
-         * immediately.  If the other thread threw an exception, we
-         * should report back.
+         */
+        Exception local;
+        Exception remote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+        } else {
+            remote = clientException;
+            local = serverException;
+        }
+
+        Exception exception = null;
+
+        /*
+         * Check various exception conditions.
          */
-        if (serverException != null)
-            throw serverException;
-        if (clientException != null)
-            throw clientException;
+        if ((local != null) && (remote != null)) {
+            // If both failed, return the curthread's exception.
+            local.initCause(remote);
+            exception = local;
+        } else if (local != null) {
+            exception = local;
+        } else if (remote != null) {
+            exception = remote;
+        } else if (startException != null) {
+            exception = startException;
+        }
+
+        /*
+         * If there was an exception *AND* a startException,
+         * output it.
+         */
+        if (exception != null) {
+            if (exception != startException && startException != null) {
+                exception.addSuppressed(startException);
+            }
+            throw exception;
+        }
+
+        // Fall-through: no exception to throw!
     }
 
     void startServer(final int port, final int nConns,
@@ -387,7 +431,13 @@
             };
             serverThread.start();
         } else {
-            doServerSide(port, nConns);
+            try {
+                doServerSide(port, nConns);
+            } catch (Exception e) {
+                serverException = e;
+            } finally {
+                serverReady = true;
+            }
         }
     }
 
@@ -409,7 +459,11 @@
             };
             clientThread.start();
         } else {
-            doClientSide();
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                clientException = e;
+            }
         }
     }
 }
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java	Fri Sep 06 15:09:44 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,14 +21,14 @@
  * questions.
  */
 
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
 /*
  * @test
  * @bug   4366807
  * @summary Need new APIs to get/set session timeout and session cache size.
  * @run main/othervm SessionTimeOutTests
- *
- *     SunJSSE does not support dynamic system properties, no way to re-use
- *     system properties in samevm/agentvm mode.
  */
 
 import java.io.*;
@@ -263,7 +263,7 @@
         for (int i = 0; i < nConnections; i++) {
             sslSockets[i].close();
         }
-         System.out.println("----------------------------------------"
+        System.out.println("----------------------------------------"
                                  + "-----------------------");
         System.out.println("Session timeout test passed");
     }
@@ -348,45 +348,88 @@
         int serverConns = MAX_ACTIVE_CONNECTIONS / (serverPorts.length);
         int remainingConns = MAX_ACTIVE_CONNECTIONS % (serverPorts.length);
 
-        if (separateServerThread) {
-            for (int i = 0; i < serverPorts.length; i++) {
-                // distribute remaining connections among the available ports
-                if (i < remainingConns)
-                    startServer(serverPorts[i], (serverConns + 1), true);
-                else
-                    startServer(serverPorts[i], serverConns, true);
+        Exception startException = null;
+        try {
+            if (separateServerThread) {
+                for (int i = 0; i < serverPorts.length; i++) {
+                    // distribute remaining connections among the
+                    // vailable ports
+                    if (i < remainingConns)
+                        startServer(serverPorts[i], (serverConns + 1), true);
+                    else
+                        startServer(serverPorts[i], serverConns, true);
+                }
+                startClient(false);
+            } else {
+                startClient(true);
+                for (int i = 0; i < serverPorts.length; i++) {
+                    if (i < remainingConns)
+                        startServer(serverPorts[i], (serverConns + 1), false);
+                    else
+                        startServer(serverPorts[i], serverConns, false);
+                }
             }
-            startClient(false);
-        } else {
-            startClient(true);
-            for (int i = 0; i < serverPorts.length; i++) {
-                if (i < remainingConns)
-                    startServer(serverPorts[i], (serverConns + 1), false);
-                else
-                    startServer(serverPorts[i], serverConns, false);
-            }
+        } catch (Exception e) {
+            startException = e;
         }
 
         /*
          * Wait for other side to close down.
          */
         if (separateServerThread) {
-            serverThread.join();
+            if (serverThread != null) {
+                serverThread.join();
+            }
         } else {
-            clientThread.join();
+            if (clientThread != null) {
+                clientThread.join();
+            }
         }
 
         /*
          * When we get here, the test is pretty much over.
-         *
-         * If the main thread excepted, that propagates back
-         * immediately.  If the other thread threw an exception, we
-         * should report back.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+        } else {
+            remote = clientException;
+            local = serverException;
+        }
+
+        Exception exception = null;
+
+        /*
+         * Check various exception conditions.
          */
-        if (serverException != null)
-            throw serverException;
-        if (clientException != null)
-            throw clientException;
+        if ((local != null) && (remote != null)) {
+            // If both failed, return the curthread's exception.
+            local.initCause(remote);
+            exception = local;
+        } else if (local != null) {
+            exception = local;
+        } else if (remote != null) {
+            exception = remote;
+        } else if (startException != null) {
+            exception = startException;
+        }
+
+        /*
+         * If there was an exception *AND* a startException,
+         * output it.
+         */
+        if (exception != null) {
+            if (exception != startException && startException != null) {
+                exception.addSuppressed(startException);
+            }
+            throw exception;
+        }
+
+        // Fall-through: no exception to throw!
     }
 
     void startServer(final int port, final int nConns,
@@ -411,7 +454,13 @@
             };
             serverThread.start();
         } else {
-            doServerSide(port, nConns);
+            try {
+                doServerSide(port, nConns);
+            } catch (Exception e) {
+                serverException = e;
+            } finally {
+                serverReady = 0;
+            }
         }
     }
 
@@ -433,7 +482,11 @@
             };
             clientThread.start();
         } else {
-            doClientSide();
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                clientException = e;
+            }
         }
     }
 }
--- a/test/sun/security/ssl/templates/SSLSocketTemplate.java	Thu Sep 05 15:37:40 2013 +0400
+++ b/test/sun/security/ssl/templates/SSLSocketTemplate.java	Fri Sep 06 15:09:44 2013 -0700
@@ -243,7 +243,7 @@
          * output it.
          */
         if (exception != null) {
-            if (exception != startException) {
+            if (exception != startException && startException != null) {
                 exception.addSuppressed(startException);
             }
             throw exception;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/tools/jarsigner/jvindex.sh	Fri Sep 06 15:09:44 2013 -0700
@@ -0,0 +1,76 @@
+#
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# 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 8022761
+# @summary regression: SecurityException is NOT thrown while trying to pack a wrongly signed Indexed Jar file
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+  JAVAC_CMD=`which javac`
+  TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  Windows_* )
+    FS="\\"
+    ;;
+  * )
+    FS="/"
+    ;;
+esac
+
+F=abcde
+KS=jvindex.jks
+JFILE=jvindex.jar
+
+KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \
+        -keystore $KS"
+JAR=$TESTJAVA${FS}bin${FS}jar
+JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit"
+
+rm $F $KS $JFILE 2> /dev/null
+
+echo 12345 > $F
+$JAR cvf $JFILE $F
+
+ERR=""
+
+$KT -alias a -dname CN=a -genkey -validity 300 || ERR="$ERR 1"
+
+$JARSIGNER $JFILE a || ERR="$ERR 2"
+$JAR i $JFILE
+
+# Make sure the $F line has "sm" (signed and in manifest)
+$JARSIGNER -verify -verbose $JFILE | grep $F | grep sm || ERR="$ERR 3"
+
+if [ "$ERR" = "" ]; then
+    exit 0
+else
+    echo "ERR is $ERR"
+    exit 1
+fi
+
+