Merge
authorvinnie
Wed, 03 Jul 2013 14:35:10 -0700
changeset 18773 9eb5f8a1f933
parent 18772 ab43f18c524e (current diff)
parent 18771 9dadb0719cea (diff)
child 18774 e951a7044fed
Merge
--- a/jdk/src/share/classes/java/lang/Class.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/lang/Class.java	Wed Jul 03 14:35:10 2013 -0700
@@ -360,36 +360,24 @@
      * any exception thrown by the constructor in a (checked) {@link
      * java.lang.reflect.InvocationTargetException}.
      *
-     * @return     a newly allocated instance of the class represented by this
-     *             object.
-     * @exception  IllegalAccessException  if the class or its nullary
-     *               constructor is not accessible.
-     * @exception  InstantiationException
-     *               if this {@code Class} represents an abstract class,
-     *               an interface, an array class, a primitive type, or void;
-     *               or if the class has no nullary constructor;
-     *               or if the instantiation fails for some other reason.
-     * @exception  ExceptionInInitializerError if the initialization
-     *               provoked by this method fails.
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
-     *
-     *             <ul>
-     *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
-     *             creation of new instances of this class
-     *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
-     *
-     *             </ul>
-     *
+     * @return  a newly allocated instance of the class represented by this
+     *          object.
+     * @throws  IllegalAccessException  if the class or its nullary
+     *          constructor is not accessible.
+     * @throws  InstantiationException
+     *          if this {@code Class} represents an abstract class,
+     *          an interface, an array class, a primitive type, or void;
+     *          or if the class has no nullary constructor;
+     *          or if the instantiation fails for some other reason.
+     * @throws  ExceptionInInitializerError if the initialization
+     *          provoked by this method fails.
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and
+     *          the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class.
      */
     @CallerSensitive
     public T newInstance()
@@ -981,24 +969,27 @@
      *
      * @return the immediately enclosing method of the underlying class, if
      *     that class is a local or anonymous class; otherwise {@code null}.
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
      *
-     *             <ul>
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and any of the
+     *         following conditions is met:
+     *
+     *         <ul>
      *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(enclosingClass, Member.DECLARED)} denies
-     *             access to the methods within the enclosing class
+     *         <li> the caller's class loader is not the same as the
+     *         class loader of the enclosing class and invocation of
+     *         {@link SecurityManager#checkPermission
+     *         s.checkPermission} method with
+     *         {@code RuntimePermission("accessDeclaredMembers")}
+     *         denies access to the methods within the enclosing class
      *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the enclosing class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of the enclosing class
+     *         <li> the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the enclosing class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of the enclosing class
      *
-     *             </ul>
+     *         </ul>
      * @since 1.5
      */
     @CallerSensitive
@@ -1025,11 +1016,6 @@
 
             // Perform access check
             Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
-            // be very careful not to change the stack depth of this
-            // checkMemberAccess call for security reasons
-            // see java.lang.SecurityManager.checkMemberAccess
-            //
-            // Note that we need to do this on the enclosing class
             enclosingCandidate.checkMemberAccess(Member.DECLARED,
                                                  Reflection.getCallerClass(), true);
             /*
@@ -1137,24 +1123,26 @@
      *
      * @return the immediately enclosing constructor of the underlying class, if
      *     that class is a local or anonymous class; otherwise {@code null}.
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and any of the
+     *         following conditions is met:
      *
-     *             <ul>
+     *         <ul>
      *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(enclosingClass, Member.DECLARED)} denies
-     *             access to the constructors within the enclosing class
+     *         <li> the caller's class loader is not the same as the
+     *         class loader of the enclosing class and invocation of
+     *         {@link SecurityManager#checkPermission
+     *         s.checkPermission} method with
+     *         {@code RuntimePermission("accessDeclaredMembers")}
+     *         denies access to the constructors within the enclosing class
      *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the enclosing class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of the enclosing class
+     *         <li> the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the enclosing class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of the enclosing class
      *
-     *             </ul>
+     *         </ul>
      * @since 1.5
      */
     @CallerSensitive
@@ -1180,11 +1168,6 @@
 
             // Perform access check
             Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
-            // be very careful not to change the stack depth of this
-            // checkMemberAccess call for security reasons
-            // see java.lang.SecurityManager.checkMemberAccess
-            //
-            // Note that we need to do this on the enclosing class
             enclosingCandidate.checkMemberAccess(Member.DECLARED,
                                                  Reflection.getCallerClass(), true);
             /*
@@ -1457,25 +1440,14 @@
      * class, or void.
      *
      * @return the array of {@code Class} objects representing the public
-     * members of this class
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
-     *
-     *             <ul>
-     *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.PUBLIC)} method
-     *             denies access to the classes within this class
-     *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
-     *
-     *             </ul>
+     *         members of this class
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
      *
      * @since JDK1.1
      */
@@ -1530,25 +1502,14 @@
      * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
      *
      * @return the array of {@code Field} objects representing the
-     * public fields
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
-     *
-     *             <ul>
-     *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
-     *             access to the fields within this class
-     *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
-     *
-     *             </ul>
+     *         public fields
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
      *
      * @since JDK1.1
      */
@@ -1579,25 +1540,14 @@
      * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
      *
      * @return the array of {@code Method} objects representing the
-     * public methods of this class
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
-     *
-     *             <ul>
-     *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
-     *             access to the methods within this class
-     *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
-     *
-     *             </ul>
+     *         public methods of this class
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
      *
      * @since JDK1.1
      */
@@ -1626,25 +1576,14 @@
      * {@code Constructor<T>[]}.
      *
      * @return the array of {@code Constructor} objects representing the
-     *  public constructors of this class
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
-     *
-     *             <ul>
-     *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
-     *             access to the constructors within this class
-     *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
-     *
-     *             </ul>
+     *         public constructors of this class
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
      *
      * @since JDK1.1
      */
@@ -1678,29 +1617,18 @@
      * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
      *
      * @param name the field name
-     * @return  the {@code Field} object of this class specified by
-     * {@code name}
-     * @exception NoSuchFieldException if a field with the specified name is
-     *              not found.
-     * @exception NullPointerException if {@code name} is {@code null}
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
-     *
-     *             <ul>
-     *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
-     *             access to the field
-     *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
-     *
-     *             </ul>
+     * @return the {@code Field} object of this class specified by
+     *         {@code name}
+     * @throws NoSuchFieldException if a field with the specified name is
+     *         not found.
+     * @throws NullPointerException if {@code name} is {@code null}
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
      *
      * @since JDK1.1
      */
@@ -1762,28 +1690,17 @@
      * @param name the name of the method
      * @param parameterTypes the list of parameters
      * @return the {@code Method} object that matches the specified
-     * {@code name} and {@code parameterTypes}
-     * @exception NoSuchMethodException if a matching method is not found
-     *            or if the name is "&lt;init&gt;"or "&lt;clinit&gt;".
-     * @exception NullPointerException if {@code name} is {@code null}
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
-     *
-     *             <ul>
-     *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
-     *             access to the method
-     *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
-     *
-     *             </ul>
+     *         {@code name} and {@code parameterTypes}
+     * @throws NoSuchMethodException if a matching method is not found
+     *         or if the name is "&lt;init&gt;"or "&lt;clinit&gt;".
+     * @throws NullPointerException if {@code name} is {@code null}
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
      *
      * @since JDK1.1
      */
@@ -1816,26 +1733,15 @@
      *
      * @param parameterTypes the parameter array
      * @return the {@code Constructor} object of the public constructor that
-     * matches the specified {@code parameterTypes}
-     * @exception NoSuchMethodException if a matching method is not found.
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
-     *
-     *             <ul>
-     *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
-     *             access to the constructor
-     *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
-     *
-     *             </ul>
+     *         matches the specified {@code parameterTypes}
+     * @throws NoSuchMethodException if a matching method is not found.
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and
+     *         the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class.
      *
      * @since JDK1.1
      */
@@ -1858,25 +1764,27 @@
      * primitive type, an array class, or void.
      *
      * @return the array of {@code Class} objects representing all the
-     * declared members of this class
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
+     *         declared members of this class
+     * @throws SecurityException
+     *         If a security manager, <i>s</i>, is present and any of the
+     *         following conditions is met:
      *
-     *             <ul>
+     *         <ul>
      *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.DECLARED)} denies
-     *             access to the declared classes within this class
+     *         <li> the caller's class loader is not the same as the
+     *         class loader of this class and invocation of
+     *         {@link SecurityManager#checkPermission
+     *         s.checkPermission} method with
+     *         {@code RuntimePermission("accessDeclaredMembers")}
+     *         denies access to the declared classes within this class
      *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
+     *         <li> the caller's class loader is not the same as or an
+     *         ancestor of the class loader for the current class and
+     *         invocation of {@link SecurityManager#checkPackageAccess
+     *         s.checkPackageAccess()} denies access to the package
+     *         of this class
      *
-     *             </ul>
+     *         </ul>
      *
      * @since JDK1.1
      */
@@ -1899,26 +1807,28 @@
      *
      * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
      *
-     * @return    the array of {@code Field} objects representing all the
-     * declared fields of this class
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
+     * @return  the array of {@code Field} objects representing all the
+     *          declared fields of this class
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
      *
-     *             <ul>
+     *          <ul>
      *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.DECLARED)} denies
-     *             access to the declared fields within this class
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared fields within this class
      *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
      *
-     *             </ul>
+     *          </ul>
      *
      * @since JDK1.1
      */
@@ -1945,26 +1855,28 @@
      *
      * <p> See <em>The Java Language Specification</em>, section 8.2.
      *
-     * @return    the array of {@code Method} objects representing all the
-     * declared methods of this class
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
+     * @return  the array of {@code Method} objects representing all the
+     *          declared methods of this class
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
      *
-     *             <ul>
+     *          <ul>
      *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.DECLARED)} denies
-     *             access to the declared methods within this class
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared methods within this class
      *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
      *
-     *             </ul>
+     *          </ul>
      *
      * @since JDK1.1
      */
@@ -1988,26 +1900,28 @@
      *
      * <p> See <em>The Java Language Specification</em>, section 8.2.
      *
-     * @return    the array of {@code Constructor} objects representing all the
-     * declared constructors of this class
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
+     * @return  the array of {@code Constructor} objects representing all the
+     *          declared constructors of this class
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
      *
-     *             <ul>
+     *          <ul>
      *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.DECLARED)} denies
-     *             access to the declared constructors within this class
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared constructors within this class
      *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
      *
-     *             </ul>
+     *          </ul>
      *
      * @since JDK1.1
      */
@@ -2026,29 +1940,31 @@
      * will not reflect the {@code length} field of an array class.
      *
      * @param name the name of the field
-     * @return the {@code Field} object for the specified field in this
-     * class
-     * @exception NoSuchFieldException if a field with the specified name is
-     *              not found.
-     * @exception NullPointerException if {@code name} is {@code null}
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
+     * @return  the {@code Field} object for the specified field in this
+     *          class
+     * @throws  NoSuchFieldException if a field with the specified name is
+     *          not found.
+     * @throws  NullPointerException if {@code name} is {@code null}
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
      *
-     *             <ul>
+     *          <ul>
      *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.DECLARED)} denies
-     *             access to the declared field
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared field
      *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
      *
-     *             </ul>
+     *          </ul>
      *
      * @since JDK1.1
      */
@@ -2080,28 +1996,30 @@
      *
      * @param name the name of the method
      * @param parameterTypes the parameter array
-     * @return    the {@code Method} object for the method of this class
-     * matching the specified name and parameters
-     * @exception NoSuchMethodException if a matching method is not found.
-     * @exception NullPointerException if {@code name} is {@code null}
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
+     * @return  the {@code Method} object for the method of this class
+     *          matching the specified name and parameters
+     * @throws  NoSuchMethodException if a matching method is not found.
+     * @throws  NullPointerException if {@code name} is {@code null}
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
      *
-     *             <ul>
+     *          <ul>
      *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.DECLARED)} denies
-     *             access to the declared method
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared method
      *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
      *
-     *             </ul>
+     *          </ul>
      *
      * @since JDK1.1
      */
@@ -2129,27 +2047,29 @@
      * include the explicit enclosing instance as the first parameter.
      *
      * @param parameterTypes the parameter array
-     * @return    The {@code Constructor} object for the constructor with the
-     * specified parameter list
-     * @exception NoSuchMethodException if a matching method is not found.
-     * @exception  SecurityException
-     *             If a security manager, <i>s</i>, is present and any of the
-     *             following conditions is met:
+     * @return  The {@code Constructor} object for the constructor with the
+     *          specified parameter list
+     * @throws  NoSuchMethodException if a matching method is not found.
+     * @throws  SecurityException
+     *          If a security manager, <i>s</i>, is present and any of the
+     *          following conditions is met:
      *
-     *             <ul>
+     *          <ul>
      *
-     *             <li> invocation of
-     *             {@link SecurityManager#checkMemberAccess
-     *             s.checkMemberAccess(this, Member.DECLARED)} denies
-     *             access to the declared constructor
+     *          <li> the caller's class loader is not the same as the
+     *          class loader of this class and invocation of
+     *          {@link SecurityManager#checkPermission
+     *          s.checkPermission} method with
+     *          {@code RuntimePermission("accessDeclaredMembers")}
+     *          denies access to the declared constructor
      *
-     *             <li> the caller's class loader is not the same as or an
-     *             ancestor of the class loader for the current class and
-     *             invocation of {@link SecurityManager#checkPackageAccess
-     *             s.checkPackageAccess()} denies access to the package
-     *             of this class
+     *          <li> the caller's class loader is not the same as or an
+     *          ancestor of the class loader for the current class and
+     *          invocation of {@link SecurityManager#checkPackageAccess
+     *          s.checkPackageAccess()} denies access to the package
+     *          of this class
      *
-     *             </ul>
+     *          </ul>
      *
      * @since JDK1.1
      */
@@ -2306,14 +2226,6 @@
      */
     static native Class<?> getPrimitiveClass(String name);
 
-    private static boolean isCheckMemberAccessOverridden(SecurityManager smgr) {
-        if (smgr.getClass() == SecurityManager.class) return false;
-
-        Class<?>[] paramTypes = new Class<?>[] {Class.class, int.class};
-        return smgr.getClass().getMethod0("checkMemberAccess", paramTypes).
-                getDeclaringClass() != SecurityManager.class;
-    }
-
     /*
      * Check if client is allowed to access members.  If access is denied,
      * throw a SecurityException.
@@ -2326,19 +2238,17 @@
     private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
         final SecurityManager s = System.getSecurityManager();
         if (s != null) {
+            /* Default policy allows access to all {@link Member#PUBLIC} members,
+             * as well as access to classes that have the same class loader as the caller.
+             * In all other cases, it requires RuntimePermission("accessDeclaredMembers")
+             * permission.
+             */
             final ClassLoader ccl = ClassLoader.getClassLoader(caller);
             final ClassLoader cl = getClassLoader0();
-            if (!isCheckMemberAccessOverridden(s)) {
-                // Inlined SecurityManager.checkMemberAccess
-                if (which != Member.PUBLIC) {
-                    if (ccl != cl) {
-                        s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
-                    }
+            if (which != Member.PUBLIC) {
+                if (ccl != cl) {
+                    s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
                 }
-            } else {
-                // Don't refactor; otherwise break the stack depth for
-                // checkMemberAccess of subclasses of SecurityManager as specified.
-                s.checkMemberAccess(this, which);
             }
             this.checkPackageAccess(ccl, checkProxyInterfaces);
         }
--- a/jdk/src/share/classes/java/lang/SecurityManager.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/lang/SecurityManager.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1675,10 +1675,18 @@
      *             permission to access members.
      * @exception  NullPointerException if the <code>clazz</code> argument is
      *             <code>null</code>.
+     *
+     * @deprecated This method relies on the caller being at a stack depth
+     *             of 4 which is error-prone and cannot be enforced by the runtime.
+     *             Users of this method should instead invoke {@link #checkPermission}
+     *             directly.  This method will be changed in a future release
+     *             to check the permission {@code java.security.AllPermission}.
+     *
      * @see java.lang.reflect.Member
      * @since JDK1.1
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
+    @Deprecated
     @CallerSensitive
     public void checkMemberAccess(Class<?> clazz, int which) {
         if (clazz == null) {
--- a/jdk/src/share/classes/java/lang/instrument/Instrumentation.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/lang/instrument/Instrumentation.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -363,6 +363,8 @@
      * Primitive classes (for example, <code>java.lang.Integer.TYPE</code>)
      * and array classes are never modifiable.
      *
+     * @param theClass the class to check for being modifiable
+     * @return whether or not the argument class is modifiable
      * @throws java.lang.NullPointerException if the specified class is <code>null</code>.
      *
      * @see #retransformClasses
@@ -549,14 +551,14 @@
      * {@link java.lang.instrument.ClassFileTransformer ClassFileTransformer},
      * it enables native methods to be
      * instrumented.
-     * <p/>
+     * <p>
      * Since native methods cannot be directly instrumented
      * (they have no bytecodes), they must be wrapped with
      * a non-native method which can be instrumented.
      * For example, if we had:
      * <pre>
      *   native boolean foo(int x);</pre>
-     * <p/>
+     * <p>
      * We could transform the class file (with the
      * ClassFileTransformer during the initial definition
      * of the class) so that this becomes:
@@ -567,14 +569,14 @@
      *   }
      *
      *   native boolean wrapped_foo(int x);</pre>
-     * <p/>
+     * <p>
      * Where <code>foo</code> becomes a wrapper for the actual native
      * method with the appended prefix "wrapped_".  Note that
      * "wrapped_" would be a poor choice of prefix since it
      * might conceivably form the name of an existing method
      * thus something like "$$$MyAgentWrapped$$$_" would be
      * better but would make these examples less readable.
-     * <p/>
+     * <p>
      * The wrapper will allow data to be collected on the native
      * method call, but now the problem becomes linking up the
      * wrapped method with the native implementation.
@@ -583,7 +585,7 @@
      * which might be:
      * <pre>
      *   Java_somePackage_someClass_foo(JNIEnv* env, jint x)</pre>
-     * <p/>
+     * <p>
      * This function allows the prefix to be specified and the
      * proper resolution to occur.
      * Specifically, when the standard resolution fails, the
@@ -596,29 +598,29 @@
      * <pre>{@code
      *   method(foo) -> nativeImplementation(foo)
      * }</pre>
-     * <p/>
+     * <p>
      * When this fails, the resolution will be retried with
      * the specified prefix prepended to the method name,
      * yielding the correct resolution:
      * <pre>{@code
      *   method(wrapped_foo) -> nativeImplementation(foo)
      * }</pre>
-     * <p/>
+     * <p>
      * For automatic resolution, the JVM will attempt:
      * <pre>{@code
      *   method(wrapped_foo) -> nativeImplementation(wrapped_foo)
      * }</pre>
-     * <p/>
+     * <p>
      * When this fails, the resolution will be retried with
      * the specified prefix deleted from the implementation name,
      * yielding the correct resolution:
      * <pre>{@code
      *   method(wrapped_foo) -> nativeImplementation(foo)
      * }</pre>
-     * <p/>
+     * <p>
      * Note that since the prefix is only used when standard
      * resolution fails, native methods can be wrapped selectively.
-     * <p/>
+     * <p>
      * Since each <code>ClassFileTransformer</code>
      * can do its own transformation of the bytecodes, more
      * than one layer of wrappers may be applied. Thus each
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Jul 03 14:35:10 2013 -0700
@@ -747,7 +747,8 @@
             GuardWithCatch gguard = new GuardWithCatch(gtarget, exType, gcatcher);
             if (gtarget == null || gcatcher == null)  throw new InternalError();
             MethodHandle ginvoker = GuardWithCatch.VARARGS_INVOKE.bindReceiver(gguard);
-            return makeCollectArguments(ginvoker, ValueConversions.varargsArray(nargs), 0, false);
+            MethodHandle gcollect = makeCollectArguments(ginvoker, ValueConversions.varargsArray(nargs), 0, false);
+            return makePairwiseConvert(gcollect, type, 2);
         }
     }
 
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java	Wed Jul 03 14:35:10 2013 -0700
@@ -41,6 +41,7 @@
 import sun.security.util.SecurityConstants;
 import static java.lang.invoke.MethodHandleStatics.*;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import sun.security.util.SecurityConstants;
 
 /**
  * This class consists exclusively of static methods that operate on or return
@@ -305,36 +306,30 @@
      * <a name="secmgr"></a>
      * If a security manager is present, member lookups are subject to
      * additional checks.
-     * From one to four calls are made to the security manager.
+     * From one to three calls are made to the security manager.
      * Any of these calls can refuse access by throwing a
      * {@link java.lang.SecurityException SecurityException}.
      * Define {@code smgr} as the security manager,
+     * {@code lookc} as the lookup class of the current lookup object,
      * {@code refc} as the containing class in which the member
      * is being sought, and {@code defc} as the class in which the
      * member is actually defined.
+     * The value {@code lookc} is defined as <em>not present</em>
+     * if the current lookup object does not have
+     * {@linkplain java.lang.invoke.MethodHandles.Lookup#PRIVATE private access}.
      * The calls are made according to the following rules:
      * <ul>
-     * <li>In all cases, {@link SecurityManager#checkMemberAccess
-     *     smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
-     * <li>If the class loader of the lookup class is not
+     * <li>If {@code lookc} is not present, or if its class loader is not
      *     the same as or an ancestor of the class loader of {@code refc},
      *     then {@link SecurityManager#checkPackageAccess
      *     smgr.checkPackageAccess(refcPkg)} is called,
      *     where {@code refcPkg} is the package of {@code refc}.
+     * <li>If the retrieved member is not public and
+     *     {@code lookc} is not present, then
+     *     {@link SecurityManager#checkPermission smgr.checkPermission}
+     *     with {@code RuntimePermission("accessDeclaredMembers")} is called.
      * <li>If the retrieved member is not public,
-     *     {@link SecurityManager#checkMemberAccess
-     *     smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
-     *     (Note that {@code defc} might be the same as {@code refc}.)
-     *     The default implementation of this security manager method
-     *     inspects the stack to determine the original caller of
-     *     the reflective request (such as {@code findStatic}),
-     *     and performs additional permission checks if the
-     *     class loader of {@code defc} differs from the class
-     *     loader of the class from which the reflective request came.
-     * <li>If the retrieved member is not public,
-     *     and if {@code defc} and {@code refc} are in different class loaders,
-     *     and if the class loader of the lookup class is not
-     *     the same as or an ancestor of the class loader of {@code defc},
+     *     and if {@code defc} and {@code refc} are different,
      *     then {@link SecurityManager#checkPackageAccess
      *     smgr.checkPackageAccess(defcPkg)} is called,
      *     where {@code defcPkg} is the package of {@code defc}.
@@ -1054,22 +1049,6 @@
         }
 
         /**
-         * Determine whether a security manager has an overridden
-         * SecurityManager.checkMemberAccess method.
-         */
-        private boolean isCheckMemberAccessOverridden(SecurityManager sm) {
-            final Class<? extends SecurityManager> cls = sm.getClass();
-            if (cls == SecurityManager.class) return false;
-
-            try {
-                return cls.getMethod("checkMemberAccess", Class.class, int.class).
-                    getDeclaringClass() != SecurityManager.class;
-            } catch (NoSuchMethodException e) {
-                throw new InternalError("should not reach here");
-            }
-        }
-
-        /**
          * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
          * Determines a trustable caller class to compare with refc, the symbolic reference class.
          * If this lookup object has private access, then the caller class is the lookupClass.
@@ -1079,45 +1058,22 @@
             if (smgr == null)  return;
             if (allowedModes == TRUSTED)  return;
 
-            final boolean overridden = isCheckMemberAccessOverridden(smgr);
             // Step 1:
-            {
-                // Default policy is to allow Member.PUBLIC; no need to check
-                // permission if SecurityManager is the default implementation
-                final int which = Member.PUBLIC;
-                final Class<?> clazz = refc;
-                if (overridden) {
-                    // Don't refactor; otherwise break the stack depth for
-                    // checkMemberAccess of subclasses of SecurityManager as specified.
-                    smgr.checkMemberAccess(clazz, which);
-                }
-            }
-
-            // Step 2:
             if (!isFullPowerLookup() ||
                 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
                 ReflectUtil.checkPackageAccess(refc);
             }
 
-            // Step 3:
+            // Step 2:
             if (m.isPublic()) return;
             Class<?> defc = m.getDeclaringClass();
             {
-                // Inline SecurityManager.checkMemberAccess
-                final int which = Member.DECLARED;
-                final Class<?> clazz = defc;
-                if (!overridden) {
-                    if (!isFullPowerLookup()) {
-                        smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
-                    }
-                } else {
-                    // Don't refactor; otherwise break the stack depth for
-                    // checkMemberAccess of subclasses of SecurityManager as specified.
-                    smgr.checkMemberAccess(clazz, which);
+                if (!isFullPowerLookup()) {
+                    smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
                 }
             }
 
-            // Step 4:
+            // Step 3:
             if (defc != refc) {
                 ReflectUtil.checkPackageAccess(defc);
             }
--- a/jdk/src/share/classes/java/lang/reflect/Member.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Member.java	Wed Jul 03 14:35:10 2013 -0700
@@ -42,14 +42,12 @@
     /**
      * Identifies the set of all public members of a class or interface,
      * including inherited members.
-     * @see java.lang.SecurityManager#checkMemberAccess
      */
     public static final int PUBLIC = 0;
 
     /**
      * Identifies the set of declared members of a class or interface.
      * Inherited members are not included.
-     * @see java.lang.SecurityManager#checkMemberAccess
      */
     public static final int DECLARED = 1;
 
--- a/jdk/src/share/classes/java/math/BigInteger.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/math/BigInteger.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1042,7 +1042,7 @@
      * recalculate powers of radix^(2^n) more than once.  This speeds
      * Schoenhage recursive base conversion significantly.
      */
-    private static ArrayList<BigInteger>[] powerCache;
+    private static volatile BigInteger[][] powerCache;
 
     /** The cache of logarithms of radices for base conversion. */
     private static final double[] logCache;
@@ -1063,14 +1063,12 @@
          * with just the very first value.  Additional values will be created
          * on demand.
          */
-        powerCache = (ArrayList<BigInteger>[])
-            new ArrayList[Character.MAX_RADIX+1];
+        powerCache = new BigInteger[Character.MAX_RADIX+1][];
         logCache = new double[Character.MAX_RADIX+1];
 
         for (int i=Character.MIN_RADIX; i<=Character.MAX_RADIX; i++)
         {
-            powerCache[i] = new ArrayList<BigInteger>(1);
-            powerCache[i].add(BigInteger.valueOf(i));
+            powerCache[i] = new BigInteger[] { BigInteger.valueOf(i) };
             logCache[i] = Math.log(i);
         }
     }
@@ -3454,22 +3452,25 @@
      * This could be changed to a more complicated caching method using
      * <code>Future</code>.
      */
-    private static synchronized BigInteger getRadixConversionCache(int radix,
-                                                                   int exponent) {
-        BigInteger retVal = null;
-        ArrayList<BigInteger> cacheLine = powerCache[radix];
-        int oldSize = cacheLine.size();
-        if (exponent >= oldSize) {
-            cacheLine.ensureCapacity(exponent+1);
-            for (int i=oldSize; i<=exponent; i++) {
-                retVal = cacheLine.get(i-1).square();
-                cacheLine.add(i, retVal);
-            }
+    private static BigInteger getRadixConversionCache(int radix, int exponent) {
+        BigInteger[] cacheLine = powerCache[radix]; // volatile read
+        if (exponent < cacheLine.length) {
+            return cacheLine[exponent];
         }
-        else
-            retVal = cacheLine.get(exponent);
-
-        return retVal;
+
+        int oldLength = cacheLine.length;
+        cacheLine = Arrays.copyOf(cacheLine, exponent + 1);
+        for (int i = oldLength; i <= exponent; i++) {
+            cacheLine[i] = cacheLine[i - 1].pow(2);
+        }
+
+        BigInteger[][] pc = powerCache; // volatile read again
+        if (exponent >= pc[radix].length) {
+            pc = pc.clone();
+            pc[radix] = cacheLine;
+            powerCache = pc; // volatile write, publish
+        }
+        return cacheLine[exponent];
     }
 
     /* zero[i] is a string of i consecutive zeros. */
--- a/jdk/src/share/classes/java/security/KeyStore.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/security/KeyStore.java	Wed Jul 03 14:35:10 2013 -0700
@@ -227,15 +227,13 @@
      * {@link #store(KeyStore.LoadStoreParameter) store} operations.
      * <p>
      * The following syntax is supported for configuration data:
-     * <pre>
-     *
+     * <pre>{@code
      *     domain <domainName> [<property> ...] {
      *         keystore <keystoreName> [<property> ...] ;
      *         ...
      *     };
      *     ...
-     *
-     * </pre>
+     * }</pre>
      * where {@code domainName} and {@code keystoreName} are identifiers
      * and {@code property} is a key/value pairing. The key and value are
      * separated by an 'equals' symbol and the value is enclosed in double
--- a/jdk/src/share/classes/java/security/Provider.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/security/Provider.java	Wed Jul 03 14:35:10 2013 -0700
@@ -67,6 +67,7 @@
  * or modified by applications.
  * The following attributes are automatically placed in each Provider object:
  * <table cellspacing=4>
+ * <caption><b>Attributes Automatically Placed in a Provider Object</b></caption>
  * <tr><th>Name</th><th>Value</th>
  * <tr><td>{@code Provider.id name}</td>
   *    <td>{@code String.valueOf(provider.getName())}</td>
--- a/jdk/src/share/classes/java/security/Security.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/security/Security.java	Wed Jul 03 14:35:10 2013 -0700
@@ -480,8 +480,8 @@
      * Returns an array containing all installed providers that satisfy the
      * specified selection criterion, or null if no such providers have been
      * installed. The returned providers are ordered
-     * according to their <a href=
-     * "#insertProviderAt(java.security.Provider, int)">preference order</a>.
+     * according to their
+     * {@linkplain #insertProviderAt(java.security.Provider, int) preference order}.
      *
      * <p> A cryptographic service is always associated with a particular
      * algorithm or type. For example, a digital signature service is
@@ -492,8 +492,8 @@
      * <p>The selection criterion must be specified in one of the following two
      * formats:
      * <ul>
-     * <li> <i>&lt;crypto_service>.&lt;algorithm_or_type></i> <p> The
-     * cryptographic service name must not contain any dots.
+     * <li> <i>{@literal <crypto_service>.<algorithm_or_type>}</i>
+     * <p> The cryptographic service name must not contain any dots.
      * <p> A
      * provider satisfies the specified selection criterion iff the provider
      * implements the
@@ -501,11 +501,12 @@
      * <p> For example, "CertificateFactory.X.509"
      * would be satisfied by any provider that supplied
      * a CertificateFactory implementation for X.509 certificates.
-     * <li> <i>&lt;crypto_service>.&lt;algorithm_or_type>
-     * &lt;attribute_name>:&lt attribute_value></i>
+     * <li> <i>{@literal <crypto_service>.<algorithm_or_type>
+     * <attribute_name>:<attribute_value>}</i>
      * <p> The cryptographic service name must not contain any dots. There
      * must be one or more space charaters between the
-     * <i>&lt;algorithm_or_type></i> and the <i>&lt;attribute_name></i>.
+     * <i>{@literal <algorithm_or_type>}</i> and the
+     * <i>{@literal <attribute_name>}</i>.
      *  <p> A provider satisfies this selection criterion iff the
      * provider implements the specified algorithm or type for the specified
      * cryptographic service and its implementation meets the
@@ -558,8 +559,9 @@
      * Returns an array containing all installed providers that satisfy the
      * specified* selection criteria, or null if no such providers have been
      * installed. The returned providers are ordered
-     * according to their <a href=
-     * "#insertProviderAt(java.security.Provider, int)">preference order</a>.
+     * according to their
+     * {@linkplain #insertProviderAt(java.security.Provider, int)
+     * preference order}.
      *
      * <p>The selection criteria are represented by a map.
      * Each map entry represents a selection criterion.
@@ -567,16 +569,18 @@
      * criteria. The key for any entry in such a map must be in one of the
      * following two formats:
      * <ul>
-     * <li> <i>&lt;crypto_service>.&lt;algorithm_or_type></i>
+     * <li> <i>{@literal <crypto_service>.<algorithm_or_type>}</i>
      * <p> The cryptographic service name must not contain any dots.
      * <p> The value associated with the key must be an empty string.
      * <p> A provider
      * satisfies this selection criterion iff the provider implements the
      * specified algorithm or type for the specified cryptographic service.
-     * <li>  <i>&lt;crypto_service>.&lt;algorithm_or_type> &lt;attribute_name></i>
+     * <li>  <i>{@literal <crypto_service>}.
+     * {@literal <algorithm_or_type> <attribute_name>}</i>
      * <p> The cryptographic service name must not contain any dots. There
-     * must be one or more space charaters between the <i>&lt;algorithm_or_type></i>
-     * and the <i>&lt;attribute_name></i>.
+     * must be one or more space charaters between the
+     * <i>{@literal <algorithm_or_type>}</i>
+     * and the <i>{@literal <attribute_name>}</i>.
      * <p> The value associated with the key must be a non-empty string.
      * A provider satisfies this selection criterion iff the
      * provider implements the specified algorithm or type for the specified
--- a/jdk/src/share/classes/java/security/cert/X509CRL.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/security/cert/X509CRL.java	Wed Jul 03 14:35:10 2013 -0700
@@ -249,7 +249,8 @@
      * The ASN.1 definition for this is:
      * <pre>
      * version    Version OPTIONAL,
-     *             -- if present, must be v2<p>
+     *             -- if present, must be v2
+     *
      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
      *             -- v3 does not apply to CRLs but appears for consistency
      *             -- with definition of Version for certs
@@ -413,7 +414,8 @@
      * signature algorithm. An example is the string "SHA256withRSA".
      * The ASN.1 definition for this is:
      * <pre>
-     * signatureAlgorithm   AlgorithmIdentifier<p>
+     * signatureAlgorithm   AlgorithmIdentifier
+     *
      * AlgorithmIdentifier  ::=  SEQUENCE  {
      *     algorithm               OBJECT IDENTIFIER,
      *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
--- a/jdk/src/share/classes/java/security/cert/X509CRLEntry.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/security/cert/X509CRLEntry.java	Wed Jul 03 14:35:10 2013 -0700
@@ -43,11 +43,11 @@
  *     crlEntryExtensions Extensions OPTIONAL
  *                        -- if present, must be v2
  * }  OPTIONAL
- *<p>
+ *
  * CertificateSerialNumber  ::=  INTEGER
- *<p>
+ *
  * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
- *<p>
+ *
  * Extension  ::=  SEQUENCE  {
  *     extnId        OBJECT IDENTIFIER,
  *     critical      BOOLEAN DEFAULT FALSE,
--- a/jdk/src/share/classes/java/security/cert/X509Certificate.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/security/cert/X509Certificate.java	Wed Jul 03 14:35:10 2013 -0700
@@ -126,10 +126,12 @@
      * is valid. It is defined in
      * ASN.1 as:
      * <pre>
-     * validity             Validity<p>
+     * validity             Validity
+     *
      * Validity ::= SEQUENCE {
      *     notBefore      CertificateValidityDate,
-     *     notAfter       CertificateValidityDate }<p>
+     *     notAfter       CertificateValidityDate }
+     *
      * CertificateValidityDate ::= CHOICE {
      *     utcTime        UTCTime,
      *     generalTime    GeneralizedTime }
@@ -165,7 +167,8 @@
      * certificate.
      * The ASN.1 definition for this is:
      * <pre>
-     * version  [0] EXPLICIT Version DEFAULT v1<p>
+     * version  [0] EXPLICIT Version DEFAULT v1
+     *
      * Version ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
      * </pre>
      * @return the version number, i.e. 1, 2 or 3.
@@ -180,7 +183,7 @@
      * serial number identify a unique certificate).
      * The ASN.1 definition for this is:
      * <pre>
-     * serialNumber     CertificateSerialNumber<p>
+     * serialNumber     CertificateSerialNumber
      *
      * CertificateSerialNumber  ::=  INTEGER
      * </pre>
@@ -204,7 +207,7 @@
      * X.500 distinguished name (DN).
      * The ASN.1 definition for this is:
      * <pre>
-     * issuer    Name<p>
+     * issuer    Name
      *
      * Name ::= CHOICE { RDNSequence }
      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
@@ -295,11 +298,12 @@
      * the certificate.
      * The relevant ASN.1 definitions are:
      * <pre>
-     * validity             Validity<p>
+     * validity             Validity
      *
      * Validity ::= SEQUENCE {
      *     notBefore      CertificateValidityDate,
-     *     notAfter       CertificateValidityDate }<p>
+     *     notAfter       CertificateValidityDate }
+     *
      * CertificateValidityDate ::= CHOICE {
      *     utcTime        UTCTime,
      *     generalTime    GeneralizedTime }
@@ -348,7 +352,8 @@
      * signature algorithm. An example is the string "SHA256withRSA".
      * The ASN.1 definition for this is:
      * <pre>
-     * signatureAlgorithm   AlgorithmIdentifier<p>
+     * signatureAlgorithm   AlgorithmIdentifier
+     *
      * AlgorithmIdentifier  ::=  SEQUENCE  {
      *     algorithm               OBJECT IDENTIFIER,
      *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
@@ -410,7 +415,8 @@
      *
      * <p>The ASN.1 definition for this is:
      * <pre>
-     * issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL<p>
+     * issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL
+     *
      * UniqueIdentifier  ::=  BIT STRING
      * </pre>
      *
@@ -424,7 +430,8 @@
      *
      * <p>The ASN.1 definition for this is:
      * <pre>
-     * subjectUniqueID  [2]  IMPLICIT UniqueIdentifier OPTIONAL<p>
+     * subjectUniqueID  [2]  IMPLICIT UniqueIdentifier OPTIONAL
+     *
      * UniqueIdentifier  ::=  BIT STRING
      * </pre>
      *
@@ -474,9 +481,9 @@
      * indicated in the key usage extension field.  The ASN.1
      * definition for this is:
      * <pre>
-     * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId<p>
+     * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
      *
-     * KeyPurposeId ::= OBJECT IDENTIFIER<p>
+     * KeyPurposeId ::= OBJECT IDENTIFIER
      * </pre>
      *
      * Key purposes may be defined by any organization with a
--- a/jdk/src/share/classes/java/time/format/DateTimeFormatter.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/time/format/DateTimeFormatter.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1304,6 +1304,7 @@
      *  LocalTime time = parsed.query(LocalTime::from);
      *  Period extraDays = parsed.query(DateTimeFormatter.parsedExcessDays());
      * </pre>
+     * @return a query that provides access to the excess days that were parsed
      */
     public static final TemporalQuery<Period> parsedExcessDays() {
         return PARSED_EXCESS_DAYS;
@@ -1344,6 +1345,7 @@
      *    // validate leap-second is correct and apply correct smoothing
      *  }
      * </pre>
+     * @return a query that provides access to whether a leap-second was parsed
      */
     public static final TemporalQuery<Boolean> parsedLeapSecond() {
         return PARSED_LEAP_SECOND;
--- a/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Wed Jul 03 14:35:10 2013 -0700
@@ -34,8 +34,15 @@
  */
 
 package java.util.concurrent;
-import java.util.concurrent.locks.*;
-import java.util.*;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.AbstractQueue;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.lang.ref.WeakReference;
+import java.util.Spliterators;
+import java.util.Spliterator;
 
 /**
  * A bounded {@linkplain BlockingQueue blocking queue} backed by an
@@ -102,19 +109,21 @@
 
     /** Main lock guarding all access */
     final ReentrantLock lock;
+
     /** Condition for waiting takes */
     private final Condition notEmpty;
+
     /** Condition for waiting puts */
     private final Condition notFull;
 
-    // Internal helper methods
+    /**
+     * Shared state for currently active iterators, or null if there
+     * are known not to be any.  Allows queue operations to update
+     * iterator state.
+     */
+    transient Itrs itrs = null;
 
-    /**
-     * Circularly increment i.
-     */
-    final int inc(int i) {
-        return (++i == items.length) ? 0 : i;
-    }
+    // Internal helper methods
 
     /**
      * Circularly decrement i.
@@ -123,11 +132,6 @@
         return ((i == 0) ? items.length : i) - 1;
     }
 
-    @SuppressWarnings("unchecked")
-    static <E> E cast(Object item) {
-        return (E) item;
-    }
-
     /**
      * Returns item at index i.
      */
@@ -150,10 +154,14 @@
      * Inserts element at current put position, advances, and signals.
      * Call only when holding lock.
      */
-    private void insert(E x) {
+    private void enqueue(E x) {
+        // assert lock.getHoldCount() == 1;
+        // assert items[putIndex] == null;
+        final Object[] items = this.items;
         items[putIndex] = x;
-        putIndex = inc(putIndex);
-        ++count;
+        if (++putIndex == items.length)
+            putIndex = 0;
+        count++;
         notEmpty.signal();
     }
 
@@ -161,43 +169,62 @@
      * Extracts element at current take position, advances, and signals.
      * Call only when holding lock.
      */
-    private E extract() {
+    private E dequeue() {
+        // assert lock.getHoldCount() == 1;
+        // assert items[takeIndex] != null;
         final Object[] items = this.items;
         @SuppressWarnings("unchecked")
         E x = (E) items[takeIndex];
         items[takeIndex] = null;
-        takeIndex = inc(takeIndex);
-        --count;
+        if (++takeIndex == items.length)
+            takeIndex = 0;
+        count--;
+        if (itrs != null)
+            itrs.elementDequeued();
         notFull.signal();
         return x;
     }
 
     /**
-     * Deletes item at position i.
-     * Utility for remove and iterator.remove.
+     * Deletes item at array index removeIndex.
+     * Utility for remove(Object) and iterator.remove.
      * Call only when holding lock.
      */
-    void removeAt(int i) {
+    void removeAt(final int removeIndex) {
+        // assert lock.getHoldCount() == 1;
+        // assert items[removeIndex] != null;
+        // assert removeIndex >= 0 && removeIndex < items.length;
         final Object[] items = this.items;
-        // if removing front item, just advance
-        if (i == takeIndex) {
+        if (removeIndex == takeIndex) {
+            // removing front item; just advance
             items[takeIndex] = null;
-            takeIndex = inc(takeIndex);
+            if (++takeIndex == items.length)
+                takeIndex = 0;
+            count--;
+            if (itrs != null)
+                itrs.elementDequeued();
         } else {
+            // an "interior" remove
+
             // slide over all others up through putIndex.
-            for (;;) {
-                int nexti = inc(i);
-                if (nexti != putIndex) {
-                    items[i] = items[nexti];
-                    i = nexti;
+            final int putIndex = this.putIndex;
+            for (int i = removeIndex;;) {
+                int next = i + 1;
+                if (next == items.length)
+                    next = 0;
+                if (next != putIndex) {
+                    items[i] = items[next];
+                    i = next;
                 } else {
                     items[i] = null;
-                    putIndex = i;
+                    this.putIndex = i;
                     break;
                 }
             }
+            count--;
+            if (itrs != null)
+                itrs.removedAt(removeIndex);
         }
-        --count;
         notFull.signal();
     }
 
@@ -302,7 +329,7 @@
             if (count == items.length)
                 return false;
             else {
-                insert(e);
+                enqueue(e);
                 return true;
             }
         } finally {
@@ -324,7 +351,7 @@
         try {
             while (count == items.length)
                 notFull.await();
-            insert(e);
+            enqueue(e);
         } finally {
             lock.unlock();
         }
@@ -351,7 +378,7 @@
                     return false;
                 nanos = notFull.awaitNanos(nanos);
             }
-            insert(e);
+            enqueue(e);
             return true;
         } finally {
             lock.unlock();
@@ -362,7 +389,7 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            return (count == 0) ? null : extract();
+            return (count == 0) ? null : dequeue();
         } finally {
             lock.unlock();
         }
@@ -374,7 +401,7 @@
         try {
             while (count == 0)
                 notEmpty.await();
-            return extract();
+            return dequeue();
         } finally {
             lock.unlock();
         }
@@ -390,7 +417,7 @@
                     return null;
                 nanos = notEmpty.awaitNanos(nanos);
             }
-            return extract();
+            return dequeue();
         } finally {
             lock.unlock();
         }
@@ -400,7 +427,7 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            return (count == 0) ? null : itemAt(takeIndex);
+            return itemAt(takeIndex); // null when queue is empty
         } finally {
             lock.unlock();
         }
@@ -469,11 +496,17 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) {
-                if (o.equals(items[i])) {
-                    removeAt(i);
-                    return true;
-                }
+            if (count > 0) {
+                final int putIndex = this.putIndex;
+                int i = takeIndex;
+                do {
+                    if (o.equals(items[i])) {
+                        removeAt(i);
+                        return true;
+                    }
+                    if (++i == items.length)
+                        i = 0;
+                } while (i != putIndex);
             }
             return false;
         } finally {
@@ -495,9 +528,16 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            for (int i = takeIndex, k = count; k > 0; i = inc(i), k--)
-                if (o.equals(items[i]))
-                    return true;
+            if (count > 0) {
+                final int putIndex = this.putIndex;
+                int i = takeIndex;
+                do {
+                    if (o.equals(items[i]))
+                        return true;
+                    if (++i == items.length)
+                        i = 0;
+                } while (i != putIndex);
+            }
             return false;
         } finally {
             lock.unlock();
@@ -518,18 +558,23 @@
      * @return an array containing all of the elements in this queue
      */
     public Object[] toArray() {
-        final Object[] items = this.items;
+        Object[] a;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
             final int count = this.count;
-            Object[] a = new Object[count];
-            for (int i = takeIndex, k = 0; k < count; i = inc(i), k++)
-                a[k] = items[i];
-            return a;
+            a = new Object[count];
+            int n = items.length - takeIndex;
+            if (count <= n)
+                System.arraycopy(items, takeIndex, a, 0, count);
+            else {
+                System.arraycopy(items, takeIndex, a, 0, n);
+                System.arraycopy(items, 0, a, n, count - n);
+            }
         } finally {
             lock.unlock();
         }
+        return a;
     }
 
     /**
@@ -553,8 +598,7 @@
      * The following code can be used to dump the queue into a newly
      * allocated array of {@code String}:
      *
-     * <pre>
-     *     String[] y = x.toArray(new String[0]);</pre>
+     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -579,14 +623,19 @@
             if (len < count)
                 a = (T[])java.lang.reflect.Array.newInstance(
                     a.getClass().getComponentType(), count);
-            for (int i = takeIndex, k = 0; k < count; i = inc(i), k++)
-                a[k] = (T) items[i];
+            int n = items.length - takeIndex;
+            if (count <= n)
+                System.arraycopy(items, takeIndex, a, 0, count);
+            else {
+                System.arraycopy(items, takeIndex, a, 0, n);
+                System.arraycopy(items, 0, a, n, count - n);
+            }
             if (len > count)
                 a[count] = null;
-            return a;
         } finally {
             lock.unlock();
         }
+        return a;
     }
 
     public String toString() {
@@ -597,14 +646,17 @@
             if (k == 0)
                 return "[]";
 
+            final Object[] items = this.items;
             StringBuilder sb = new StringBuilder();
             sb.append('[');
-            for (int i = takeIndex; ; i = inc(i)) {
+            for (int i = takeIndex; ; ) {
                 Object e = items[i];
                 sb.append(e == this ? "(this Collection)" : e);
                 if (--k == 0)
                     return sb.append(']').toString();
                 sb.append(',').append(' ');
+                if (++i == items.length)
+                    i = 0;
             }
         } finally {
             lock.unlock();
@@ -620,12 +672,22 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            for (int i = takeIndex, k = count; k > 0; i = inc(i), k--)
-                items[i] = null;
-            count = 0;
-            putIndex = 0;
-            takeIndex = 0;
-            notFull.signalAll();
+            int k = count;
+            if (k > 0) {
+                final int putIndex = this.putIndex;
+                int i = takeIndex;
+                do {
+                    items[i] = null;
+                    if (++i == items.length)
+                        i = 0;
+                } while (i != putIndex);
+                takeIndex = putIndex;
+                count = 0;
+                if (itrs != null)
+                    itrs.queueIsEmpty();
+                for (; k > 0 && lock.hasWaiters(notFull); k--)
+                    notFull.signal();
+            }
         } finally {
             lock.unlock();
         }
@@ -638,34 +700,7 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c) {
-        checkNotNull(c);
-        if (c == this)
-            throw new IllegalArgumentException();
-        final Object[] items = this.items;
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            int i = takeIndex;
-            int n = 0;
-            int max = count;
-            while (n < max) {
-                @SuppressWarnings("unchecked")
-                E x = (E) items[i];
-                c.add(x);
-                items[i] = null;
-                i = inc(i);
-                ++n;
-            }
-            if (n > 0) {
-                count = 0;
-                putIndex = 0;
-                takeIndex = 0;
-                notFull.signalAll();
-            }
-            return n;
-        } finally {
-            lock.unlock();
-        }
+        return drainTo(c, Integer.MAX_VALUE);
     }
 
     /**
@@ -684,23 +719,35 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            int i = takeIndex;
-            int n = 0;
-            int max = (maxElements < count) ? maxElements : count;
-            while (n < max) {
-                @SuppressWarnings("unchecked")
-                E x = (E) items[i];
-                c.add(x);
-                items[i] = null;
-                i = inc(i);
-                ++n;
+            int n = Math.min(maxElements, count);
+            int take = takeIndex;
+            int i = 0;
+            try {
+                while (i < n) {
+                    @SuppressWarnings("unchecked")
+                    E x = (E) items[take];
+                    c.add(x);
+                    items[take] = null;
+                    if (++take == items.length)
+                        take = 0;
+                    i++;
+                }
+                return n;
+            } finally {
+                // Restore invariants even if c.add() threw
+                if (i > 0) {
+                    count -= i;
+                    takeIndex = take;
+                    if (itrs != null) {
+                        if (count == 0)
+                            itrs.queueIsEmpty();
+                        else if (i > take)
+                            itrs.takeIndexWrapped();
+                    }
+                    for (; i > 0 && lock.hasWaiters(notFull); i--)
+                        notFull.signal();
+                }
             }
-            if (n > 0) {
-                count -= n;
-                takeIndex = i;
-                notFull.signalAll();
-            }
-            return n;
         } finally {
             lock.unlock();
         }
@@ -710,12 +757,12 @@
      * Returns an iterator over the elements in this queue in proper sequence.
      * The elements will be returned in order from first (head) to last (tail).
      *
-     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
+     * <p>The returned iterator is a "weakly consistent" iterator that
      * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * ConcurrentModificationException}, and guarantees to traverse
+     * elements as they existed upon construction of the iterator, and
+     * may (but is not guaranteed to) reflect any modifications
+     * subsequent to construction.
      *
      * @return an iterator over the elements in this queue in proper sequence
      */
@@ -724,88 +771,634 @@
     }
 
     /**
-     * Iterator for ArrayBlockingQueue. To maintain weak consistency
-     * with respect to puts and takes, we (1) read ahead one slot, so
-     * as to not report hasNext true but then not have an element to
-     * return -- however we later recheck this slot to use the most
-     * current value; (2) ensure that each array slot is traversed at
-     * most once (by tracking "remaining" elements); (3) skip over
-     * null slots, which can occur if takes race ahead of iterators.
-     * However, for circular array-based queues, we cannot rely on any
-     * well established definition of what it means to be weakly
-     * consistent with respect to interior removes since these may
-     * require slot overwrites in the process of sliding elements to
-     * cover gaps. So we settle for resiliency, operating on
-     * established apparent nexts, which may miss some elements that
-     * have moved between calls to next.
+     * Shared data between iterators and their queue, allowing queue
+     * modifications to update iterators when elements are removed.
+     *
+     * This adds a lot of complexity for the sake of correctly
+     * handling some uncommon operations, but the combination of
+     * circular-arrays and supporting interior removes (i.e., those
+     * not at head) would cause iterators to sometimes lose their
+     * places and/or (re)report elements they shouldn't.  To avoid
+     * this, when a queue has one or more iterators, it keeps iterator
+     * state consistent by:
+     *
+     * (1) keeping track of the number of "cycles", that is, the
+     *     number of times takeIndex has wrapped around to 0.
+     * (2) notifying all iterators via the callback removedAt whenever
+     *     an interior element is removed (and thus other elements may
+     *     be shifted).
+     *
+     * These suffice to eliminate iterator inconsistencies, but
+     * unfortunately add the secondary responsibility of maintaining
+     * the list of iterators.  We track all active iterators in a
+     * simple linked list (accessed only when the queue's lock is
+     * held) of weak references to Itr.  The list is cleaned up using
+     * 3 different mechanisms:
+     *
+     * (1) Whenever a new iterator is created, do some O(1) checking for
+     *     stale list elements.
+     *
+     * (2) Whenever takeIndex wraps around to 0, check for iterators
+     *     that have been unused for more than one wrap-around cycle.
+     *
+     * (3) Whenever the queue becomes empty, all iterators are notified
+     *     and this entire data structure is discarded.
+     *
+     * So in addition to the removedAt callback that is necessary for
+     * correctness, iterators have the shutdown and takeIndexWrapped
+     * callbacks that help remove stale iterators from the list.
+     *
+     * Whenever a list element is examined, it is expunged if either
+     * the GC has determined that the iterator is discarded, or if the
+     * iterator reports that it is "detached" (does not need any
+     * further state updates).  Overhead is maximal when takeIndex
+     * never advances, iterators are discarded before they are
+     * exhausted, and all removals are interior removes, in which case
+     * all stale iterators are discovered by the GC.  But even in this
+     * case we don't increase the amortized complexity.
+     *
+     * Care must be taken to keep list sweeping methods from
+     * reentrantly invoking another such method, causing subtle
+     * corruption bugs.
+     */
+    class Itrs {
+
+        /**
+         * Node in a linked list of weak iterator references.
+         */
+        private class Node extends WeakReference<Itr> {
+            Node next;
+
+            Node(Itr iterator, Node next) {
+                super(iterator);
+                this.next = next;
+            }
+        }
+
+        /** Incremented whenever takeIndex wraps around to 0 */
+        int cycles = 0;
+
+        /** Linked list of weak iterator references */
+        private Node head;
+
+        /** Used to expunge stale iterators */
+        private Node sweeper = null;
+
+        private static final int SHORT_SWEEP_PROBES = 4;
+        private static final int LONG_SWEEP_PROBES = 16;
+
+        Itrs(Itr initial) {
+            register(initial);
+        }
+
+        /**
+         * Sweeps itrs, looking for and expunging stale iterators.
+         * If at least one was found, tries harder to find more.
+         * Called only from iterating thread.
+         *
+         * @param tryHarder whether to start in try-harder mode, because
+         * there is known to be at least one iterator to collect
+         */
+        void doSomeSweeping(boolean tryHarder) {
+            // assert lock.getHoldCount() == 1;
+            // assert head != null;
+            int probes = tryHarder ? LONG_SWEEP_PROBES : SHORT_SWEEP_PROBES;
+            Node o, p;
+            final Node sweeper = this.sweeper;
+            boolean passedGo;   // to limit search to one full sweep
+
+            if (sweeper == null) {
+                o = null;
+                p = head;
+                passedGo = true;
+            } else {
+                o = sweeper;
+                p = o.next;
+                passedGo = false;
+            }
+
+            for (; probes > 0; probes--) {
+                if (p == null) {
+                    if (passedGo)
+                        break;
+                    o = null;
+                    p = head;
+                    passedGo = true;
+                }
+                final Itr it = p.get();
+                final Node next = p.next;
+                if (it == null || it.isDetached()) {
+                    // found a discarded/exhausted iterator
+                    probes = LONG_SWEEP_PROBES; // "try harder"
+                    // unlink p
+                    p.clear();
+                    p.next = null;
+                    if (o == null) {
+                        head = next;
+                        if (next == null) {
+                            // We've run out of iterators to track; retire
+                            itrs = null;
+                            return;
+                        }
+                    }
+                    else
+                        o.next = next;
+                } else {
+                    o = p;
+                }
+                p = next;
+            }
+
+            this.sweeper = (p == null) ? null : o;
+        }
+
+        /**
+         * Adds a new iterator to the linked list of tracked iterators.
+         */
+        void register(Itr itr) {
+            // assert lock.getHoldCount() == 1;
+            head = new Node(itr, head);
+        }
+
+        /**
+         * Called whenever takeIndex wraps around to 0.
+         *
+         * Notifies all iterators, and expunges any that are now stale.
+         */
+        void takeIndexWrapped() {
+            // assert lock.getHoldCount() == 1;
+            cycles++;
+            for (Node o = null, p = head; p != null;) {
+                final Itr it = p.get();
+                final Node next = p.next;
+                if (it == null || it.takeIndexWrapped()) {
+                    // unlink p
+                    // assert it == null || it.isDetached();
+                    p.clear();
+                    p.next = null;
+                    if (o == null)
+                        head = next;
+                    else
+                        o.next = next;
+                } else {
+                    o = p;
+                }
+                p = next;
+            }
+            if (head == null)   // no more iterators to track
+                itrs = null;
+        }
+
+        /**
+         * Called whenever an interior remove (not at takeIndex) occured.
+         *
+         * Notifies all iterators, and expunges any that are now stale.
+         */
+        void removedAt(int removedIndex) {
+            for (Node o = null, p = head; p != null;) {
+                final Itr it = p.get();
+                final Node next = p.next;
+                if (it == null || it.removedAt(removedIndex)) {
+                    // unlink p
+                    // assert it == null || it.isDetached();
+                    p.clear();
+                    p.next = null;
+                    if (o == null)
+                        head = next;
+                    else
+                        o.next = next;
+                } else {
+                    o = p;
+                }
+                p = next;
+            }
+            if (head == null)   // no more iterators to track
+                itrs = null;
+        }
+
+        /**
+         * Called whenever the queue becomes empty.
+         *
+         * Notifies all active iterators that the queue is empty,
+         * clears all weak refs, and unlinks the itrs datastructure.
+         */
+        void queueIsEmpty() {
+            // assert lock.getHoldCount() == 1;
+            for (Node p = head; p != null; p = p.next) {
+                Itr it = p.get();
+                if (it != null) {
+                    p.clear();
+                    it.shutdown();
+                }
+            }
+            head = null;
+            itrs = null;
+        }
+
+        /**
+         * Called whenever an element has been dequeued (at takeIndex).
+         */
+        void elementDequeued() {
+            // assert lock.getHoldCount() == 1;
+            if (count == 0)
+                queueIsEmpty();
+            else if (takeIndex == 0)
+                takeIndexWrapped();
+        }
+    }
+
+    /**
+     * Iterator for ArrayBlockingQueue.
+     *
+     * To maintain weak consistency with respect to puts and takes, we
+     * read ahead one slot, so as to not report hasNext true but then
+     * not have an element to return.
+     *
+     * We switch into "detached" mode (allowing prompt unlinking from
+     * itrs without help from the GC) when all indices are negative, or
+     * when hasNext returns false for the first time.  This allows the
+     * iterator to track concurrent updates completely accurately,
+     * except for the corner case of the user calling Iterator.remove()
+     * after hasNext() returned false.  Even in this case, we ensure
+     * that we don't remove the wrong element by keeping track of the
+     * expected element to remove, in lastItem.  Yes, we may fail to
+     * remove lastItem from the queue if it moved due to an interleaved
+     * interior remove while in detached mode.
      */
     private class Itr implements Iterator<E> {
-        private int remaining; // Number of elements yet to be returned
-        private int nextIndex; // Index of element to be returned by next
-        private E nextItem;    // Element to be returned by next call to next
-        private E lastItem;    // Element returned by last call to next
-        private int lastRet;   // Index of last element returned, or -1 if none
+        /** Index to look for new nextItem; NONE at end */
+        private int cursor;
+
+        /** Element to be returned by next call to next(); null if none */
+        private E nextItem;
+
+        /** Index of nextItem; NONE if none, REMOVED if removed elsewhere */
+        private int nextIndex;
+
+        /** Last element returned; null if none or not detached. */
+        private E lastItem;
+
+        /** Index of lastItem, NONE if none, REMOVED if removed elsewhere */
+        private int lastRet;
+
+        /** Previous value of takeIndex, or DETACHED when detached */
+        private int prevTakeIndex;
+
+        /** Previous value of iters.cycles */
+        private int prevCycles;
+
+        /** Special index value indicating "not available" or "undefined" */
+        private static final int NONE = -1;
+
+        /**
+         * Special index value indicating "removed elsewhere", that is,
+         * removed by some operation other than a call to this.remove().
+         */
+        private static final int REMOVED = -2;
+
+        /** Special value for prevTakeIndex indicating "detached mode" */
+        private static final int DETACHED = -3;
 
         Itr() {
+            // assert lock.getHoldCount() == 0;
+            lastRet = NONE;
             final ReentrantLock lock = ArrayBlockingQueue.this.lock;
             lock.lock();
             try {
-                lastRet = -1;
-                if ((remaining = count) > 0)
+                if (count == 0) {
+                    // assert itrs == null;
+                    cursor = NONE;
+                    nextIndex = NONE;
+                    prevTakeIndex = DETACHED;
+                } else {
+                    final int takeIndex = ArrayBlockingQueue.this.takeIndex;
+                    prevTakeIndex = takeIndex;
                     nextItem = itemAt(nextIndex = takeIndex);
+                    cursor = incCursor(takeIndex);
+                    if (itrs == null) {
+                        itrs = new Itrs(this);
+                    } else {
+                        itrs.register(this); // in this order
+                        itrs.doSomeSweeping(false);
+                    }
+                    prevCycles = itrs.cycles;
+                    // assert takeIndex >= 0;
+                    // assert prevTakeIndex == takeIndex;
+                    // assert nextIndex >= 0;
+                    // assert nextItem != null;
+                }
             } finally {
                 lock.unlock();
             }
         }
 
-        public boolean hasNext() {
-            return remaining > 0;
+        boolean isDetached() {
+            // assert lock.getHoldCount() == 1;
+            return prevTakeIndex < 0;
+        }
+
+        private int incCursor(int index) {
+            // assert lock.getHoldCount() == 1;
+            if (++index == items.length)
+                index = 0;
+            if (index == putIndex)
+                index = NONE;
+            return index;
+        }
+
+        /**
+         * Returns true if index is invalidated by the given number of
+         * dequeues, starting from prevTakeIndex.
+         */
+        private boolean invalidated(int index, int prevTakeIndex,
+                                    long dequeues, int length) {
+            if (index < 0)
+                return false;
+            int distance = index - prevTakeIndex;
+            if (distance < 0)
+                distance += length;
+            return dequeues > distance;
         }
 
-        public E next() {
+        /**
+         * Adjusts indices to incorporate all dequeues since the last
+         * operation on this iterator.  Call only from iterating thread.
+         */
+        private void incorporateDequeues() {
+            // assert lock.getHoldCount() == 1;
+            // assert itrs != null;
+            // assert !isDetached();
+            // assert count > 0;
+
+            final int cycles = itrs.cycles;
+            final int takeIndex = ArrayBlockingQueue.this.takeIndex;
+            final int prevCycles = this.prevCycles;
+            final int prevTakeIndex = this.prevTakeIndex;
+
+            if (cycles != prevCycles || takeIndex != prevTakeIndex) {
+                final int len = items.length;
+                // how far takeIndex has advanced since the previous
+                // operation of this iterator
+                long dequeues = (cycles - prevCycles) * len
+                    + (takeIndex - prevTakeIndex);
+
+                // Check indices for invalidation
+                if (invalidated(lastRet, prevTakeIndex, dequeues, len))
+                    lastRet = REMOVED;
+                if (invalidated(nextIndex, prevTakeIndex, dequeues, len))
+                    nextIndex = REMOVED;
+                if (invalidated(cursor, prevTakeIndex, dequeues, len))
+                    cursor = takeIndex;
+
+                if (cursor < 0 && nextIndex < 0 && lastRet < 0)
+                    detach();
+                else {
+                    this.prevCycles = cycles;
+                    this.prevTakeIndex = takeIndex;
+                }
+            }
+        }
+
+        /**
+         * Called when itrs should stop tracking this iterator, either
+         * because there are no more indices to update (cursor < 0 &&
+         * nextIndex < 0 && lastRet < 0) or as a special exception, when
+         * lastRet >= 0, because hasNext() is about to return false for the
+         * first time.  Call only from iterating thread.
+         */
+        private void detach() {
+            // Switch to detached mode
+            // assert lock.getHoldCount() == 1;
+            // assert cursor == NONE;
+            // assert nextIndex < 0;
+            // assert lastRet < 0 || nextItem == null;
+            // assert lastRet < 0 ^ lastItem != null;
+            if (prevTakeIndex >= 0) {
+                // assert itrs != null;
+                prevTakeIndex = DETACHED;
+                // try to unlink from itrs (but not too hard)
+                itrs.doSomeSweeping(true);
+            }
+        }
+
+        /**
+         * For performance reasons, we would like not to acquire a lock in
+         * hasNext in the common case.  To allow for this, we only access
+         * fields (i.e. nextItem) that are not modified by update operations
+         * triggered by queue modifications.
+         */
+        public boolean hasNext() {
+            // assert lock.getHoldCount() == 0;
+            if (nextItem != null)
+                return true;
+            noNext();
+            return false;
+        }
+
+        private void noNext() {
             final ReentrantLock lock = ArrayBlockingQueue.this.lock;
             lock.lock();
             try {
-                if (remaining <= 0)
-                    throw new NoSuchElementException();
-                lastRet = nextIndex;
-                E x = itemAt(nextIndex);  // check for fresher value
-                if (x == null) {
-                    x = nextItem;         // we are forced to report old value
-                    lastItem = null;      // but ensure remove fails
+                // assert cursor == NONE;
+                // assert nextIndex == NONE;
+                if (!isDetached()) {
+                    // assert lastRet >= 0;
+                    incorporateDequeues(); // might update lastRet
+                    if (lastRet >= 0) {
+                        lastItem = itemAt(lastRet);
+                        // assert lastItem != null;
+                        detach();
+                    }
                 }
-                else
-                    lastItem = x;
-                while (--remaining > 0 && // skip over nulls
-                       (nextItem = itemAt(nextIndex = inc(nextIndex))) == null)
-                    ;
-                return x;
+                // assert isDetached();
+                // assert lastRet < 0 ^ lastItem != null;
             } finally {
                 lock.unlock();
             }
         }
 
-        public void remove() {
+        public E next() {
+            // assert lock.getHoldCount() == 0;
+            final E x = nextItem;
+            if (x == null)
+                throw new NoSuchElementException();
             final ReentrantLock lock = ArrayBlockingQueue.this.lock;
             lock.lock();
             try {
-                int i = lastRet;
-                if (i == -1)
-                    throw new IllegalStateException();
-                lastRet = -1;
-                E x = lastItem;
-                lastItem = null;
-                // only remove if item still at index
-                if (x != null && x == items[i]) {
-                    boolean removingHead = (i == takeIndex);
-                    removeAt(i);
-                    if (!removingHead)
-                        nextIndex = dec(nextIndex);
+                if (!isDetached())
+                    incorporateDequeues();
+                // assert nextIndex != NONE;
+                // assert lastItem == null;
+                lastRet = nextIndex;
+                final int cursor = this.cursor;
+                if (cursor >= 0) {
+                    nextItem = itemAt(nextIndex = cursor);
+                    // assert nextItem != null;
+                    this.cursor = incCursor(cursor);
+                } else {
+                    nextIndex = NONE;
+                    nextItem = null;
                 }
             } finally {
                 lock.unlock();
             }
+            return x;
         }
+
+        public void remove() {
+            // assert lock.getHoldCount() == 0;
+            final ReentrantLock lock = ArrayBlockingQueue.this.lock;
+            lock.lock();
+            try {
+                if (!isDetached())
+                    incorporateDequeues(); // might update lastRet or detach
+                final int lastRet = this.lastRet;
+                this.lastRet = NONE;
+                if (lastRet >= 0) {
+                    if (!isDetached())
+                        removeAt(lastRet);
+                    else {
+                        final E lastItem = this.lastItem;
+                        // assert lastItem != null;
+                        this.lastItem = null;
+                        if (itemAt(lastRet) == lastItem)
+                            removeAt(lastRet);
+                    }
+                } else if (lastRet == NONE)
+                    throw new IllegalStateException();
+                // else lastRet == REMOVED and the last returned element was
+                // previously asynchronously removed via an operation other
+                // than this.remove(), so nothing to do.
+
+                if (cursor < 0 && nextIndex < 0)
+                    detach();
+            } finally {
+                lock.unlock();
+                // assert lastRet == NONE;
+                // assert lastItem == null;
+            }
+        }
+
+        /**
+         * Called to notify the iterator that the queue is empty, or that it
+         * has fallen hopelessly behind, so that it should abandon any
+         * further iteration, except possibly to return one more element
+         * from next(), as promised by returning true from hasNext().
+         */
+        void shutdown() {
+            // assert lock.getHoldCount() == 1;
+            cursor = NONE;
+            if (nextIndex >= 0)
+                nextIndex = REMOVED;
+            if (lastRet >= 0) {
+                lastRet = REMOVED;
+                lastItem = null;
+            }
+            prevTakeIndex = DETACHED;
+            // Don't set nextItem to null because we must continue to be
+            // able to return it on next().
+            //
+            // Caller will unlink from itrs when convenient.
+        }
+
+        private int distance(int index, int prevTakeIndex, int length) {
+            int distance = index - prevTakeIndex;
+            if (distance < 0)
+                distance += length;
+            return distance;
+        }
+
+        /**
+         * Called whenever an interior remove (not at takeIndex) occured.
+         *
+         * @return true if this iterator should be unlinked from itrs
+         */
+        boolean removedAt(int removedIndex) {
+            // assert lock.getHoldCount() == 1;
+            if (isDetached())
+                return true;
+
+            final int cycles = itrs.cycles;
+            final int takeIndex = ArrayBlockingQueue.this.takeIndex;
+            final int prevCycles = this.prevCycles;
+            final int prevTakeIndex = this.prevTakeIndex;
+            final int len = items.length;
+            int cycleDiff = cycles - prevCycles;
+            if (removedIndex < takeIndex)
+                cycleDiff++;
+            final int removedDistance =
+                (cycleDiff * len) + (removedIndex - prevTakeIndex);
+            // assert removedDistance >= 0;
+            int cursor = this.cursor;
+            if (cursor >= 0) {
+                int x = distance(cursor, prevTakeIndex, len);
+                if (x == removedDistance) {
+                    if (cursor == putIndex)
+                        this.cursor = cursor = NONE;
+                }
+                else if (x > removedDistance) {
+                    // assert cursor != prevTakeIndex;
+                    this.cursor = cursor = dec(cursor);
+                }
+            }
+            int lastRet = this.lastRet;
+            if (lastRet >= 0) {
+                int x = distance(lastRet, prevTakeIndex, len);
+                if (x == removedDistance)
+                    this.lastRet = lastRet = REMOVED;
+                else if (x > removedDistance)
+                    this.lastRet = lastRet = dec(lastRet);
+            }
+            int nextIndex = this.nextIndex;
+            if (nextIndex >= 0) {
+                int x = distance(nextIndex, prevTakeIndex, len);
+                if (x == removedDistance)
+                    this.nextIndex = nextIndex = REMOVED;
+                else if (x > removedDistance)
+                    this.nextIndex = nextIndex = dec(nextIndex);
+            }
+            else if (cursor < 0 && nextIndex < 0 && lastRet < 0) {
+                this.prevTakeIndex = DETACHED;
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Called whenever takeIndex wraps around to zero.
+         *
+         * @return true if this iterator should be unlinked from itrs
+         */
+        boolean takeIndexWrapped() {
+            // assert lock.getHoldCount() == 1;
+            if (isDetached())
+                return true;
+            if (itrs.cycles - prevCycles > 1) {
+                // All the elements that existed at the time of the last
+                // operation are gone, so abandon further iteration.
+                shutdown();
+                return true;
+            }
+            return false;
+        }
+
+//         /** Uncomment for debugging. */
+//         public String toString() {
+//             return ("cursor=" + cursor + " " +
+//                     "nextIndex=" + nextIndex + " " +
+//                     "lastRet=" + lastRet + " " +
+//                     "nextItem=" + nextItem + " " +
+//                     "lastItem=" + lastItem + " " +
+//                     "prevCycles=" + prevCycles + " " +
+//                     "prevTakeIndex=" + prevTakeIndex + " " +
+//                     "size()=" + size() + " " +
+//                     "remainingCapacity()=" + remainingCapacity());
+//         }
     }
 
+    public Spliterator<E> spliterator() {
+        return Spliterators.spliterator
+            (this, Spliterator.ORDERED | Spliterator.NONNULL |
+             Spliterator.CONCURRENT);
+    }
 }
--- a/jdk/src/share/classes/java/util/concurrent/BlockingDeque.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BlockingDeque.java	Wed Jul 03 14:35:10 2013 -0700
@@ -41,17 +41,18 @@
  * for the deque to become non-empty when retrieving an element, and wait for
  * space to become available in the deque when storing an element.
  *
- * <p><tt>BlockingDeque</tt> methods come in four forms, with different ways
+ * <p>{@code BlockingDeque} methods come in four forms, with different ways
  * of handling operations that cannot be satisfied immediately, but may be
  * satisfied at some point in the future:
  * one throws an exception, the second returns a special value (either
- * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third
+ * {@code null} or {@code false}, depending on the operation), the third
  * blocks the current thread indefinitely until the operation can succeed,
  * and the fourth blocks for only a given maximum time limit before giving
  * up.  These methods are summarized in the following table:
  *
  * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Summary of BlockingDeque methods</caption>
  *  <tr>
  *    <td ALIGN=CENTER COLSPAN = 5> <b>First Element (Head)</b></td>
  *  </tr>
@@ -116,20 +117,21 @@
  *  </tr>
  * </table>
  *
- * <p>Like any {@link BlockingQueue}, a <tt>BlockingDeque</tt> is thread safe,
+ * <p>Like any {@link BlockingQueue}, a {@code BlockingDeque} is thread safe,
  * does not permit null elements, and may (or may not) be
  * capacity-constrained.
  *
- * <p>A <tt>BlockingDeque</tt> implementation may be used directly as a FIFO
- * <tt>BlockingQueue</tt>. The methods inherited from the
- * <tt>BlockingQueue</tt> interface are precisely equivalent to
- * <tt>BlockingDeque</tt> methods as indicated in the following table:
+ * <p>A {@code BlockingDeque} implementation may be used directly as a FIFO
+ * {@code BlockingQueue}. The methods inherited from the
+ * {@code BlockingQueue} interface are precisely equivalent to
+ * {@code BlockingDeque} methods as indicated in the following table:
  *
  * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Comparison of BlockingQueue and BlockingDeque methods</caption>
  *  <tr>
- *    <td ALIGN=CENTER> <b><tt>BlockingQueue</tt> Method</b></td>
- *    <td ALIGN=CENTER> <b>Equivalent <tt>BlockingDeque</tt> Method</b></td>
+ *    <td ALIGN=CENTER> <b>{@code BlockingQueue} Method</b></td>
+ *    <td ALIGN=CENTER> <b>Equivalent {@code BlockingDeque} Method</b></td>
  *  </tr>
  *  <tr>
  *    <td ALIGN=CENTER COLSPAN = 2> <b>Insert</b></td>
@@ -208,7 +210,7 @@
     /**
      * Inserts the specified element at the front of this deque if it is
      * possible to do so immediately without violating capacity restrictions,
-     * throwing an <tt>IllegalStateException</tt> if no space is currently
+     * throwing an {@code IllegalStateException} if no space is currently
      * available.  When using a capacity-restricted deque, it is generally
      * preferable to use {@link #offerFirst(Object) offerFirst}.
      *
@@ -223,7 +225,7 @@
     /**
      * Inserts the specified element at the end of this deque if it is
      * possible to do so immediately without violating capacity restrictions,
-     * throwing an <tt>IllegalStateException</tt> if no space is currently
+     * throwing an {@code IllegalStateException} if no space is currently
      * available.  When using a capacity-restricted deque, it is generally
      * preferable to use {@link #offerLast(Object) offerLast}.
      *
@@ -238,7 +240,7 @@
     /**
      * Inserts the specified element at the front of this deque if it is
      * possible to do so immediately without violating capacity restrictions,
-     * returning <tt>true</tt> upon success and <tt>false</tt> if no space is
+     * returning {@code true} upon success and {@code false} if no space is
      * currently available.
      * When using a capacity-restricted deque, this method is generally
      * preferable to the {@link #addFirst(Object) addFirst} method, which can
@@ -254,7 +256,7 @@
     /**
      * Inserts the specified element at the end of this deque if it is
      * possible to do so immediately without violating capacity restrictions,
-     * returning <tt>true</tt> upon success and <tt>false</tt> if no space is
+     * returning {@code true} upon success and {@code false} if no space is
      * currently available.
      * When using a capacity-restricted deque, this method is generally
      * preferable to the {@link #addLast(Object) addLast} method, which can
@@ -302,10 +304,10 @@
      *
      * @param e the element to add
      * @param timeout how long to wait before giving up, in units of
-     *        <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     *        <tt>timeout</tt> parameter
-     * @return <tt>true</tt> if successful, or <tt>false</tt> if
+     *        {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code timeout} parameter
+     * @return {@code true} if successful, or {@code false} if
      *         the specified waiting time elapses before space is available
      * @throws InterruptedException if interrupted while waiting
      * @throws ClassCastException if the class of the specified element
@@ -324,10 +326,10 @@
      *
      * @param e the element to add
      * @param timeout how long to wait before giving up, in units of
-     *        <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     *        <tt>timeout</tt> parameter
-     * @return <tt>true</tt> if successful, or <tt>false</tt> if
+     *        {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code timeout} parameter
+     * @return {@code true} if successful, or {@code false} if
      *         the specified waiting time elapses before space is available
      * @throws InterruptedException if interrupted while waiting
      * @throws ClassCastException if the class of the specified element
@@ -363,10 +365,10 @@
      * become available.
      *
      * @param timeout how long to wait before giving up, in units of
-     *        <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     *        <tt>timeout</tt> parameter
-     * @return the head of this deque, or <tt>null</tt> if the specified
+     *        {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code timeout} parameter
+     * @return the head of this deque, or {@code null} if the specified
      *         waiting time elapses before an element is available
      * @throws InterruptedException if interrupted while waiting
      */
@@ -379,10 +381,10 @@
      * become available.
      *
      * @param timeout how long to wait before giving up, in units of
-     *        <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     *        <tt>timeout</tt> parameter
-     * @return the tail of this deque, or <tt>null</tt> if the specified
+     *        {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code timeout} parameter
+     * @return the tail of this deque, or {@code null} if the specified
      *         waiting time elapses before an element is available
      * @throws InterruptedException if interrupted while waiting
      */
@@ -392,13 +394,13 @@
     /**
      * Removes the first occurrence of the specified element from this deque.
      * If the deque does not contain the element, it is unchanged.
-     * More formally, removes the first element <tt>e</tt> such that
-     * <tt>o.equals(e)</tt> (if such an element exists).
-     * Returns <tt>true</tt> if this deque contained the specified element
+     * More formally, removes the first element {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
      * (or equivalently, if this deque changed as a result of the call).
      *
      * @param o element to be removed from this deque, if present
-     * @return <tt>true</tt> if an element was removed as a result of this call
+     * @return {@code true} if an element was removed as a result of this call
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this deque
      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
@@ -410,13 +412,13 @@
     /**
      * Removes the last occurrence of the specified element from this deque.
      * If the deque does not contain the element, it is unchanged.
-     * More formally, removes the last element <tt>e</tt> such that
-     * <tt>o.equals(e)</tt> (if such an element exists).
-     * Returns <tt>true</tt> if this deque contained the specified element
+     * More formally, removes the last element {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
      * (or equivalently, if this deque changed as a result of the call).
      *
      * @param o element to be removed from this deque, if present
-     * @return <tt>true</tt> if an element was removed as a result of this call
+     * @return {@code true} if an element was removed as a result of this call
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this deque
      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
@@ -431,8 +433,8 @@
      * Inserts the specified element into the queue represented by this deque
      * (in other words, at the tail of this deque) if it is possible to do so
      * immediately without violating capacity restrictions, returning
-     * <tt>true</tt> upon success and throwing an
-     * <tt>IllegalStateException</tt> if no space is currently available.
+     * {@code true} upon success and throwing an
+     * {@code IllegalStateException} if no space is currently available.
      * When using a capacity-restricted deque, it is generally preferable to
      * use {@link #offer(Object) offer}.
      *
@@ -452,7 +454,7 @@
      * Inserts the specified element into the queue represented by this deque
      * (in other words, at the tail of this deque) if it is possible to do so
      * immediately without violating capacity restrictions, returning
-     * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
+     * {@code true} upon success and {@code false} if no space is currently
      * available.  When using a capacity-restricted deque, this method is
      * generally preferable to the {@link #add} method, which can fail to
      * insert an element only by throwing an exception.
@@ -494,8 +496,8 @@
      * {@link #offerLast(Object,long,TimeUnit) offerLast}.
      *
      * @param e the element to add
-     * @return <tt>true</tt> if the element was added to this deque, else
-     *         <tt>false</tt>
+     * @return {@code true} if the element was added to this deque, else
+     *         {@code false}
      * @throws InterruptedException {@inheritDoc}
      * @throws ClassCastException if the class of the specified element
      *         prevents it from being added to this deque
@@ -522,11 +524,11 @@
     /**
      * Retrieves and removes the head of the queue represented by this deque
      * (in other words, the first element of this deque), or returns
-     * <tt>null</tt> if this deque is empty.
+     * {@code null} if this deque is empty.
      *
      * <p>This method is equivalent to {@link #pollFirst()}.
      *
-     * @return the head of this deque, or <tt>null</tt> if this deque is empty
+     * @return the head of this deque, or {@code null} if this deque is empty
      */
     E poll();
 
@@ -550,7 +552,7 @@
      * <p>This method is equivalent to
      * {@link #pollFirst(long,TimeUnit) pollFirst}.
      *
-     * @return the head of this deque, or <tt>null</tt> if the
+     * @return the head of this deque, or {@code null} if the
      *         specified waiting time elapses before an element is available
      * @throws InterruptedException if interrupted while waiting
      */
@@ -573,27 +575,27 @@
     /**
      * Retrieves, but does not remove, the head of the queue represented by
      * this deque (in other words, the first element of this deque), or
-     * returns <tt>null</tt> if this deque is empty.
+     * returns {@code null} if this deque is empty.
      *
      * <p>This method is equivalent to {@link #peekFirst() peekFirst}.
      *
-     * @return the head of this deque, or <tt>null</tt> if this deque is empty
+     * @return the head of this deque, or {@code null} if this deque is empty
      */
     E peek();
 
     /**
      * Removes the first occurrence of the specified element from this deque.
      * If the deque does not contain the element, it is unchanged.
-     * More formally, removes the first element <tt>e</tt> such that
-     * <tt>o.equals(e)</tt> (if such an element exists).
-     * Returns <tt>true</tt> if this deque contained the specified element
+     * More formally, removes the first element {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
      * (or equivalently, if this deque changed as a result of the call).
      *
      * <p>This method is equivalent to
      * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
      *
      * @param o element to be removed from this deque, if present
-     * @return <tt>true</tt> if this deque changed as a result of the call
+     * @return {@code true} if this deque changed as a result of the call
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this deque
      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
@@ -603,12 +605,12 @@
     boolean remove(Object o);
 
     /**
-     * Returns <tt>true</tt> if this deque contains the specified element.
-     * More formally, returns <tt>true</tt> if and only if this deque contains
-     * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+     * Returns {@code true} if this deque contains the specified element.
+     * More formally, returns {@code true} if and only if this deque contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
      *
      * @param o object to be checked for containment in this deque
-     * @return <tt>true</tt> if this deque contains the specified element
+     * @return {@code true} if this deque contains the specified element
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this deque
      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
@@ -635,9 +637,10 @@
     // *** Stack methods ***
 
     /**
-     * Pushes an element onto the stack represented by this deque.  In other
-     * words, inserts the element at the front of this deque unless it would
-     * violate capacity restrictions.
+     * Pushes an element onto the stack represented by this deque (in other
+     * words, at the head of this deque) if it is possible to do so
+     * immediately without violating capacity restrictions, throwing an
+     * {@code IllegalStateException} if no space is currently available.
      *
      * <p>This method is equivalent to {@link #addFirst(Object) addFirst}.
      *
--- a/jdk/src/share/classes/java/util/concurrent/BlockingQueue.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BlockingQueue.java	Wed Jul 03 14:35:10 2013 -0700
@@ -44,17 +44,18 @@
  * element, and wait for space to become available in the queue when
  * storing an element.
  *
- * <p><tt>BlockingQueue</tt> methods come in four forms, with different ways
+ * <p>{@code BlockingQueue} methods come in four forms, with different ways
  * of handling operations that cannot be satisfied immediately, but may be
  * satisfied at some point in the future:
  * one throws an exception, the second returns a special value (either
- * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third
+ * {@code null} or {@code false}, depending on the operation), the third
  * blocks the current thread indefinitely until the operation can succeed,
  * and the fourth blocks for only a given maximum time limit before giving
  * up.  These methods are summarized in the following table:
  *
  * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Summary of BlockingQueue methods</caption>
  *  <tr>
  *    <td></td>
  *    <td ALIGN=CENTER><em>Throws exception</em></td>
@@ -85,37 +86,37 @@
  *  </tr>
  * </table>
  *
- * <p>A <tt>BlockingQueue</tt> does not accept <tt>null</tt> elements.
- * Implementations throw <tt>NullPointerException</tt> on attempts
- * to <tt>add</tt>, <tt>put</tt> or <tt>offer</tt> a <tt>null</tt>.  A
- * <tt>null</tt> is used as a sentinel value to indicate failure of
- * <tt>poll</tt> operations.
+ * <p>A {@code BlockingQueue} does not accept {@code null} elements.
+ * Implementations throw {@code NullPointerException} on attempts
+ * to {@code add}, {@code put} or {@code offer} a {@code null}.  A
+ * {@code null} is used as a sentinel value to indicate failure of
+ * {@code poll} operations.
  *
- * <p>A <tt>BlockingQueue</tt> may be capacity bounded. At any given
- * time it may have a <tt>remainingCapacity</tt> beyond which no
- * additional elements can be <tt>put</tt> without blocking.
- * A <tt>BlockingQueue</tt> without any intrinsic capacity constraints always
- * reports a remaining capacity of <tt>Integer.MAX_VALUE</tt>.
+ * <p>A {@code BlockingQueue} may be capacity bounded. At any given
+ * time it may have a {@code remainingCapacity} beyond which no
+ * additional elements can be {@code put} without blocking.
+ * A {@code BlockingQueue} without any intrinsic capacity constraints always
+ * reports a remaining capacity of {@code Integer.MAX_VALUE}.
  *
- * <p> <tt>BlockingQueue</tt> implementations are designed to be used
+ * <p>{@code BlockingQueue} implementations are designed to be used
  * primarily for producer-consumer queues, but additionally support
  * the {@link java.util.Collection} interface.  So, for example, it is
  * possible to remove an arbitrary element from a queue using
- * <tt>remove(x)</tt>. However, such operations are in general
+ * {@code remove(x)}. However, such operations are in general
  * <em>not</em> performed very efficiently, and are intended for only
  * occasional use, such as when a queued message is cancelled.
  *
- * <p> <tt>BlockingQueue</tt> implementations are thread-safe.  All
+ * <p>{@code BlockingQueue} implementations are thread-safe.  All
  * queuing methods achieve their effects atomically using internal
  * locks or other forms of concurrency control. However, the
- * <em>bulk</em> Collection operations <tt>addAll</tt>,
- * <tt>containsAll</tt>, <tt>retainAll</tt> and <tt>removeAll</tt> are
+ * <em>bulk</em> Collection operations {@code addAll},
+ * {@code containsAll}, {@code retainAll} and {@code removeAll} are
  * <em>not</em> necessarily performed atomically unless specified
  * otherwise in an implementation. So it is possible, for example, for
- * <tt>addAll(c)</tt> to fail (throwing an exception) after adding
- * only some of the elements in <tt>c</tt>.
+ * {@code addAll(c)} to fail (throwing an exception) after adding
+ * only some of the elements in {@code c}.
  *
- * <p>A <tt>BlockingQueue</tt> does <em>not</em> intrinsically support
+ * <p>A {@code BlockingQueue} does <em>not</em> intrinsically support
  * any kind of &quot;close&quot; or &quot;shutdown&quot; operation to
  * indicate that no more items will be added.  The needs and usage of
  * such features tend to be implementation-dependent. For example, a
@@ -125,7 +126,7 @@
  *
  * <p>
  * Usage example, based on a typical producer-consumer scenario.
- * Note that a <tt>BlockingQueue</tt> can safely be used with multiple
+ * Note that a {@code BlockingQueue} can safely be used with multiple
  * producers and multiple consumers.
  *  <pre> {@code
  * class Producer implements Runnable {
@@ -181,13 +182,13 @@
     /**
      * Inserts the specified element into this queue if it is possible to do
      * so immediately without violating capacity restrictions, returning
-     * <tt>true</tt> upon success and throwing an
-     * <tt>IllegalStateException</tt> if no space is currently available.
+     * {@code true} upon success and throwing an
+     * {@code IllegalStateException} if no space is currently available.
      * When using a capacity-restricted queue, it is generally preferable to
      * use {@link #offer(Object) offer}.
      *
      * @param e the element to add
-     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     * @return {@code true} (as specified by {@link Collection#add})
      * @throws IllegalStateException if the element cannot be added at this
      *         time due to capacity restrictions
      * @throws ClassCastException if the class of the specified element
@@ -201,14 +202,14 @@
     /**
      * Inserts the specified element into this queue if it is possible to do
      * so immediately without violating capacity restrictions, returning
-     * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
+     * {@code true} upon success and {@code false} if no space is currently
      * available.  When using a capacity-restricted queue, this method is
      * generally preferable to {@link #add}, which can fail to insert an
      * element only by throwing an exception.
      *
      * @param e the element to add
-     * @return <tt>true</tt> if the element was added to this queue, else
-     *         <tt>false</tt>
+     * @return {@code true} if the element was added to this queue, else
+     *         {@code false}
      * @throws ClassCastException if the class of the specified element
      *         prevents it from being added to this queue
      * @throws NullPointerException if the specified element is null
@@ -237,10 +238,10 @@
      *
      * @param e the element to add
      * @param timeout how long to wait before giving up, in units of
-     *        <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     *        <tt>timeout</tt> parameter
-     * @return <tt>true</tt> if successful, or <tt>false</tt> if
+     *        {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code timeout} parameter
+     * @return {@code true} if successful, or {@code false} if
      *         the specified waiting time elapses before space is available
      * @throws InterruptedException if interrupted while waiting
      * @throws ClassCastException if the class of the specified element
@@ -266,10 +267,10 @@
      * specified wait time if necessary for an element to become available.
      *
      * @param timeout how long to wait before giving up, in units of
-     *        <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     *        <tt>timeout</tt> parameter
-     * @return the head of this queue, or <tt>null</tt> if the
+     *        {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code timeout} parameter
+     * @return the head of this queue, or {@code null} if the
      *         specified waiting time elapses before an element is available
      * @throws InterruptedException if interrupted while waiting
      */
@@ -279,11 +280,11 @@
     /**
      * Returns the number of additional elements that this queue can ideally
      * (in the absence of memory or resource constraints) accept without
-     * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no intrinsic
+     * blocking, or {@code Integer.MAX_VALUE} if there is no intrinsic
      * limit.
      *
      * <p>Note that you <em>cannot</em> always tell if an attempt to insert
-     * an element will succeed by inspecting <tt>remainingCapacity</tt>
+     * an element will succeed by inspecting {@code remainingCapacity}
      * because it may be the case that another thread is about to
      * insert or remove an element.
      *
@@ -293,14 +294,14 @@
 
     /**
      * Removes a single instance of the specified element from this queue,
-     * if it is present.  More formally, removes an element <tt>e</tt> such
-     * that <tt>o.equals(e)</tt>, if this queue contains one or more such
+     * if it is present.  More formally, removes an element {@code e} such
+     * that {@code o.equals(e)}, if this queue contains one or more such
      * elements.
-     * Returns <tt>true</tt> if this queue contained the specified element
+     * Returns {@code true} if this queue contained the specified element
      * (or equivalently, if this queue changed as a result of the call).
      *
      * @param o element to be removed from this queue, if present
-     * @return <tt>true</tt> if this queue changed as a result of the call
+     * @return {@code true} if this queue changed as a result of the call
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this queue
      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
@@ -310,12 +311,12 @@
     boolean remove(Object o);
 
     /**
-     * Returns <tt>true</tt> if this queue contains the specified element.
-     * More formally, returns <tt>true</tt> if and only if this queue contains
-     * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+     * Returns {@code true} if this queue contains the specified element.
+     * More formally, returns {@code true} if and only if this queue contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
      *
      * @param o object to be checked for containment in this queue
-     * @return <tt>true</tt> if this queue contains the specified element
+     * @return {@code true} if this queue contains the specified element
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this queue
      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
@@ -329,10 +330,10 @@
      * to the given collection.  This operation may be more
      * efficient than repeatedly polling this queue.  A failure
      * encountered while attempting to add elements to
-     * collection <tt>c</tt> may result in elements being in neither,
+     * collection {@code c} may result in elements being in neither,
      * either or both collections when the associated exception is
      * thrown.  Attempts to drain a queue to itself result in
-     * <tt>IllegalArgumentException</tt>. Further, the behavior of
+     * {@code IllegalArgumentException}. Further, the behavior of
      * this operation is undefined if the specified collection is
      * modified while the operation is in progress.
      *
@@ -353,10 +354,10 @@
      * Removes at most the given number of available elements from
      * this queue and adds them to the given collection.  A failure
      * encountered while attempting to add elements to
-     * collection <tt>c</tt> may result in elements being in neither,
+     * collection {@code c} may result in elements being in neither,
      * either or both collections when the associated exception is
      * thrown.  Attempts to drain a queue to itself result in
-     * <tt>IllegalArgumentException</tt>. Further, the behavior of
+     * {@code IllegalArgumentException}. Further, the behavior of
      * this operation is undefined if the specified collection is
      * modified while the operation is in progress.
      *
--- a/jdk/src/share/classes/java/util/concurrent/BrokenBarrierException.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BrokenBarrierException.java	Wed Jul 03 14:35:10 2013 -0700
@@ -49,13 +49,13 @@
     private static final long serialVersionUID = 7117394618823254244L;
 
     /**
-     * Constructs a <tt>BrokenBarrierException</tt> with no specified detail
+     * Constructs a {@code BrokenBarrierException} with no specified detail
      * message.
      */
     public BrokenBarrierException() {}
 
     /**
-     * Constructs a <tt>BrokenBarrierException</tt> with the specified
+     * Constructs a {@code BrokenBarrierException} with the specified
      * detail message.
      *
      * @param message the detail message
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Wed Jul 03 14:35:10 2013 -0700
@@ -42,6 +42,9 @@
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 import java.util.Queue;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
 
 /**
  * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
@@ -816,7 +819,7 @@
      * Creates an array list and fills it with elements of this list.
      * Used by toArray.
      *
-     * @return the arrayList
+     * @return the array list
      */
     private ArrayList<E> toArrayList() {
         ArrayList<E> list = new ArrayList<E>();
@@ -1024,11 +1027,27 @@
     }
 
     public E poll()           { return pollFirst(); }
+    public E peek()           { return peekFirst(); }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
     public E remove()         { return removeFirst(); }
-    public E peek()           { return peekFirst(); }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E pop()            { return removeFirst(); }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
     public E element()        { return getFirst(); }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     public void push(E e)     { addFirst(e); }
-    public E pop()            { return removeFirst(); }
 
     /**
      * Removes the first element {@code e} such that
@@ -1385,6 +1404,99 @@
         Node<E> nextNode(Node<E> p) { return pred(p); }
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class CLDSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final ConcurrentLinkedDeque<E> queue;
+        Node<E> current;    // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        CLDSpliterator(ConcurrentLinkedDeque<E> queue) {
+            this.queue = queue;
+        }
+
+        public Spliterator<E> trySplit() {
+            Node<E> p;
+            final ConcurrentLinkedDeque<E> q = this.queue;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                if (p.item == null && p == (p = p.next))
+                    current = p = q.first();
+                if (p != null && p.next != null) {
+                    Object[] a = new Object[n];
+                    int i = 0;
+                    do {
+                        if ((a[i] = p.item) != null)
+                            ++i;
+                        if (p == (p = p.next))
+                            p = q.first();
+                    } while (p != null && i < n);
+                    if ((current = p) == null)
+                        exhausted = true;
+                    if (i > 0) {
+                        batch = i;
+                        return Spliterators.spliterator
+                            (a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL |
+                             Spliterator.CONCURRENT);
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            Node<E> p;
+            if (action == null) throw new NullPointerException();
+            final ConcurrentLinkedDeque<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                exhausted = true;
+                do {
+                    E e = p.item;
+                    if (p == (p = p.next))
+                        p = q.first();
+                    if (e != null)
+                        action.accept(e);
+                } while (p != null);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            Node<E> p;
+            if (action == null) throw new NullPointerException();
+            final ConcurrentLinkedDeque<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                E e;
+                do {
+                    e = p.item;
+                    if (p == (p = p.next))
+                        p = q.first();
+                } while (e == null && p != null);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept(e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public long estimateSize() { return Long.MAX_VALUE; }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
+    public Spliterator<E> spliterator() {
+        return new CLDSpliterator<E>(this);
+    }
+
     /**
      * Saves this deque to a stream (that is, serializes it).
      *
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Wed Jul 03 14:35:10 2013 -0700
@@ -41,6 +41,9 @@
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 import java.util.Queue;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
 
 /**
  * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.
@@ -56,7 +59,7 @@
  * Like most other concurrent collection implementations, this class
  * does not permit the use of {@code null} elements.
  *
- * <p>This implementation employs an efficient &quot;wait-free&quot;
+ * <p>This implementation employs an efficient <em>non-blocking</em>
  * algorithm based on one described in <a
  * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple,
  * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
@@ -295,7 +298,7 @@
     }
 
     /**
-     * Try to CAS head to p. If successful, repoint old head to itself
+     * Tries to CAS head to p. If successful, repoint old head to itself
      * as sentinel for succ(), below.
      */
     final void updateHead(Node<E> h, Node<E> p) {
@@ -792,6 +795,96 @@
         tail = t;
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class CLQSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final ConcurrentLinkedQueue<E> queue;
+        Node<E> current;    // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        CLQSpliterator(ConcurrentLinkedQueue<E> queue) {
+            this.queue = queue;
+        }
+
+        public Spliterator<E> trySplit() {
+            Node<E> p;
+            final ConcurrentLinkedQueue<E> q = this.queue;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null) &&
+                p.next != null) {
+                Object[] a = new Object[n];
+                int i = 0;
+                do {
+                    if ((a[i] = p.item) != null)
+                        ++i;
+                    if (p == (p = p.next))
+                        p = q.first();
+                } while (p != null && i < n);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (i > 0) {
+                    batch = i;
+                    return Spliterators.spliterator
+                        (a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL |
+                         Spliterator.CONCURRENT);
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            Node<E> p;
+            if (action == null) throw new NullPointerException();
+            final ConcurrentLinkedQueue<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                exhausted = true;
+                do {
+                    E e = p.item;
+                    if (p == (p = p.next))
+                        p = q.first();
+                    if (e != null)
+                        action.accept(e);
+                } while (p != null);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            Node<E> p;
+            if (action == null) throw new NullPointerException();
+            final ConcurrentLinkedQueue<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                E e;
+                do {
+                    e = p.item;
+                    if (p == (p = p.next))
+                        p = q.first();
+                } while (e == null && p != null);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept(e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public long estimateSize() { return Long.MAX_VALUE; }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
+    public Spliterator<E> spliterator() {
+        return new CLQSpliterator<E>(this);
+    }
+
     /**
      * Throws NullPointerException if argument is null.
      *
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Wed Jul 03 14:35:10 2013 -0700
@@ -34,7 +34,25 @@
  */
 
 package java.util.concurrent;
-import java.util.*;
+import java.util.AbstractCollection;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.Spliterator;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
 
 /**
  * A scalable concurrent {@link ConcurrentNavigableMap} implementation.
@@ -45,38 +63,38 @@
  * <p>This class implements a concurrent variant of <a
  * href="http://en.wikipedia.org/wiki/Skip_list" target="_top">SkipLists</a>
  * providing expected average <i>log(n)</i> time cost for the
- * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and
- * <tt>remove</tt> operations and their variants.  Insertion, removal,
+ * {@code containsKey}, {@code get}, {@code put} and
+ * {@code remove} operations and their variants.  Insertion, removal,
  * update, and access operations safely execute concurrently by
  * multiple threads.  Iterators are <i>weakly consistent</i>, returning
  * elements reflecting the state of the map at some point at or since
  * the creation of the iterator.  They do <em>not</em> throw {@link
- * ConcurrentModificationException}, and may proceed concurrently with
- * other operations. Ascending key ordered views and their iterators
- * are faster than descending ones.
+ * java.util.ConcurrentModificationException ConcurrentModificationException},
+ * and may proceed concurrently with other operations. Ascending key ordered
+ * views and their iterators are faster than descending ones.
  *
- * <p>All <tt>Map.Entry</tt> pairs returned by methods in this class
+ * <p>All {@code Map.Entry} pairs returned by methods in this class
  * and its views represent snapshots of mappings at the time they were
- * produced. They do <em>not</em> support the <tt>Entry.setValue</tt>
+ * produced. They do <em>not</em> support the {@code Entry.setValue}
  * method. (Note however that it is possible to change mappings in the
- * associated map using <tt>put</tt>, <tt>putIfAbsent</tt>, or
- * <tt>replace</tt>, depending on exactly which effect you need.)
+ * associated map using {@code put}, {@code putIfAbsent}, or
+ * {@code replace}, depending on exactly which effect you need.)
  *
- * <p>Beware that, unlike in most collections, the <tt>size</tt>
+ * <p>Beware that, unlike in most collections, the {@code size}
  * method is <em>not</em> a constant-time operation. Because of the
  * asynchronous nature of these maps, determining the current number
  * of elements requires a traversal of the elements, and so may report
  * inaccurate results if this collection is modified during traversal.
- * Additionally, the bulk operations <tt>putAll</tt>, <tt>equals</tt>,
- * <tt>toArray</tt>, <tt>containsValue</tt>, and <tt>clear</tt> are
+ * Additionally, the bulk operations {@code putAll}, {@code equals},
+ * {@code toArray}, {@code containsValue}, and {@code clear} are
  * <em>not</em> guaranteed to be performed atomically. For example, an
- * iterator operating concurrently with a <tt>putAll</tt> operation
+ * iterator operating concurrently with a {@code putAll} operation
  * might view only some of the added elements.
  *
  * <p>This class and its views and iterators implement all of the
  * <em>optional</em> methods of the {@link Map} and {@link Iterator}
  * interfaces. Like most other concurrent collections, this class does
- * <em>not</em> permit the use of <tt>null</tt> keys or values because some
+ * <em>not</em> permit the use of {@code null} keys or values because some
  * null return values cannot be reliably distinguished from the absence of
  * elements.
  *
@@ -89,7 +107,6 @@
  * @param <V> the type of mapped values
  * @since 1.6
  */
-@SuppressWarnings("unchecked")
 public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
     implements ConcurrentNavigableMap<K,V>,
                Cloneable,
@@ -257,7 +274,7 @@
      *
      * Indexing uses skip list parameters that maintain good search
      * performance while using sparser-than-usual indices: The
-     * hardwired parameters k=1, p=0.5 (see method randomLevel) mean
+     * hardwired parameters k=1, p=0.5 (see method doPut) mean
      * that about one-quarter of the nodes have indices. Of those that
      * do, half have one level, a quarter have two, and so on (see
      * Pugh's Skip List Cookbook, sec 3.4).  The expected total space
@@ -295,6 +312,20 @@
      * there is a fair amount of near-duplication of code to handle
      * variants.
      *
+     * To produce random values without interference across threads,
+     * we use within-JDK thread local random support (via the
+     * "secondary seed", to avoid interference with user-level
+     * ThreadLocalRandom.)
+     *
+     * A previous version of this class wrapped non-comparable keys
+     * with their comparators to emulate Comparables when using
+     * comparators vs Comparables.  However, JVMs now appear to better
+     * handle infusing comparator-vs-comparable choice into search
+     * loops. Static method cpr(comparator, x, y) is used for all
+     * comparisons, which works well as long as the comparator
+     * argument is set up outside of loops (thus sometimes passed as
+     * an argument to internal methods) to avoid field re-reads.
+     *
      * For explanation of algorithms sharing at least a couple of
      * features with this one, see Mikhail Fomitchev's thesis
      * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis
@@ -323,12 +354,6 @@
     private static final long serialVersionUID = -8627078645895051609L;
 
     /**
-     * Generates the initial random seed for the cheaper per-instance
-     * random number generators used in randomLevel.
-     */
-    private static final Random seedGenerator = new Random();
-
-    /**
      * Special value used to identify base-level header
      */
     private static final Object BASE_HEADER = new Object();
@@ -339,17 +364,12 @@
     private transient volatile HeadIndex<K,V> head;
 
     /**
-     * The comparator used to maintain order in this map, or null
-     * if using natural ordering.
+     * The comparator used to maintain order in this map, or null if
+     * using natural ordering.  (Non-private to simplify access in
+     * nested classes.)
      * @serial
      */
-    private final Comparator<? super K> comparator;
-
-    /**
-     * Seed for simple random number generator.  Not volatile since it
-     * doesn't matter too much if different threads don't see updates.
-     */
-    private transient int randomSeed;
+    final Comparator<? super K> comparator;
 
     /** Lazily initialized key set */
     private transient KeySet<K> keySet;
@@ -365,12 +385,11 @@
      * clear, readObject. and ConcurrentSkipListSet.clone.
      * (Note that comparator must be separately initialized.)
      */
-    final void initialize() {
+    private void initialize() {
         keySet = null;
         entrySet = null;
         values = null;
         descendingMap = null;
-        randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero
         head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null),
                                   null, null, 1);
     }
@@ -438,7 +457,7 @@
          * because callers will have already read value field and need
          * to use that read (not another done here) and so directly
          * test if value points to node.
-         * @param n a possibly null reference to a node
+         *
          * @return true if this node is a marker node
          */
         boolean isMarker() {
@@ -477,7 +496,7 @@
              */
             if (f == next && this == b.next) {
                 if (f == null || f.value != f) // not already marked
-                    appendMarker(f);
+                    casNext(f, new Node<K,V>(f));
                 else
                     b.casNext(this, f.next);
             }
@@ -487,13 +506,14 @@
          * Returns value if this node contains a valid key-value pair,
          * else null.
          * @return this node's value if it isn't a marker or header or
-         * is deleted, else null.
+         * is deleted, else null
          */
         V getValidValue() {
             Object v = value;
             if (v == this || v == BASE_HEADER)
                 return null;
-            return (V)v;
+            @SuppressWarnings("unchecked") V vv = (V)v;
+            return vv;
         }
 
         /**
@@ -502,10 +522,11 @@
          * @return new entry or null
          */
         AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() {
-            V v = getValidValue();
-            if (v == null)
+            Object v = value;
+            if (v == null || v == this || v == BASE_HEADER)
                 return null;
-            return new AbstractMap.SimpleImmutableEntry<K,V>(key, v);
+            @SuppressWarnings("unchecked") V vv = (V)v;
+            return new AbstractMap.SimpleImmutableEntry<K,V>(key, vv);
         }
 
         // UNSAFE mechanics
@@ -588,7 +609,7 @@
          * @return true if successful
          */
         final boolean unlink(Index<K,V> succ) {
-            return !indexesDeletedNode() && casRight(succ, succ.right);
+            return node.value != null && casRight(succ, succ.right);
         }
 
         // Unsafe mechanics
@@ -622,80 +643,12 @@
     /* ---------------- Comparison utilities -------------- */
 
     /**
-     * Represents a key with a comparator as a Comparable.
-     *
-     * Because most sorted collections seem to use natural ordering on
-     * Comparables (Strings, Integers, etc), most internal methods are
-     * geared to use them. This is generally faster than checking
-     * per-comparison whether to use comparator or comparable because
-     * it doesn't require a (Comparable) cast for each comparison.
-     * (Optimizers can only sometimes remove such redundant checks
-     * themselves.) When Comparators are used,
-     * ComparableUsingComparators are created so that they act in the
-     * same way as natural orderings. This penalizes use of
-     * Comparators vs Comparables, which seems like the right
-     * tradeoff.
-     */
-    static final class ComparableUsingComparator<K> implements Comparable<K> {
-        final K actualKey;
-        final Comparator<? super K> cmp;
-        ComparableUsingComparator(K key, Comparator<? super K> cmp) {
-            this.actualKey = key;
-            this.cmp = cmp;
-        }
-        public int compareTo(K k2) {
-            return cmp.compare(actualKey, k2);
-        }
-    }
-
-    /**
-     * If using comparator, return a ComparableUsingComparator, else
-     * cast key as Comparable, which may cause ClassCastException,
-     * which is propagated back to caller.
+     * Compares using comparator or natural ordering if null.
+     * Called only by methods that have performed required type checks.
      */
-    private Comparable<? super K> comparable(Object key)
-            throws ClassCastException {
-        if (key == null)
-            throw new NullPointerException();
-        if (comparator != null)
-            return new ComparableUsingComparator<K>((K)key, comparator);
-        else
-            return (Comparable<? super K>)key;
-    }
-
-    /**
-     * Compares using comparator or natural ordering. Used when the
-     * ComparableUsingComparator approach doesn't apply.
-     */
-    int compare(K k1, K k2) throws ClassCastException {
-        Comparator<? super K> cmp = comparator;
-        if (cmp != null)
-            return cmp.compare(k1, k2);
-        else
-            return ((Comparable<? super K>)k1).compareTo(k2);
-    }
-
-    /**
-     * Returns true if given key greater than or equal to least and
-     * strictly less than fence, bypassing either test if least or
-     * fence are null. Needed mainly in submap operations.
-     */
-    boolean inHalfOpenRange(K key, K least, K fence) {
-        if (key == null)
-            throw new NullPointerException();
-        return ((least == null || compare(key, least) >= 0) &&
-                (fence == null || compare(key, fence) <  0));
-    }
-
-    /**
-     * Returns true if given key greater than or equal to least and less
-     * or equal to fence. Needed mainly in submap operations.
-     */
-    boolean inOpenRange(K key, K least, K fence) {
-        if (key == null)
-            throw new NullPointerException();
-        return ((least == null || compare(key, least) >= 0) &&
-                (fence == null || compare(key, fence) <= 0));
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    static final int cpr(Comparator c, Object x, Object y) {
+        return (c != null) ? c.compare(x, y) : ((Comparable)x).compareTo(y);
     }
 
     /* ---------------- Traversal -------------- */
@@ -708,13 +661,11 @@
      * @param key the key
      * @return a predecessor of key
      */
-    private Node<K,V> findPredecessor(Comparable<? super K> key) {
+    private Node<K,V> findPredecessor(Object key, Comparator<? super K> cmp) {
         if (key == null)
             throw new NullPointerException(); // don't postpone errors
         for (;;) {
-            Index<K,V> q = head;
-            Index<K,V> r = q.right;
-            for (;;) {
+            for (Index<K,V> q = head, r = q.right, d;;) {
                 if (r != null) {
                     Node<K,V> n = r.node;
                     K k = n.key;
@@ -724,18 +675,16 @@
                         r = q.right;         // reread r
                         continue;
                     }
-                    if (key.compareTo(k) > 0) {
+                    if (cpr(cmp, key, k) > 0) {
                         q = r;
                         r = r.right;
                         continue;
                     }
                 }
-                Index<K,V> d = q.down;
-                if (d != null) {
-                    q = d;
-                    r = d.right;
-                } else
+                if ((d = q.down) == null)
                     return q.node;
+                q = d;
+                r = d.right;
             }
         }
     }
@@ -784,54 +733,71 @@
      * @param key the key
      * @return node holding key, or null if no such
      */
-    private Node<K,V> findNode(Comparable<? super K> key) {
-        for (;;) {
-            Node<K,V> b = findPredecessor(key);
-            Node<K,V> n = b.next;
-            for (;;) {
+    private Node<K,V> findNode(Object key) {
+        if (key == null)
+            throw new NullPointerException(); // don't postpone errors
+        Comparator<? super K> cmp = comparator;
+        outer: for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
+                Object v; int c;
                 if (n == null)
-                    return null;
+                    break outer;
                 Node<K,V> f = n.next;
                 if (n != b.next)                // inconsistent read
                     break;
-                Object v = n.value;
-                if (v == null) {                // n is deleted
+                if ((v = n.value) == null) {    // n is deleted
                     n.helpDelete(b, f);
                     break;
                 }
-                if (v == n || b.value == null)  // b is deleted
+                if (b.value == null || v == n)  // b is deleted
                     break;
-                int c = key.compareTo(n.key);
-                if (c == 0)
+                if ((c = cpr(cmp, key, n.key)) == 0)
                     return n;
                 if (c < 0)
-                    return null;
+                    break outer;
                 b = n;
                 n = f;
             }
         }
+        return null;
     }
 
     /**
-     * Gets value for key using findNode.
-     * @param okey the key
+     * Gets value for key. Almost the same as findNode, but returns
+     * the found value (to avoid retries during re-reads)
+     *
+     * @param key the key
      * @return the value, or null if absent
      */
-    private V doGet(Object okey) {
-        Comparable<? super K> key = comparable(okey);
-        /*
-         * Loop needed here and elsewhere in case value field goes
-         * null just as it is about to be returned, in which case we
-         * lost a race with a deletion, so must retry.
-         */
-        for (;;) {
-            Node<K,V> n = findNode(key);
-            if (n == null)
-                return null;
-            Object v = n.value;
-            if (v != null)
-                return (V)v;
+    private V doGet(Object key) {
+        if (key == null)
+            throw new NullPointerException();
+        Comparator<? super K> cmp = comparator;
+        outer: for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
+                Object v; int c;
+                if (n == null)
+                    break outer;
+                Node<K,V> f = n.next;
+                if (n != b.next)                // inconsistent read
+                    break;
+                if ((v = n.value) == null) {    // n is deleted
+                    n.helpDelete(b, f);
+                    break;
+                }
+                if (b.value == null || v == n)  // b is deleted
+                    break;
+                if ((c = cpr(cmp, key, n.key)) == 0) {
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    return vv;
+                }
+                if (c < 0)
+                    break outer;
+                b = n;
+                n = f;
+            }
         }
+        return null;
     }
 
     /* ---------------- Insertion -------------- */
@@ -839,187 +805,126 @@
     /**
      * Main insertion method.  Adds element if not present, or
      * replaces value if present and onlyIfAbsent is false.
-     * @param kkey the key
-     * @param value  the value that must be associated with key
+     * @param key the key
+     * @param value the value that must be associated with key
      * @param onlyIfAbsent if should not insert if already present
      * @return the old value, or null if newly inserted
      */
-    private V doPut(K kkey, V value, boolean onlyIfAbsent) {
-        Comparable<? super K> key = comparable(kkey);
-        for (;;) {
-            Node<K,V> b = findPredecessor(key);
-            Node<K,V> n = b.next;
-            for (;;) {
+    private V doPut(K key, V value, boolean onlyIfAbsent) {
+        Node<K,V> z;             // added node
+        if (key == null)
+            throw new NullPointerException();
+        Comparator<? super K> cmp = comparator;
+        outer: for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
                 if (n != null) {
+                    Object v; int c;
                     Node<K,V> f = n.next;
                     if (n != b.next)               // inconsistent read
                         break;
-                    Object v = n.value;
-                    if (v == null) {               // n is deleted
+                    if ((v = n.value) == null) {   // n is deleted
                         n.helpDelete(b, f);
                         break;
                     }
-                    if (v == n || b.value == null) // b is deleted
+                    if (b.value == null || v == n) // b is deleted
                         break;
-                    int c = key.compareTo(n.key);
-                    if (c > 0) {
+                    if ((c = cpr(cmp, key, n.key)) > 0) {
                         b = n;
                         n = f;
                         continue;
                     }
                     if (c == 0) {
-                        if (onlyIfAbsent || n.casValue(v, value))
-                            return (V)v;
-                        else
-                            break; // restart if lost race to replace value
+                        if (onlyIfAbsent || n.casValue(v, value)) {
+                            @SuppressWarnings("unchecked") V vv = (V)v;
+                            return vv;
+                        }
+                        break; // restart if lost race to replace value
                     }
                     // else c < 0; fall through
                 }
 
-                Node<K,V> z = new Node<K,V>(kkey, value, n);
+                z = new Node<K,V>(key, value, n);
                 if (!b.casNext(n, z))
                     break;         // restart if lost race to append to b
-                int level = randomLevel();
-                if (level > 0)
-                    insertIndex(z, level);
-                return null;
+                break outer;
             }
         }
-    }
 
-    /**
-     * Returns a random level for inserting a new node.
-     * Hardwired to k=1, p=0.5, max 31 (see above and
-     * Pugh's "Skip List Cookbook", sec 3.4).
-     *
-     * This uses the simplest of the generators described in George
-     * Marsaglia's "Xorshift RNGs" paper.  This is not a high-quality
-     * generator but is acceptable here.
-     */
-    private int randomLevel() {
-        int x = randomSeed;
-        x ^= x << 13;
-        x ^= x >>> 17;
-        randomSeed = x ^= x << 5;
-        if ((x & 0x80000001) != 0) // test highest and lowest bits
-            return 0;
-        int level = 1;
-        while (((x >>>= 1) & 1) != 0) ++level;
-        return level;
-    }
-
-    /**
-     * Creates and adds index nodes for the given node.
-     * @param z the node
-     * @param level the level of the index
-     */
-    private void insertIndex(Node<K,V> z, int level) {
-        HeadIndex<K,V> h = head;
-        int max = h.level;
-
-        if (level <= max) {
+        int rnd = ThreadLocalRandom.nextSecondarySeed();
+        if ((rnd & 0x80000001) == 0) { // test highest and lowest bits
+            int level = 1, max;
+            while (((rnd >>>= 1) & 1) != 0)
+                ++level;
             Index<K,V> idx = null;
-            for (int i = 1; i <= level; ++i)
-                idx = new Index<K,V>(z, idx, null);
-            addIndex(idx, h, level);
-
-        } else { // Add a new level
-            /*
-             * To reduce interference by other threads checking for
-             * empty levels in tryReduceLevel, new levels are added
-             * with initialized right pointers. Which in turn requires
-             * keeping levels in an array to access them while
-             * creating new head index nodes from the opposite
-             * direction.
-             */
-            level = max + 1;
-            Index<K,V>[] idxs = (Index<K,V>[])new Index<?,?>[level+1];
-            Index<K,V> idx = null;
-            for (int i = 1; i <= level; ++i)
-                idxs[i] = idx = new Index<K,V>(z, idx, null);
-
-            HeadIndex<K,V> oldh;
-            int k;
-            for (;;) {
-                oldh = head;
-                int oldLevel = oldh.level;
-                if (level <= oldLevel) { // lost race to add level
-                    k = level;
-                    break;
-                }
-                HeadIndex<K,V> newh = oldh;
-                Node<K,V> oldbase = oldh.node;
-                for (int j = oldLevel+1; j <= level; ++j)
-                    newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
-                if (casHead(oldh, newh)) {
-                    k = oldLevel;
-                    break;
+            HeadIndex<K,V> h = head;
+            if (level <= (max = h.level)) {
+                for (int i = 1; i <= level; ++i)
+                    idx = new Index<K,V>(z, idx, null);
+            }
+            else { // try to grow by one level
+                level = max + 1; // hold in array and later pick the one to use
+                @SuppressWarnings("unchecked")Index<K,V>[] idxs =
+                    (Index<K,V>[])new Index<?,?>[level+1];
+                for (int i = 1; i <= level; ++i)
+                    idxs[i] = idx = new Index<K,V>(z, idx, null);
+                for (;;) {
+                    h = head;
+                    int oldLevel = h.level;
+                    if (level <= oldLevel) // lost race to add level
+                        break;
+                    HeadIndex<K,V> newh = h;
+                    Node<K,V> oldbase = h.node;
+                    for (int j = oldLevel+1; j <= level; ++j)
+                        newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
+                    if (casHead(h, newh)) {
+                        h = newh;
+                        idx = idxs[level = oldLevel];
+                        break;
+                    }
                 }
             }
-            addIndex(idxs[k], oldh, k);
-        }
-    }
-
-    /**
-     * Adds given index nodes from given level down to 1.
-     * @param idx the topmost index node being inserted
-     * @param h the value of head to use to insert. This must be
-     * snapshotted by callers to provide correct insertion level
-     * @param indexLevel the level of the index
-     */
-    private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) {
-        // Track next level to insert in case of retries
-        int insertionLevel = indexLevel;
-        Comparable<? super K> key = comparable(idx.node.key);
-        if (key == null) throw new NullPointerException();
+            // find insertion points and splice in
+            splice: for (int insertionLevel = level;;) {
+                int j = h.level;
+                for (Index<K,V> q = h, r = q.right, t = idx;;) {
+                    if (q == null || t == null)
+                        break splice;
+                    if (r != null) {
+                        Node<K,V> n = r.node;
+                        // compare before deletion check avoids needing recheck
+                        int c = cpr(cmp, key, n.key);
+                        if (n.value == null) {
+                            if (!q.unlink(r))
+                                break;
+                            r = q.right;
+                            continue;
+                        }
+                        if (c > 0) {
+                            q = r;
+                            r = r.right;
+                            continue;
+                        }
+                    }
 
-        // Similar to findPredecessor, but adding index nodes along
-        // path to key.
-        for (;;) {
-            int j = h.level;
-            Index<K,V> q = h;
-            Index<K,V> r = q.right;
-            Index<K,V> t = idx;
-            for (;;) {
-                if (r != null) {
-                    Node<K,V> n = r.node;
-                    // compare before deletion check avoids needing recheck
-                    int c = key.compareTo(n.key);
-                    if (n.value == null) {
-                        if (!q.unlink(r))
-                            break;
-                        r = q.right;
-                        continue;
-                    }
-                    if (c > 0) {
-                        q = r;
-                        r = r.right;
-                        continue;
+                    if (j == insertionLevel) {
+                        if (!q.link(r, t))
+                            break; // restart
+                        if (t.node.value == null) {
+                            findNode(key);
+                            break splice;
+                        }
+                        if (--insertionLevel == 0)
+                            break splice;
                     }
+
+                    if (--j >= insertionLevel && j < level)
+                        t = t.down;
+                    q = q.down;
+                    r = q.right;
                 }
-
-                if (j == insertionLevel) {
-                    // Don't insert index if node already deleted
-                    if (t.indexesDeletedNode()) {
-                        findNode(key); // cleans up
-                        return;
-                    }
-                    if (!q.link(r, t))
-                        break; // restart
-                    if (--insertionLevel == 0) {
-                        // need final deletion check before return
-                        if (t.indexesDeletedNode())
-                            findNode(key);
-                        return;
-                    }
-                }
-
-                if (--j >= insertionLevel && j < indexLevel)
-                    t = t.down;
-                q = q.down;
-                r = q.right;
             }
         }
+        return null;
     }
 
     /* ---------------- Deletion -------------- */
@@ -1038,51 +943,52 @@
      * search for it, and we'd like to ensure lack of garbage
      * retention, so must call to be sure.
      *
-     * @param okey the key
+     * @param key the key
      * @param value if non-null, the value that must be
      * associated with key
      * @return the node, or null if not found
      */
-    final V doRemove(Object okey, Object value) {
-        Comparable<? super K> key = comparable(okey);
-        for (;;) {
-            Node<K,V> b = findPredecessor(key);
-            Node<K,V> n = b.next;
-            for (;;) {
+    final V doRemove(Object key, Object value) {
+        if (key == null)
+            throw new NullPointerException();
+        Comparator<? super K> cmp = comparator;
+        outer: for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
+                Object v; int c;
                 if (n == null)
-                    return null;
+                    break outer;
                 Node<K,V> f = n.next;
                 if (n != b.next)                    // inconsistent read
                     break;
-                Object v = n.value;
-                if (v == null) {                    // n is deleted
+                if ((v = n.value) == null) {        // n is deleted
                     n.helpDelete(b, f);
                     break;
                 }
-                if (v == n || b.value == null)      // b is deleted
+                if (b.value == null || v == n)      // b is deleted
                     break;
-                int c = key.compareTo(n.key);
-                if (c < 0)
-                    return null;
+                if ((c = cpr(cmp, key, n.key)) < 0)
+                    break outer;
                 if (c > 0) {
                     b = n;
                     n = f;
                     continue;
                 }
                 if (value != null && !value.equals(v))
-                    return null;
+                    break outer;
                 if (!n.casValue(v, null))
                     break;
                 if (!n.appendMarker(f) || !b.casNext(n, f))
-                    findNode(key);                  // Retry via findNode
+                    findNode(key);                  // retry via findNode
                 else {
-                    findPredecessor(key);           // Clean index
+                    findPredecessor(key, cmp);      // clean index
                     if (head.right == null)
                         tryReduceLevel();
                 }
-                return (V)v;
+                @SuppressWarnings("unchecked") V vv = (V)v;
+                return vv;
             }
         }
+        return null;
     }
 
     /**
@@ -1126,11 +1032,9 @@
      * Specialized variant of findNode to get first valid node.
      * @return first node or null if empty
      */
-    Node<K,V> findFirst() {
-        for (;;) {
-            Node<K,V> b = head.node;
-            Node<K,V> n = b.next;
-            if (n == null)
+    final Node<K,V> findFirst() {
+        for (Node<K,V> b, n;;) {
+            if ((n = (b = head.node).next) == null)
                 return null;
             if (n.value != null)
                 return n;
@@ -1142,11 +1046,9 @@
      * Removes first entry; returns its snapshot.
      * @return null if empty, else snapshot of first entry
      */
-    Map.Entry<K,V> doRemoveFirstEntry() {
-        for (;;) {
-            Node<K,V> b = head.node;
-            Node<K,V> n = b.next;
-            if (n == null)
+    private Map.Entry<K,V> doRemoveFirstEntry() {
+        for (Node<K,V> b, n;;) {
+            if ((n = (b = head.node).next) == null)
                 return null;
             Node<K,V> f = n.next;
             if (n != b.next)
@@ -1161,7 +1063,8 @@
             if (!n.appendMarker(f) || !b.casNext(n, f))
                 findFirst(); // retry
             clearIndexToFirst();
-            return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v);
+            @SuppressWarnings("unchecked") V vv = (V)v;
+            return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, vv);
         }
     }
 
@@ -1170,8 +1073,7 @@
      */
     private void clearIndexToFirst() {
         for (;;) {
-            Index<K,V> q = head;
-            for (;;) {
+            for (Index<K,V> q = head;;) {
                 Index<K,V> r = q.right;
                 if (r != null && r.indexesDeletedNode() && !q.unlink(r))
                     break;
@@ -1184,6 +1086,52 @@
         }
     }
 
+    /**
+     * Removes last entry; returns its snapshot.
+     * Specialized variant of doRemove.
+     * @return null if empty, else snapshot of last entry
+     */
+    private Map.Entry<K,V> doRemoveLastEntry() {
+        for (;;) {
+            Node<K,V> b = findPredecessorOfLast();
+            Node<K,V> n = b.next;
+            if (n == null) {
+                if (b.isBaseHeader())               // empty
+                    return null;
+                else
+                    continue; // all b's successors are deleted; retry
+            }
+            for (;;) {
+                Node<K,V> f = n.next;
+                if (n != b.next)                    // inconsistent read
+                    break;
+                Object v = n.value;
+                if (v == null) {                    // n is deleted
+                    n.helpDelete(b, f);
+                    break;
+                }
+                if (b.value == null || v == n)      // b is deleted
+                    break;
+                if (f != null) {
+                    b = n;
+                    n = f;
+                    continue;
+                }
+                if (!n.casValue(v, null))
+                    break;
+                K key = n.key;
+                if (!n.appendMarker(f) || !b.casNext(n, f))
+                    findNode(key);                  // retry via findNode
+                else {                              // clean index
+                    findPredecessor(key, comparator);
+                    if (head.right == null)
+                        tryReduceLevel();
+                }
+                @SuppressWarnings("unchecked") V vv = (V)v;
+                return new AbstractMap.SimpleImmutableEntry<K,V>(key, vv);
+            }
+        }
+    }
 
     /* ---------------- Finding and removing last element -------------- */
 
@@ -1191,7 +1139,7 @@
      * Specialized version of find to get last valid node.
      * @return last node or null if empty
      */
-    Node<K,V> findLast() {
+    final Node<K,V> findLast() {
         /*
          * findPredecessor can't be used to traverse index level
          * because this doesn't use comparisons.  So traversals of
@@ -1210,9 +1158,7 @@
             } else if ((d = q.down) != null) {
                 q = d;
             } else {
-                Node<K,V> b = q.node;
-                Node<K,V> n = b.next;
-                for (;;) {
+                for (Node<K,V> b = q.node, n = b.next;;) {
                     if (n == null)
                         return b.isBaseHeader() ? null : b;
                     Node<K,V> f = n.next;            // inconsistent read
@@ -1223,7 +1169,7 @@
                         n.helpDelete(b, f);
                         break;
                     }
-                    if (v == n || b.value == null)   // b is deleted
+                    if (b.value == null || v == n)      // b is deleted
                         break;
                     b = n;
                     n = f;
@@ -1242,8 +1188,7 @@
      */
     private Node<K,V> findPredecessorOfLast() {
         for (;;) {
-            Index<K,V> q = head;
-            for (;;) {
+            for (Index<K,V> q = head;;) {
                 Index<K,V> d, r;
                 if ((r = q.right) != null) {
                     if (r.indexesDeletedNode()) {
@@ -1264,53 +1209,6 @@
         }
     }
 
-    /**
-     * Removes last entry; returns its snapshot.
-     * Specialized variant of doRemove.
-     * @return null if empty, else snapshot of last entry
-     */
-    Map.Entry<K,V> doRemoveLastEntry() {
-        for (;;) {
-            Node<K,V> b = findPredecessorOfLast();
-            Node<K,V> n = b.next;
-            if (n == null) {
-                if (b.isBaseHeader())               // empty
-                    return null;
-                else
-                    continue; // all b's successors are deleted; retry
-            }
-            for (;;) {
-                Node<K,V> f = n.next;
-                if (n != b.next)                    // inconsistent read
-                    break;
-                Object v = n.value;
-                if (v == null) {                    // n is deleted
-                    n.helpDelete(b, f);
-                    break;
-                }
-                if (v == n || b.value == null)      // b is deleted
-                    break;
-                if (f != null) {
-                    b = n;
-                    n = f;
-                    continue;
-                }
-                if (!n.casValue(v, null))
-                    break;
-                K key = n.key;
-                Comparable<? super K> ck = comparable(key);
-                if (!n.appendMarker(f) || !b.casNext(n, f))
-                    findNode(ck);                  // Retry via findNode
-                else {
-                    findPredecessor(ck);           // Clean index
-                    if (head.right == null)
-                        tryReduceLevel();
-                }
-                return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v);
-            }
-        }
-    }
-
     /* ---------------- Relational operations -------------- */
 
     // Control values OR'ed as arguments to findNear
@@ -1321,29 +1219,28 @@
 
     /**
      * Utility for ceiling, floor, lower, higher methods.
-     * @param kkey the key
+     * @param key the key
      * @param rel the relation -- OR'ed combination of EQ, LT, GT
      * @return nearest node fitting relation, or null if no such
      */
-    Node<K,V> findNear(K kkey, int rel) {
-        Comparable<? super K> key = comparable(kkey);
+    final Node<K,V> findNear(K key, int rel, Comparator<? super K> cmp) {
+        if (key == null)
+            throw new NullPointerException();
         for (;;) {
-            Node<K,V> b = findPredecessor(key);
-            Node<K,V> n = b.next;
-            for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
+                Object v;
                 if (n == null)
                     return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b;
                 Node<K,V> f = n.next;
                 if (n != b.next)                  // inconsistent read
                     break;
-                Object v = n.value;
-                if (v == null) {                  // n is deleted
+                if ((v = n.value) == null) {      // n is deleted
                     n.helpDelete(b, f);
                     break;
                 }
-                if (v == n || b.value == null)    // b is deleted
+                if (b.value == null || v == n)      // b is deleted
                     break;
-                int c = key.compareTo(n.key);
+                int c = cpr(cmp, key, n.key);
                 if ((c == 0 && (rel & EQ) != 0) ||
                     (c <  0 && (rel & LT) == 0))
                     return n;
@@ -1361,9 +1258,10 @@
      * @param rel the relation -- OR'ed combination of EQ, LT, GT
      * @return Entry fitting relation, or null if no such
      */
-    AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) {
+    final AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) {
+        Comparator<? super K> cmp = comparator;
         for (;;) {
-            Node<K,V> n = findNear(key, rel);
+            Node<K,V> n = findNear(key, rel, cmp);
             if (n == null)
                 return null;
             AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
@@ -1372,7 +1270,6 @@
         }
     }
 
-
     /* ---------------- Constructors -------------- */
 
     /**
@@ -1389,7 +1286,7 @@
      * comparator.
      *
      * @param comparator the comparator that will be used to order this map.
-     *        If <tt>null</tt>, the {@linkplain Comparable natural
+     *        If {@code null}, the {@linkplain Comparable natural
      *        ordering} of the keys will be used.
      */
     public ConcurrentSkipListMap(Comparator<? super K> comparator) {
@@ -1403,7 +1300,7 @@
      * the keys.
      *
      * @param  m the map whose mappings are to be placed in this map
-     * @throws ClassCastException if the keys in <tt>m</tt> are not
+     * @throws ClassCastException if the keys in {@code m} are not
      *         {@link Comparable}, or are not mutually comparable
      * @throws NullPointerException if the specified map or any of its keys
      *         or values are null
@@ -1430,7 +1327,7 @@
     }
 
     /**
-     * Returns a shallow copy of this <tt>ConcurrentSkipListMap</tt>
+     * Returns a shallow copy of this {@code ConcurrentSkipListMap}
      * instance. (The keys and values themselves are not cloned.)
      *
      * @return a shallow copy of this map
@@ -1477,8 +1374,14 @@
             map.entrySet().iterator();
         while (it.hasNext()) {
             Map.Entry<? extends K, ? extends V> e = it.next();
-            int j = randomLevel();
-            if (j > h.level) j = h.level + 1;
+            int rnd = ThreadLocalRandom.current().nextInt();
+            int j = 0;
+            if ((rnd & 0x80000001) == 0) {
+                do {
+                    ++j;
+                } while (((rnd >>>= 1) & 1) != 0);
+                if (j > h.level) j = h.level + 1;
+            }
             K k = e.getKey();
             V v = e.getValue();
             if (k == null || v == null)
@@ -1511,7 +1414,7 @@
      *
      * @serialData The key (Object) and value (Object) for each
      * key-value mapping represented by the map, followed by
-     * <tt>null</tt>. The key-value mappings are emitted in key-order
+     * {@code null}. The key-value mappings are emitted in key-order
      * (as determined by the Comparator, or by the keys' natural
      * ordering if no Comparator).
      */
@@ -1534,6 +1437,7 @@
     /**
      * Reconstitutes this map from a stream (that is, deserializes it).
      */
+    @SuppressWarnings("unchecked")
     private void readObject(final java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
         // Read in the Comparator and any hidden stuff
@@ -1569,8 +1473,14 @@
                 throw new NullPointerException();
             K key = (K) k;
             V val = (V) v;
-            int j = randomLevel();
-            if (j > h.level) j = h.level + 1;
+            int rnd = ThreadLocalRandom.current().nextInt();
+            int j = 0;
+            if ((rnd & 0x80000001) == 0) {
+                do {
+                    ++j;
+                } while (((rnd >>>= 1) & 1) != 0);
+                if (j > h.level) j = h.level + 1;
+            }
             Node<K,V> z = new Node<K,V>(key, val, null);
             basepred.next = z;
             basepred = z;
@@ -1595,11 +1505,11 @@
     /* ------ Map API methods ------ */
 
     /**
-     * Returns <tt>true</tt> if this map contains a mapping for the specified
+     * Returns {@code true} if this map contains a mapping for the specified
      * key.
      *
      * @param key key whose presence in this map is to be tested
-     * @return <tt>true</tt> if this map contains a mapping for the specified key
+     * @return {@code true} if this map contains a mapping for the specified key
      * @throws ClassCastException if the specified key cannot be compared
      *         with the keys currently in the map
      * @throws NullPointerException if the specified key is null
@@ -1627,6 +1537,22 @@
     }
 
     /**
+     * Returns the value to which the specified key is mapped,
+     * or the given defaultValue if this map contains no mapping for the key.
+     *
+     * @param key the key
+     * @param defaultValue the value to return if this map contains
+     * no mapping for the given key
+     * @return the mapping for the key, if present; else the defaultValue
+     * @throws NullPointerException if the specified key is null
+     * @since 1.8
+     */
+    public V getOrDefault(Object key, V defaultValue) {
+        V v;
+        return (v = doGet(key)) == null ? defaultValue : v;
+    }
+
+    /**
      * Associates the specified value with the specified key in this map.
      * If the map previously contained a mapping for the key, the old
      * value is replaced.
@@ -1634,7 +1560,7 @@
      * @param key key with which the specified value is to be associated
      * @param value value to be associated with the specified key
      * @return the previous value associated with the specified key, or
-     *         <tt>null</tt> if there was no mapping for the key
+     *         {@code null} if there was no mapping for the key
      * @throws ClassCastException if the specified key cannot be compared
      *         with the keys currently in the map
      * @throws NullPointerException if the specified key or value is null
@@ -1650,7 +1576,7 @@
      *
      * @param  key key for which mapping should be removed
      * @return the previous value associated with the specified key, or
-     *         <tt>null</tt> if there was no mapping for the key
+     *         {@code null} if there was no mapping for the key
      * @throws ClassCastException if the specified key cannot be compared
      *         with the keys currently in the map
      * @throws NullPointerException if the specified key is null
@@ -1660,15 +1586,15 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this map maps one or more keys to the
+     * Returns {@code true} if this map maps one or more keys to the
      * specified value.  This operation requires time linear in the
      * map size. Additionally, it is possible for the map to change
      * during execution of this method, in which case the returned
      * result may be inaccurate.
      *
      * @param value value whose presence in this map is to be tested
-     * @return <tt>true</tt> if a mapping to <tt>value</tt> exists;
-     *         <tt>false</tt> otherwise
+     * @return {@code true} if a mapping to {@code value} exists;
+     *         {@code false} otherwise
      * @throws NullPointerException if the specified value is null
      */
     public boolean containsValue(Object value) {
@@ -1684,8 +1610,8 @@
 
     /**
      * Returns the number of key-value mappings in this map.  If this map
-     * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
-     * returns <tt>Integer.MAX_VALUE</tt>.
+     * contains more than {@code Integer.MAX_VALUE} elements, it
+     * returns {@code Integer.MAX_VALUE}.
      *
      * <p>Beware that, unlike in most collections, this method is
      * <em>NOT</em> a constant-time operation. Because of the
@@ -1708,8 +1634,8 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this map contains no key-value mappings.
-     * @return <tt>true</tt> if this map contains no key-value mappings
+     * Returns {@code true} if this map contains no key-value mappings.
+     * @return {@code true} if this map contains no key-value mappings
      */
     public boolean isEmpty() {
         return findFirst() == null;
@@ -1722,6 +1648,140 @@
         initialize();
     }
 
+    /**
+     * If the specified key is not already associated with a value,
+     * attempts to compute its value using the given mapping function
+     * and enters it into this map unless {@code null}.  The function
+     * is <em>NOT</em> guaranteed to be applied once atomically only
+     * if the value is not present.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param mappingFunction the function to compute a value
+     * @return the current (existing or computed) value associated with
+     *         the specified key, or null if the computed value is null
+     * @throws NullPointerException if the specified key is null
+     *         or the mappingFunction is null
+     * @since 1.8
+     */
+    public V computeIfAbsent(K key,
+                             Function<? super K, ? extends V> mappingFunction) {
+        if (key == null || mappingFunction == null)
+            throw new NullPointerException();
+        V v, p, r;
+        if ((v = doGet(key)) == null &&
+            (r = mappingFunction.apply(key)) != null)
+            v = (p = doPut(key, r, true)) == null ? r : p;
+        return v;
+    }
+
+    /**
+     * If the value for the specified key is present, attempts to
+     * compute a new mapping given the key and its current mapped
+     * value. The function is <em>NOT</em> guaranteed to be applied
+     * once atomically.
+     *
+     * @param key key with which a value may be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key is null
+     *         or the remappingFunction is null
+     * @since 1.8
+     */
+    public V computeIfPresent(K key,
+                              BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        Node<K,V> n; Object v;
+        while ((n = findNode(key)) != null) {
+            if ((v = n.value) != null) {
+                @SuppressWarnings("unchecked") V vv = (V) v;
+                V r = remappingFunction.apply(key, vv);
+                if (r != null) {
+                    if (n.casValue(vv, r))
+                        return r;
+                }
+                else if (doRemove(key, vv) != null)
+                    break;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Attempts to compute a mapping for the specified key and its
+     * current mapped value (or {@code null} if there is no current
+     * mapping). The function is <em>NOT</em> guaranteed to be applied
+     * once atomically.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key is null
+     *         or the remappingFunction is null
+     * @since 1.8
+     */
+    public V compute(K key,
+                     BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        for (;;) {
+            Node<K,V> n; Object v; V r;
+            if ((n = findNode(key)) == null) {
+                if ((r = remappingFunction.apply(key, null)) == null)
+                    break;
+                if (doPut(key, r, true) == null)
+                    return r;
+            }
+            else if ((v = n.value) != null) {
+                @SuppressWarnings("unchecked") V vv = (V) v;
+                if ((r = remappingFunction.apply(key, vv)) != null) {
+                    if (n.casValue(vv, r))
+                        return r;
+                }
+                else if (doRemove(key, vv) != null)
+                    break;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * If the specified key is not already associated with a value,
+     * associates it with the given value.  Otherwise, replaces the
+     * value with the results of the given remapping function, or
+     * removes if {@code null}. The function is <em>NOT</em>
+     * guaranteed to be applied once atomically.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param value the value to use if absent
+     * @param remappingFunction the function to recompute a value if present
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key or value is null
+     *         or the remappingFunction is null
+     * @since 1.8
+     */
+    public V merge(K key, V value,
+                   BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+        if (key == null || value == null || remappingFunction == null)
+            throw new NullPointerException();
+        for (;;) {
+            Node<K,V> n; Object v; V r;
+            if ((n = findNode(key)) == null) {
+                if (doPut(key, value, true) == null)
+                    return value;
+            }
+            else if ((v = n.value) != null) {
+                @SuppressWarnings("unchecked") V vv = (V) v;
+                if ((r = remappingFunction.apply(vv, value)) != null) {
+                    if (n.casValue(vv, r))
+                        return r;
+                }
+                else if (doRemove(key, vv) != null)
+                    return null;
+            }
+        }
+    }
+
     /* ---------------- View methods -------------- */
 
     /*
@@ -1744,11 +1804,11 @@
      * operations.  It does not support the {@code add} or {@code addAll}
      * operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException}, and guarantees to traverse elements
+     * as they existed upon construction of the iterator, and may (but is not
+     * guaranteed to) reflect any modifications subsequent to construction.
      *
      * <p>This method is equivalent to method {@code navigableKeySet}.
      *
@@ -1771,16 +1831,16 @@
      * The collection is backed by the map, so changes to the map are
      * reflected in the collection, and vice-versa.  The collection
      * supports element removal, which removes the corresponding
-     * mapping from the map, via the <tt>Iterator.remove</tt>,
-     * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
-     * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not
-     * support the <tt>add</tt> or <tt>addAll</tt> operations.
+     * mapping from the map, via the {@code Iterator.remove},
+     * {@code Collection.remove}, {@code removeAll},
+     * {@code retainAll} and {@code clear} operations.  It does not
+     * support the {@code add} or {@code addAll} operations.
      *
-     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException}, and guarantees to traverse elements
+     * as they existed upon construction of the iterator, and may (but is not
+     * guaranteed to) reflect any modifications subsequent to construction.
      */
     public Collection<V> values() {
         Values<V> vs = values;
@@ -1793,20 +1853,20 @@
      * The set is backed by the map, so changes to the map are
      * reflected in the set, and vice-versa.  The set supports element
      * removal, which removes the corresponding mapping from the map,
-     * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
-     * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt>
-     * operations.  It does not support the <tt>add</tt> or
-     * <tt>addAll</tt> operations.
+     * via the {@code Iterator.remove}, {@code Set.remove},
+     * {@code removeAll}, {@code retainAll} and {@code clear}
+     * operations.  It does not support the {@code add} or
+     * {@code addAll} operations.
      *
-     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException}, and guarantees to traverse elements
+     * as they existed upon construction of the iterator, and may (but is not
+     * guaranteed to) reflect any modifications subsequent to construction.
      *
-     * <p>The <tt>Map.Entry</tt> elements returned by
-     * <tt>iterator.next()</tt> do <em>not</em> support the
-     * <tt>setValue</tt> operation.
+     * <p>The {@code Map.Entry} elements returned by
+     * {@code iterator.next()} do <em>not</em> support the
+     * {@code setValue} operation.
      *
      * @return a set view of the mappings contained in this map,
      *         sorted in ascending key order
@@ -1830,15 +1890,15 @@
 
     /**
      * Compares the specified object with this map for equality.
-     * Returns <tt>true</tt> if the given object is also a map and the
+     * Returns {@code true} if the given object is also a map and the
      * two maps represent the same mappings.  More formally, two maps
-     * <tt>m1</tt> and <tt>m2</tt> represent the same mappings if
-     * <tt>m1.entrySet().equals(m2.entrySet())</tt>.  This
+     * {@code m1} and {@code m2} represent the same mappings if
+     * {@code m1.entrySet().equals(m2.entrySet())}.  This
      * operation may return misleading results if either map is
      * concurrently modified during execution of this method.
      *
      * @param o object to be compared for equality with this map
-     * @return <tt>true</tt> if the specified object is equal to this map
+     * @return {@code true} if the specified object is equal to this map
      */
     public boolean equals(Object o) {
         if (o == this)
@@ -1870,7 +1930,7 @@
      * {@inheritDoc}
      *
      * @return the previous value associated with the specified key,
-     *         or <tt>null</tt> if there was no mapping for the key
+     *         or {@code null} if there was no mapping for the key
      * @throws ClassCastException if the specified key cannot be compared
      *         with the keys currently in the map
      * @throws NullPointerException if the specified key or value is null
@@ -1891,9 +1951,7 @@
     public boolean remove(Object key, Object value) {
         if (key == null)
             throw new NullPointerException();
-        if (value == null)
-            return false;
-        return doRemove(key, value) != null;
+        return value != null && doRemove(key, value) != null;
     }
 
     /**
@@ -1904,15 +1962,13 @@
      * @throws NullPointerException if any of the arguments are null
      */
     public boolean replace(K key, V oldValue, V newValue) {
-        if (oldValue == null || newValue == null)
+        if (key == null || oldValue == null || newValue == null)
             throw new NullPointerException();
-        Comparable<? super K> k = comparable(key);
         for (;;) {
-            Node<K,V> n = findNode(k);
-            if (n == null)
+            Node<K,V> n; Object v;
+            if ((n = findNode(key)) == null)
                 return false;
-            Object v = n.value;
-            if (v != null) {
+            if ((v = n.value) != null) {
                 if (!oldValue.equals(v))
                     return false;
                 if (n.casValue(v, newValue))
@@ -1925,22 +1981,22 @@
      * {@inheritDoc}
      *
      * @return the previous value associated with the specified key,
-     *         or <tt>null</tt> if there was no mapping for the key
+     *         or {@code null} if there was no mapping for the key
      * @throws ClassCastException if the specified key cannot be compared
      *         with the keys currently in the map
      * @throws NullPointerException if the specified key or value is null
      */
     public V replace(K key, V value) {
-        if (value == null)
+        if (key == null || value == null)
             throw new NullPointerException();
-        Comparable<? super K> k = comparable(key);
         for (;;) {
-            Node<K,V> n = findNode(k);
-            if (n == null)
+            Node<K,V> n; Object v;
+            if ((n = findNode(key)) == null)
                 return null;
-            Object v = n.value;
-            if (v != null && n.casValue(v, value))
-                return (V)v;
+            if ((v = n.value) != null && n.casValue(v, value)) {
+                @SuppressWarnings("unchecked") V vv = (V)v;
+                return vv;
+            }
         }
     }
 
@@ -2042,9 +2098,9 @@
 
     /**
      * Returns a key-value mapping associated with the greatest key
-     * strictly less than the given key, or <tt>null</tt> if there is
+     * strictly less than the given key, or {@code null} if there is
      * no such key. The returned entry does <em>not</em> support the
-     * <tt>Entry.setValue</tt> method.
+     * {@code Entry.setValue} method.
      *
      * @throws ClassCastException {@inheritDoc}
      * @throws NullPointerException if the specified key is null
@@ -2058,15 +2114,15 @@
      * @throws NullPointerException if the specified key is null
      */
     public K lowerKey(K key) {
-        Node<K,V> n = findNear(key, LT);
+        Node<K,V> n = findNear(key, LT, comparator);
         return (n == null) ? null : n.key;
     }
 
     /**
      * Returns a key-value mapping associated with the greatest key
-     * less than or equal to the given key, or <tt>null</tt> if there
+     * less than or equal to the given key, or {@code null} if there
      * is no such key. The returned entry does <em>not</em> support
-     * the <tt>Entry.setValue</tt> method.
+     * the {@code Entry.setValue} method.
      *
      * @param key the key
      * @throws ClassCastException {@inheritDoc}
@@ -2082,15 +2138,15 @@
      * @throws NullPointerException if the specified key is null
      */
     public K floorKey(K key) {
-        Node<K,V> n = findNear(key, LT|EQ);
+        Node<K,V> n = findNear(key, LT|EQ, comparator);
         return (n == null) ? null : n.key;
     }
 
     /**
      * Returns a key-value mapping associated with the least key
-     * greater than or equal to the given key, or <tt>null</tt> if
+     * greater than or equal to the given key, or {@code null} if
      * there is no such entry. The returned entry does <em>not</em>
-     * support the <tt>Entry.setValue</tt> method.
+     * support the {@code Entry.setValue} method.
      *
      * @throws ClassCastException {@inheritDoc}
      * @throws NullPointerException if the specified key is null
@@ -2104,15 +2160,15 @@
      * @throws NullPointerException if the specified key is null
      */
     public K ceilingKey(K key) {
-        Node<K,V> n = findNear(key, GT|EQ);
+        Node<K,V> n = findNear(key, GT|EQ, comparator);
         return (n == null) ? null : n.key;
     }
 
     /**
      * Returns a key-value mapping associated with the least key
-     * strictly greater than the given key, or <tt>null</tt> if there
+     * strictly greater than the given key, or {@code null} if there
      * is no such key. The returned entry does <em>not</em> support
-     * the <tt>Entry.setValue</tt> method.
+     * the {@code Entry.setValue} method.
      *
      * @param key the key
      * @throws ClassCastException {@inheritDoc}
@@ -2128,15 +2184,15 @@
      * @throws NullPointerException if the specified key is null
      */
     public K higherKey(K key) {
-        Node<K,V> n = findNear(key, GT);
+        Node<K,V> n = findNear(key, GT, comparator);
         return (n == null) ? null : n.key;
     }
 
     /**
      * Returns a key-value mapping associated with the least
-     * key in this map, or <tt>null</tt> if the map is empty.
+     * key in this map, or {@code null} if the map is empty.
      * The returned entry does <em>not</em> support
-     * the <tt>Entry.setValue</tt> method.
+     * the {@code Entry.setValue} method.
      */
     public Map.Entry<K,V> firstEntry() {
         for (;;) {
@@ -2151,9 +2207,9 @@
 
     /**
      * Returns a key-value mapping associated with the greatest
-     * key in this map, or <tt>null</tt> if the map is empty.
+     * key in this map, or {@code null} if the map is empty.
      * The returned entry does <em>not</em> support
-     * the <tt>Entry.setValue</tt> method.
+     * the {@code Entry.setValue} method.
      */
     public Map.Entry<K,V> lastEntry() {
         for (;;) {
@@ -2168,9 +2224,9 @@
 
     /**
      * Removes and returns a key-value mapping associated with
-     * the least key in this map, or <tt>null</tt> if the map is empty.
+     * the least key in this map, or {@code null} if the map is empty.
      * The returned entry does <em>not</em> support
-     * the <tt>Entry.setValue</tt> method.
+     * the {@code Entry.setValue} method.
      */
     public Map.Entry<K,V> pollFirstEntry() {
         return doRemoveFirstEntry();
@@ -2178,9 +2234,9 @@
 
     /**
      * Removes and returns a key-value mapping associated with
-     * the greatest key in this map, or <tt>null</tt> if the map is empty.
+     * the greatest key in this map, or {@code null} if the map is empty.
      * The returned entry does <em>not</em> support
-     * the <tt>Entry.setValue</tt> method.
+     * the {@code Entry.setValue} method.
      */
     public Map.Entry<K,V> pollLastEntry() {
         return doRemoveLastEntry();
@@ -2202,13 +2258,11 @@
 
         /** Initializes ascending iterator for entire range. */
         Iter() {
-            for (;;) {
-                next = findFirst();
-                if (next == null)
-                    break;
+            while ((next = findFirst()) != null) {
                 Object x = next.value;
                 if (x != null && x != next) {
-                    nextValue = (V) x;
+                    @SuppressWarnings("unchecked") V vv = (V)x;
+                    nextValue = vv;
                     break;
                 }
             }
@@ -2223,13 +2277,11 @@
             if (next == null)
                 throw new NoSuchElementException();
             lastReturned = next;
-            for (;;) {
-                next = next.next;
-                if (next == null)
-                    break;
+            while ((next = next.next) != null) {
                 Object x = next.value;
                 if (x != null && x != next) {
-                    nextValue = (V) x;
+                    @SuppressWarnings("unchecked") V vv = (V)x;
+                    nextValue = vv;
                     break;
                 }
             }
@@ -2296,7 +2348,7 @@
 
     static final <E> List<E> toList(Collection<E> c) {
         // Using size() here would be a pessimization.
-        List<E> list = new ArrayList<E>();
+        ArrayList<E> list = new ArrayList<E>();
         for (E e : c)
             list.add(e);
         return list;
@@ -2304,7 +2356,7 @@
 
     static final class KeySet<E>
             extends AbstractSet<E> implements NavigableSet<E> {
-        private final ConcurrentNavigableMap<E,?> m;
+        final ConcurrentNavigableMap<E,?> m;
         KeySet(ConcurrentNavigableMap<E,?> map) { m = map; }
         public int size() { return m.size(); }
         public boolean isEmpty() { return m.isEmpty(); }
@@ -2326,6 +2378,7 @@
             Map.Entry<E,?> e = m.pollLastEntry();
             return (e == null) ? null : e.getKey();
         }
+        @SuppressWarnings("unchecked")
         public Iterator<E> iterator() {
             if (m instanceof ConcurrentSkipListMap)
                 return ((ConcurrentSkipListMap<E,Object>)m).keyIterator();
@@ -2376,13 +2429,21 @@
         public NavigableSet<E> descendingSet() {
             return new KeySet<E>(m.descendingMap());
         }
+        @SuppressWarnings("unchecked")
+        public Spliterator<E> spliterator() {
+            if (m instanceof ConcurrentSkipListMap)
+                return ((ConcurrentSkipListMap<E,?>)m).keySpliterator();
+            else
+                return (Spliterator<E>)((SubMap<E,?>)m).keyIterator();
+        }
     }
 
     static final class Values<E> extends AbstractCollection<E> {
-        private final ConcurrentNavigableMap<?, E> m;
+        final ConcurrentNavigableMap<?, E> m;
         Values(ConcurrentNavigableMap<?, E> map) {
             m = map;
         }
+        @SuppressWarnings("unchecked")
         public Iterator<E> iterator() {
             if (m instanceof ConcurrentSkipListMap)
                 return ((ConcurrentSkipListMap<?,E>)m).valueIterator();
@@ -2403,14 +2464,21 @@
         }
         public Object[] toArray()     { return toList(this).toArray();  }
         public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
+        @SuppressWarnings("unchecked")
+        public Spliterator<E> spliterator() {
+            if (m instanceof ConcurrentSkipListMap)
+                return ((ConcurrentSkipListMap<?,E>)m).valueSpliterator();
+            else
+                return (Spliterator<E>)((SubMap<?,E>)m).valueIterator();
+        }
     }
 
     static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> {
-        private final ConcurrentNavigableMap<K1, V1> m;
+        final ConcurrentNavigableMap<K1, V1> m;
         EntrySet(ConcurrentNavigableMap<K1, V1> map) {
             m = map;
         }
-
+        @SuppressWarnings("unchecked")
         public Iterator<Map.Entry<K1,V1>> iterator() {
             if (m instanceof ConcurrentSkipListMap)
                 return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator();
@@ -2457,6 +2525,14 @@
         }
         public Object[] toArray()     { return toList(this).toArray();  }
         public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
+        @SuppressWarnings("unchecked")
+        public Spliterator<Map.Entry<K1,V1>> spliterator() {
+            if (m instanceof ConcurrentSkipListMap)
+                return ((ConcurrentSkipListMap<K1,V1>)m).entrySpliterator();
+            else
+                return (Spliterator<Map.Entry<K1,V1>>)
+                    ((SubMap<K1,V1>)m).entryIterator();
+        }
     }
 
     /**
@@ -2466,8 +2542,8 @@
      * underlying maps, differing in that mappings outside their range are
      * ignored, and attempts to add mappings outside their ranges result
      * in {@link IllegalArgumentException}.  Instances of this class are
-     * constructed only using the <tt>subMap</tt>, <tt>headMap</tt>, and
-     * <tt>tailMap</tt> methods of their underlying maps.
+     * constructed only using the {@code subMap}, {@code headMap}, and
+     * {@code tailMap} methods of their underlying maps.
      *
      * @serial include
      */
@@ -2495,14 +2571,15 @@
         private transient Collection<V> valuesView;
 
         /**
-         * Creates a new submap, initializing all fields
+         * Creates a new submap, initializing all fields.
          */
         SubMap(ConcurrentSkipListMap<K,V> map,
                K fromKey, boolean fromInclusive,
                K toKey, boolean toInclusive,
                boolean isDescending) {
+            Comparator<? super K> cmp = map.comparator;
             if (fromKey != null && toKey != null &&
-                map.compare(fromKey, toKey) > 0)
+                cpr(cmp, fromKey, toKey) > 0)
                 throw new IllegalArgumentException("inconsistent range");
             this.m = map;
             this.lo = fromKey;
@@ -2514,39 +2591,34 @@
 
         /* ----------------  Utilities -------------- */
 
-        private boolean tooLow(K key) {
-            if (lo != null) {
-                int c = m.compare(key, lo);
-                if (c < 0 || (c == 0 && !loInclusive))
-                    return true;
-            }
-            return false;
+        boolean tooLow(Object key, Comparator<? super K> cmp) {
+            int c;
+            return (lo != null && ((c = cpr(cmp, key, lo)) < 0 ||
+                                   (c == 0 && !loInclusive)));
         }
 
-        private boolean tooHigh(K key) {
-            if (hi != null) {
-                int c = m.compare(key, hi);
-                if (c > 0 || (c == 0 && !hiInclusive))
-                    return true;
-            }
-            return false;
+        boolean tooHigh(Object key, Comparator<? super K> cmp) {
+            int c;
+            return (hi != null && ((c = cpr(cmp, key, hi)) > 0 ||
+                                   (c == 0 && !hiInclusive)));
         }
 
-        private boolean inBounds(K key) {
-            return !tooLow(key) && !tooHigh(key);
+        boolean inBounds(Object key, Comparator<? super K> cmp) {
+            return !tooLow(key, cmp) && !tooHigh(key, cmp);
         }
 
-        private void checkKeyBounds(K key) throws IllegalArgumentException {
+        void checkKeyBounds(K key, Comparator<? super K> cmp) {
             if (key == null)
                 throw new NullPointerException();
-            if (!inBounds(key))
+            if (!inBounds(key, cmp))
                 throw new IllegalArgumentException("key out of range");
         }
 
         /**
-         * Returns true if node key is less than upper bound of range
+         * Returns true if node key is less than upper bound of range.
          */
-        private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) {
+        boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n,
+                            Comparator<? super K> cmp) {
             if (n == null)
                 return false;
             if (hi == null)
@@ -2554,7 +2626,7 @@
             K k = n.key;
             if (k == null) // pass by markers and headers
                 return true;
-            int c = m.compare(k, hi);
+            int c = cpr(cmp, k, hi);
             if (c > 0 || (c == 0 && !hiInclusive))
                 return false;
             return true;
@@ -2562,58 +2634,61 @@
 
         /**
          * Returns lowest node. This node might not be in range, so
-         * most usages need to check bounds
+         * most usages need to check bounds.
          */
-        private ConcurrentSkipListMap.Node<K,V> loNode() {
+        ConcurrentSkipListMap.Node<K,V> loNode(Comparator<? super K> cmp) {
             if (lo == null)
                 return m.findFirst();
             else if (loInclusive)
-                return m.findNear(lo, GT|EQ);
+                return m.findNear(lo, GT|EQ, cmp);
             else
-                return m.findNear(lo, GT);
+                return m.findNear(lo, GT, cmp);
         }
 
         /**
          * Returns highest node. This node might not be in range, so
-         * most usages need to check bounds
+         * most usages need to check bounds.
          */
-        private ConcurrentSkipListMap.Node<K,V> hiNode() {
+        ConcurrentSkipListMap.Node<K,V> hiNode(Comparator<? super K> cmp) {
             if (hi == null)
                 return m.findLast();
             else if (hiInclusive)
-                return m.findNear(hi, LT|EQ);
+                return m.findNear(hi, LT|EQ, cmp);
             else
-                return m.findNear(hi, LT);
+                return m.findNear(hi, LT, cmp);
         }
 
         /**
-         * Returns lowest absolute key (ignoring directonality)
+         * Returns lowest absolute key (ignoring directonality).
          */
-        private K lowestKey() {
-            ConcurrentSkipListMap.Node<K,V> n = loNode();
-            if (isBeforeEnd(n))
+        K lowestKey() {
+            Comparator<? super K> cmp = m.comparator;
+            ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+            if (isBeforeEnd(n, cmp))
                 return n.key;
             else
                 throw new NoSuchElementException();
         }
 
         /**
-         * Returns highest absolute key (ignoring directonality)
+         * Returns highest absolute key (ignoring directonality).
          */
-        private K highestKey() {
-            ConcurrentSkipListMap.Node<K,V> n = hiNode();
+        K highestKey() {
+            Comparator<? super K> cmp = m.comparator;
+            ConcurrentSkipListMap.Node<K,V> n = hiNode(cmp);
             if (n != null) {
                 K last = n.key;
-                if (inBounds(last))
+                if (inBounds(last, cmp))
                     return last;
             }
             throw new NoSuchElementException();
         }
 
-        private Map.Entry<K,V> lowestEntry() {
+        Map.Entry<K,V> lowestEntry() {
+            Comparator<? super K> cmp = m.comparator;
             for (;;) {
-                ConcurrentSkipListMap.Node<K,V> n = loNode();
-                if (!isBeforeEnd(n))
+                ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                if (!isBeforeEnd(n, cmp))
                     return null;
                 Map.Entry<K,V> e = n.createSnapshot();
                 if (e != null)
@@ -2621,10 +2696,11 @@
             }
         }
 
-        private Map.Entry<K,V> highestEntry() {
+        Map.Entry<K,V> highestEntry() {
+            Comparator<? super K> cmp = m.comparator;
             for (;;) {
-                ConcurrentSkipListMap.Node<K,V> n = hiNode();
-                if (n == null || !inBounds(n.key))
+                ConcurrentSkipListMap.Node<K,V> n = hiNode(cmp);
+                if (n == null || !inBounds(n.key, cmp))
                     return null;
                 Map.Entry<K,V> e = n.createSnapshot();
                 if (e != null)
@@ -2632,13 +2708,14 @@
             }
         }
 
-        private Map.Entry<K,V> removeLowest() {
+        Map.Entry<K,V> removeLowest() {
+            Comparator<? super K> cmp = m.comparator;
             for (;;) {
-                Node<K,V> n = loNode();
+                Node<K,V> n = loNode(cmp);
                 if (n == null)
                     return null;
                 K k = n.key;
-                if (!inBounds(k))
+                if (!inBounds(k, cmp))
                     return null;
                 V v = m.doRemove(k, null);
                 if (v != null)
@@ -2646,13 +2723,14 @@
             }
         }
 
-        private Map.Entry<K,V> removeHighest() {
+        Map.Entry<K,V> removeHighest() {
+            Comparator<? super K> cmp = m.comparator;
             for (;;) {
-                Node<K,V> n = hiNode();
+                Node<K,V> n = hiNode(cmp);
                 if (n == null)
                     return null;
                 K k = n.key;
-                if (!inBounds(k))
+                if (!inBounds(k, cmp))
                     return null;
                 V v = m.doRemove(k, null);
                 if (v != null)
@@ -2663,20 +2741,21 @@
         /**
          * Submap version of ConcurrentSkipListMap.getNearEntry
          */
-        private Map.Entry<K,V> getNearEntry(K key, int rel) {
+        Map.Entry<K,V> getNearEntry(K key, int rel) {
+            Comparator<? super K> cmp = m.comparator;
             if (isDescending) { // adjust relation for direction
                 if ((rel & LT) == 0)
                     rel |= LT;
                 else
                     rel &= ~LT;
             }
-            if (tooLow(key))
+            if (tooLow(key, cmp))
                 return ((rel & LT) != 0) ? null : lowestEntry();
-            if (tooHigh(key))
+            if (tooHigh(key, cmp))
                 return ((rel & LT) != 0) ? highestEntry() : null;
             for (;;) {
-                Node<K,V> n = m.findNear(key, rel);
-                if (n == null || !inBounds(n.key))
+                Node<K,V> n = m.findNear(key, rel, cmp);
+                if (n == null || !inBounds(n.key, cmp))
                     return null;
                 K k = n.key;
                 V v = n.getValidValue();
@@ -2686,35 +2765,36 @@
         }
 
         // Almost the same as getNearEntry, except for keys
-        private K getNearKey(K key, int rel) {
+        K getNearKey(K key, int rel) {
+            Comparator<? super K> cmp = m.comparator;
             if (isDescending) { // adjust relation for direction
                 if ((rel & LT) == 0)
                     rel |= LT;
                 else
                     rel &= ~LT;
             }
-            if (tooLow(key)) {
+            if (tooLow(key, cmp)) {
                 if ((rel & LT) == 0) {
-                    ConcurrentSkipListMap.Node<K,V> n = loNode();
-                    if (isBeforeEnd(n))
+                    ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                    if (isBeforeEnd(n, cmp))
                         return n.key;
                 }
                 return null;
             }
-            if (tooHigh(key)) {
+            if (tooHigh(key, cmp)) {
                 if ((rel & LT) != 0) {
-                    ConcurrentSkipListMap.Node<K,V> n = hiNode();
+                    ConcurrentSkipListMap.Node<K,V> n = hiNode(cmp);
                     if (n != null) {
                         K last = n.key;
-                        if (inBounds(last))
+                        if (inBounds(last, cmp))
                             return last;
                     }
                 }
                 return null;
             }
             for (;;) {
-                Node<K,V> n = m.findNear(key, rel);
-                if (n == null || !inBounds(n.key))
+                Node<K,V> n = m.findNear(key, rel, cmp);
+                if (n == null || !inBounds(n.key, cmp))
                     return null;
                 K k = n.key;
                 V v = n.getValidValue();
@@ -2727,30 +2807,28 @@
 
         public boolean containsKey(Object key) {
             if (key == null) throw new NullPointerException();
-            K k = (K)key;
-            return inBounds(k) && m.containsKey(k);
+            return inBounds(key, m.comparator) && m.containsKey(key);
         }
 
         public V get(Object key) {
             if (key == null) throw new NullPointerException();
-            K k = (K)key;
-            return (!inBounds(k)) ? null : m.get(k);
+            return (!inBounds(key, m.comparator)) ? null : m.get(key);
         }
 
         public V put(K key, V value) {
-            checkKeyBounds(key);
+            checkKeyBounds(key, m.comparator);
             return m.put(key, value);
         }
 
         public V remove(Object key) {
-            K k = (K)key;
-            return (!inBounds(k)) ? null : m.remove(k);
+            return (!inBounds(key, m.comparator)) ? null : m.remove(key);
         }
 
         public int size() {
+            Comparator<? super K> cmp = m.comparator;
             long count = 0;
-            for (ConcurrentSkipListMap.Node<K,V> n = loNode();
-                 isBeforeEnd(n);
+            for (ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                 isBeforeEnd(n, cmp);
                  n = n.next) {
                 if (n.getValidValue() != null)
                     ++count;
@@ -2759,14 +2837,16 @@
         }
 
         public boolean isEmpty() {
-            return !isBeforeEnd(loNode());
+            Comparator<? super K> cmp = m.comparator;
+            return !isBeforeEnd(loNode(cmp), cmp);
         }
 
         public boolean containsValue(Object value) {
             if (value == null)
                 throw new NullPointerException();
-            for (ConcurrentSkipListMap.Node<K,V> n = loNode();
-                 isBeforeEnd(n);
+            Comparator<? super K> cmp = m.comparator;
+            for (ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                 isBeforeEnd(n, cmp);
                  n = n.next) {
                 V v = n.getValidValue();
                 if (v != null && value.equals(v))
@@ -2776,8 +2856,9 @@
         }
 
         public void clear() {
-            for (ConcurrentSkipListMap.Node<K,V> n = loNode();
-                 isBeforeEnd(n);
+            Comparator<? super K> cmp = m.comparator;
+            for (ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                 isBeforeEnd(n, cmp);
                  n = n.next) {
                 if (n.getValidValue() != null)
                     m.remove(n.key);
@@ -2787,22 +2868,21 @@
         /* ----------------  ConcurrentMap API methods -------------- */
 
         public V putIfAbsent(K key, V value) {
-            checkKeyBounds(key);
+            checkKeyBounds(key, m.comparator);
             return m.putIfAbsent(key, value);
         }
 
         public boolean remove(Object key, Object value) {
-            K k = (K)key;
-            return inBounds(k) && m.remove(k, value);
+            return inBounds(key, m.comparator) && m.remove(key, value);
         }
 
         public boolean replace(K key, V oldValue, V newValue) {
-            checkKeyBounds(key);
+            checkKeyBounds(key, m.comparator);
             return m.replace(key, oldValue, newValue);
         }
 
         public V replace(K key, V value) {
-            checkKeyBounds(key);
+            checkKeyBounds(key, m.comparator);
             return m.replace(key, value);
         }
 
@@ -2820,10 +2900,9 @@
          * Utility to create submaps, where given bounds override
          * unbounded(null) ones and/or are checked against bounded ones.
          */
-        private SubMap<K,V> newSubMap(K fromKey,
-                                      boolean fromInclusive,
-                                      K toKey,
-                                      boolean toInclusive) {
+        SubMap<K,V> newSubMap(K fromKey, boolean fromInclusive,
+                              K toKey, boolean toInclusive) {
+            Comparator<? super K> cmp = m.comparator;
             if (isDescending) { // flip senses
                 K tk = fromKey;
                 fromKey = toKey;
@@ -2838,7 +2917,7 @@
                     fromInclusive = loInclusive;
                 }
                 else {
-                    int c = m.compare(fromKey, lo);
+                    int c = cpr(cmp, fromKey, lo);
                     if (c < 0 || (c == 0 && !loInclusive && fromInclusive))
                         throw new IllegalArgumentException("key out of range");
                 }
@@ -2849,7 +2928,7 @@
                     toInclusive = hiInclusive;
                 }
                 else {
-                    int c = m.compare(toKey, hi);
+                    int c = cpr(cmp, toKey, hi);
                     if (c > 0 || (c == 0 && !hiInclusive && toInclusive))
                         throw new IllegalArgumentException("key out of range");
                 }
@@ -2858,24 +2937,20 @@
                                    toKey, toInclusive, isDescending);
         }
 
-        public SubMap<K,V> subMap(K fromKey,
-                                  boolean fromInclusive,
-                                  K toKey,
-                                  boolean toInclusive) {
+        public SubMap<K,V> subMap(K fromKey, boolean fromInclusive,
+                                  K toKey, boolean toInclusive) {
             if (fromKey == null || toKey == null)
                 throw new NullPointerException();
             return newSubMap(fromKey, fromInclusive, toKey, toInclusive);
         }
 
-        public SubMap<K,V> headMap(K toKey,
-                                   boolean inclusive) {
+        public SubMap<K,V> headMap(K toKey, boolean inclusive) {
             if (toKey == null)
                 throw new NullPointerException();
             return newSubMap(null, false, toKey, inclusive);
         }
 
-        public SubMap<K,V> tailMap(K fromKey,
-                                   boolean inclusive) {
+        public SubMap<K,V> tailMap(K fromKey, boolean inclusive) {
             if (fromKey == null)
                 throw new NullPointerException();
             return newSubMap(fromKey, inclusive, null, false);
@@ -2996,8 +3071,9 @@
 
         /**
          * Variant of main Iter class to traverse through submaps.
+         * Also serves as back-up Spliterator for views
          */
-        abstract class SubMapIter<T> implements Iterator<T> {
+        abstract class SubMapIter<T> implements Iterator<T>, Spliterator<T> {
             /** the last node returned by next() */
             Node<K,V> lastReturned;
             /** the next node to return from next(); */
@@ -3006,16 +3082,19 @@
             V nextValue;
 
             SubMapIter() {
+                Comparator<? super K> cmp = m.comparator;
                 for (;;) {
-                    next = isDescending ? hiNode() : loNode();
+                    next = isDescending ? hiNode(cmp) : loNode(cmp);
                     if (next == null)
                         break;
                     Object x = next.value;
                     if (x != null && x != next) {
-                        if (! inBounds(next.key))
+                        if (! inBounds(next.key, cmp))
                             next = null;
-                        else
-                            nextValue = (V) x;
+                        else {
+                            @SuppressWarnings("unchecked") V vv = (V)x;
+                            nextValue = vv;
+                        }
                         break;
                     }
                 }
@@ -3036,32 +3115,38 @@
             }
 
             private void ascend() {
+                Comparator<? super K> cmp = m.comparator;
                 for (;;) {
                     next = next.next;
                     if (next == null)
                         break;
                     Object x = next.value;
                     if (x != null && x != next) {
-                        if (tooHigh(next.key))
+                        if (tooHigh(next.key, cmp))
                             next = null;
-                        else
-                            nextValue = (V) x;
+                        else {
+                            @SuppressWarnings("unchecked") V vv = (V)x;
+                            nextValue = vv;
+                        }
                         break;
                     }
                 }
             }
 
             private void descend() {
+                Comparator<? super K> cmp = m.comparator;
                 for (;;) {
-                    next = m.findNear(lastReturned.key, LT);
+                    next = m.findNear(lastReturned.key, LT, cmp);
                     if (next == null)
                         break;
                     Object x = next.value;
                     if (x != null && x != next) {
-                        if (tooLow(next.key))
+                        if (tooLow(next.key, cmp))
                             next = null;
-                        else
-                            nextValue = (V) x;
+                        else {
+                            @SuppressWarnings("unchecked") V vv = (V)x;
+                            nextValue = vv;
+                        }
                         break;
                     }
                 }
@@ -3075,6 +3160,26 @@
                 lastReturned = null;
             }
 
+            public Spliterator<T> trySplit() {
+                return null;
+            }
+
+            public boolean tryAdvance(Consumer<? super T> action) {
+                if (hasNext()) {
+                    action.accept(next());
+                    return true;
+                }
+                return false;
+            }
+
+            public void forEachRemaining(Consumer<? super T> action) {
+                while (hasNext())
+                    action.accept(next());
+            }
+
+            public long estimateSize() {
+                return Long.MAX_VALUE;
+            }
         }
 
         final class SubMapValueIterator extends SubMapIter<V> {
@@ -3083,6 +3188,9 @@
                 advance();
                 return v;
             }
+            public int characteristics() {
+                return 0;
+            }
         }
 
         final class SubMapKeyIterator extends SubMapIter<K> {
@@ -3091,6 +3199,13 @@
                 advance();
                 return n.key;
             }
+            public int characteristics() {
+                return Spliterator.DISTINCT | Spliterator.ORDERED |
+                    Spliterator.SORTED;
+            }
+            public final Comparator<? super K> getComparator() {
+                return SubMap.this.comparator();
+            }
         }
 
         final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> {
@@ -3100,18 +3215,351 @@
                 advance();
                 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
             }
+            public int characteristics() {
+                return Spliterator.DISTINCT;
+            }
+        }
+    }
+
+    // default Map method overrides
+
+    public void forEach(BiConsumer<? super K, ? super V> action) {
+        if (action == null) throw new NullPointerException();
+        V v;
+        for (Node<K,V> n = findFirst(); n != null; n = n.next) {
+            if ((v = n.getValidValue()) != null)
+                action.accept(n.key, v);
+        }
+    }
+
+    public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
+        if (function == null) throw new NullPointerException();
+        V v;
+        for (Node<K,V> n = findFirst(); n != null; n = n.next) {
+            while ((v = n.getValidValue()) != null) {
+                V r = function.apply(n.key, v);
+                if (r == null) throw new NullPointerException();
+                if (n.casValue(v, r))
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Base class providing common structure for Spliterators.
+     * (Although not all that much common functionality; as usual for
+     * view classes, details annoyingly vary in key, value, and entry
+     * subclasses in ways that are not worth abstracting out for
+     * internal classes.)
+     *
+     * The basic split strategy is to recursively descend from top
+     * level, row by row, descending to next row when either split
+     * off, or the end of row is encountered. Control of the number of
+     * splits relies on some statistical estimation: The expected
+     * remaining number of elements of a skip list when advancing
+     * either across or down decreases by about 25%. To make this
+     * observation useful, we need to know initial size, which we
+     * don't. But we can just use Integer.MAX_VALUE so that we
+     * don't prematurely zero out while splitting.
+     */
+    abstract static class CSLMSpliterator<K,V> {
+        final Comparator<? super K> comparator;
+        final K fence;     // exclusive upper bound for keys, or null if to end
+        Index<K,V> row;    // the level to split out
+        Node<K,V> current; // current traversal node; initialize at origin
+        int est;           // pseudo-size estimate
+        CSLMSpliterator(Comparator<? super K> comparator, Index<K,V> row,
+                        Node<K,V> origin, K fence, int est) {
+            this.comparator = comparator; this.row = row;
+            this.current = origin; this.fence = fence; this.est = est;
+        }
+
+        public final long estimateSize() { return (long)est; }
+    }
+
+    static final class KeySpliterator<K,V> extends CSLMSpliterator<K,V>
+        implements Spliterator<K> {
+        KeySpliterator(Comparator<? super K> comparator, Index<K,V> row,
+                       Node<K,V> origin, K fence, int est) {
+            super(comparator, row, origin, fence, est);
+        }
+
+        public Spliterator<K> trySplit() {
+            Node<K,V> e; K ek;
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            if ((e = current) != null && (ek = e.key) != null) {
+                for (Index<K,V> q = row; q != null; q = row = q.down) {
+                    Index<K,V> s; Node<K,V> b, n; K sk;
+                    if ((s = q.right) != null && (b = s.node) != null &&
+                        (n = b.next) != null && n.value != null &&
+                        (sk = n.key) != null && cpr(cmp, sk, ek) > 0 &&
+                        (f == null || cpr(cmp, sk, f) < 0)) {
+                        current = n;
+                        Index<K,V> r = q.down;
+                        row = (s.right != null) ? s : s.down;
+                        est -= est >>> 2;
+                        return new KeySpliterator<K,V>(cmp, r, e, sk, est);
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super K> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            current = null;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0)
+                    break;
+                if ((v = e.value) != null && v != e)
+                    action.accept(k);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super K> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) {
+                    e = null;
+                    break;
+                }
+                if ((v = e.value) != null && v != e) {
+                    current = e.next;
+                    action.accept(k);
+                    return true;
+                }
+            }
+            current = e;
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.DISTINCT | Spliterator.SORTED |
+                Spliterator.ORDERED | Spliterator.CONCURRENT |
+                Spliterator.NONNULL;
+        }
+
+        public final Comparator<? super K> getComparator() {
+            return comparator;
+        }
+    }
+    // factory method for KeySpliterator
+    final KeySpliterator<K,V> keySpliterator() {
+        Comparator<? super K> cmp = comparator;
+        for (;;) { // ensure h corresponds to origin p
+            HeadIndex<K,V> h; Node<K,V> p;
+            Node<K,V> b = (h = head).node;
+            if ((p = b.next) == null || p.value != null)
+                return new KeySpliterator<K,V>(cmp, h, p, null, (p == null) ?
+                                               0 : Integer.MAX_VALUE);
+            p.helpDelete(b, p.next);
+        }
+    }
+
+    static final class ValueSpliterator<K,V> extends CSLMSpliterator<K,V>
+        implements Spliterator<V> {
+        ValueSpliterator(Comparator<? super K> comparator, Index<K,V> row,
+                       Node<K,V> origin, K fence, int est) {
+            super(comparator, row, origin, fence, est);
+        }
+
+        public Spliterator<V> trySplit() {
+            Node<K,V> e; K ek;
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            if ((e = current) != null && (ek = e.key) != null) {
+                for (Index<K,V> q = row; q != null; q = row = q.down) {
+                    Index<K,V> s; Node<K,V> b, n; K sk;
+                    if ((s = q.right) != null && (b = s.node) != null &&
+                        (n = b.next) != null && n.value != null &&
+                        (sk = n.key) != null && cpr(cmp, sk, ek) > 0 &&
+                        (f == null || cpr(cmp, sk, f) < 0)) {
+                        current = n;
+                        Index<K,V> r = q.down;
+                        row = (s.right != null) ? s : s.down;
+                        est -= est >>> 2;
+                        return new ValueSpliterator<K,V>(cmp, r, e, sk, est);
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super V> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            current = null;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0)
+                    break;
+                if ((v = e.value) != null && v != e) {
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    action.accept(vv);
+                }
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super V> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) {
+                    e = null;
+                    break;
+                }
+                if ((v = e.value) != null && v != e) {
+                    current = e.next;
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    action.accept(vv);
+                    return true;
+                }
+            }
+            current = e;
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.CONCURRENT | Spliterator.NONNULL;
+        }
+    }
+
+    // Almost the same as keySpliterator()
+    final ValueSpliterator<K,V> valueSpliterator() {
+        Comparator<? super K> cmp = comparator;
+        for (;;) {
+            HeadIndex<K,V> h; Node<K,V> p;
+            Node<K,V> b = (h = head).node;
+            if ((p = b.next) == null || p.value != null)
+                return new ValueSpliterator<K,V>(cmp, h, p, null, (p == null) ?
+                                                 0 : Integer.MAX_VALUE);
+            p.helpDelete(b, p.next);
+        }
+    }
+
+    static final class EntrySpliterator<K,V> extends CSLMSpliterator<K,V>
+        implements Spliterator<Map.Entry<K,V>> {
+        EntrySpliterator(Comparator<? super K> comparator, Index<K,V> row,
+                         Node<K,V> origin, K fence, int est) {
+            super(comparator, row, origin, fence, est);
+        }
+
+        public Spliterator<Map.Entry<K,V>> trySplit() {
+            Node<K,V> e; K ek;
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            if ((e = current) != null && (ek = e.key) != null) {
+                for (Index<K,V> q = row; q != null; q = row = q.down) {
+                    Index<K,V> s; Node<K,V> b, n; K sk;
+                    if ((s = q.right) != null && (b = s.node) != null &&
+                        (n = b.next) != null && n.value != null &&
+                        (sk = n.key) != null && cpr(cmp, sk, ek) > 0 &&
+                        (f == null || cpr(cmp, sk, f) < 0)) {
+                        current = n;
+                        Index<K,V> r = q.down;
+                        row = (s.right != null) ? s : s.down;
+                        est -= est >>> 2;
+                        return new EntrySpliterator<K,V>(cmp, r, e, sk, est);
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super Map.Entry<K,V>> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            current = null;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0)
+                    break;
+                if ((v = e.value) != null && v != e) {
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    action.accept
+                        (new AbstractMap.SimpleImmutableEntry<K,V>(k, vv));
+                }
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) {
+                    e = null;
+                    break;
+                }
+                if ((v = e.value) != null && v != e) {
+                    current = e.next;
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    action.accept
+                        (new AbstractMap.SimpleImmutableEntry<K,V>(k, vv));
+                    return true;
+                }
+            }
+            current = e;
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.DISTINCT | Spliterator.SORTED |
+                Spliterator.ORDERED | Spliterator.CONCURRENT |
+                Spliterator.NONNULL;
+        }
+
+        public final Comparator<Map.Entry<K,V>> getComparator() {
+            return comparator == null ? null :
+                Map.Entry.comparingByKey(comparator);
+        }
+    }
+
+    // Almost the same as keySpliterator()
+    final EntrySpliterator<K,V> entrySpliterator() {
+        Comparator<? super K> cmp = comparator;
+        for (;;) { // almost same as key version
+            HeadIndex<K,V> h; Node<K,V> p;
+            Node<K,V> b = (h = head).node;
+            if ((p = b.next) == null || p.value != null)
+                return new EntrySpliterator<K,V>(cmp, h, p, null, (p == null) ?
+                                                 0 : Integer.MAX_VALUE);
+            p.helpDelete(b, p.next);
         }
     }
 
     // Unsafe mechanics
     private static final sun.misc.Unsafe UNSAFE;
     private static final long headOffset;
+    private static final long SECONDARY;
     static {
         try {
             UNSAFE = sun.misc.Unsafe.getUnsafe();
             Class<?> k = ConcurrentSkipListMap.class;
             headOffset = UNSAFE.objectFieldOffset
                 (k.getDeclaredField("head"));
+            Class<?> tk = Thread.class;
+            SECONDARY = UNSAFE.objectFieldOffset
+                (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
+
         } catch (Exception e) {
             throw new Error(e);
         }
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java	Wed Jul 03 14:35:10 2013 -0700
@@ -34,7 +34,17 @@
  */
 
 package java.util.concurrent;
-import java.util.*;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.Spliterator;
 
 /**
  * A scalable concurrent {@link NavigableSet} implementation based on
@@ -44,33 +54,33 @@
  * on which constructor is used.
  *
  * <p>This implementation provides expected average <i>log(n)</i> time
- * cost for the <tt>contains</tt>, <tt>add</tt>, and <tt>remove</tt>
+ * cost for the {@code contains}, {@code add}, and {@code remove}
  * operations and their variants.  Insertion, removal, and access
  * operations safely execute concurrently by multiple threads.
  * Iterators are <i>weakly consistent</i>, returning elements
  * reflecting the state of the set at some point at or since the
  * creation of the iterator.  They do <em>not</em> throw {@link
- * ConcurrentModificationException}, and may proceed concurrently with
- * other operations.  Ascending ordered views and their iterators are
- * faster than descending ones.
+ * java.util.ConcurrentModificationException}, and may proceed
+ * concurrently with other operations.  Ascending ordered views and
+ * their iterators are faster than descending ones.
  *
- * <p>Beware that, unlike in most collections, the <tt>size</tt>
+ * <p>Beware that, unlike in most collections, the {@code size}
  * method is <em>not</em> a constant-time operation. Because of the
  * asynchronous nature of these sets, determining the current number
  * of elements requires a traversal of the elements, and so may report
  * inaccurate results if this collection is modified during traversal.
- * Additionally, the bulk operations <tt>addAll</tt>,
- * <tt>removeAll</tt>, <tt>retainAll</tt>, <tt>containsAll</tt>,
- * <tt>equals</tt>, and <tt>toArray</tt> are <em>not</em> guaranteed
+ * Additionally, the bulk operations {@code addAll},
+ * {@code removeAll}, {@code retainAll}, {@code containsAll},
+ * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
  * to be performed atomically. For example, an iterator operating
- * concurrently with an <tt>addAll</tt> operation might view only some
+ * concurrently with an {@code addAll} operation might view only some
  * of the added elements.
  *
  * <p>This class and its iterators implement all of the
  * <em>optional</em> methods of the {@link Set} and {@link Iterator}
  * interfaces. Like most other concurrent collection implementations,
- * this class does not permit the use of <tt>null</tt> elements,
- * because <tt>null</tt> arguments and return values cannot be reliably
+ * this class does not permit the use of {@code null} elements,
+ * because {@code null} arguments and return values cannot be reliably
  * distinguished from the absence of elements.
  *
  * <p>This class is a member of the
@@ -90,7 +100,7 @@
     /**
      * The underlying map. Uses Boolean.TRUE as value for each
      * element.  This field is declared final for the sake of thread
-     * safety, which entails some ugliness in clone()
+     * safety, which entails some ugliness in clone().
      */
     private final ConcurrentNavigableMap<E,Object> m;
 
@@ -107,7 +117,7 @@
      * the specified comparator.
      *
      * @param comparator the comparator that will be used to order this set.
-     *        If <tt>null</tt>, the {@linkplain Comparable natural
+     *        If {@code null}, the {@linkplain Comparable natural
      *        ordering} of the elements will be used.
      */
     public ConcurrentSkipListSet(Comparator<? super E> comparator) {
@@ -120,7 +130,7 @@
      * {@linkplain Comparable natural ordering}.
      *
      * @param c The elements that will comprise the new set
-     * @throws ClassCastException if the elements in <tt>c</tt> are
+     * @throws ClassCastException if the elements in {@code c} are
      *         not {@link Comparable}, or are not mutually comparable
      * @throws NullPointerException if the specified collection or any
      *         of its elements are null
@@ -151,7 +161,7 @@
     }
 
     /**
-     * Returns a shallow copy of this <tt>ConcurrentSkipListSet</tt>
+     * Returns a shallow copy of this {@code ConcurrentSkipListSet}
      * instance. (The elements themselves are not cloned.)
      *
      * @return a shallow copy of this set
@@ -172,8 +182,8 @@
 
     /**
      * Returns the number of elements in this set.  If this set
-     * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
-     * returns <tt>Integer.MAX_VALUE</tt>.
+     * contains more than {@code Integer.MAX_VALUE} elements, it
+     * returns {@code Integer.MAX_VALUE}.
      *
      * <p>Beware that, unlike in most collections, this method is
      * <em>NOT</em> a constant-time operation. Because of the
@@ -191,20 +201,20 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this set contains no elements.
-     * @return <tt>true</tt> if this set contains no elements
+     * Returns {@code true} if this set contains no elements.
+     * @return {@code true} if this set contains no elements
      */
     public boolean isEmpty() {
         return m.isEmpty();
     }
 
     /**
-     * Returns <tt>true</tt> if this set contains the specified element.
-     * More formally, returns <tt>true</tt> if and only if this set
-     * contains an element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+     * Returns {@code true} if this set contains the specified element.
+     * More formally, returns {@code true} if and only if this set
+     * contains an element {@code e} such that {@code o.equals(e)}.
      *
      * @param o object to be checked for containment in this set
-     * @return <tt>true</tt> if this set contains the specified element
+     * @return {@code true} if this set contains the specified element
      * @throws ClassCastException if the specified element cannot be
      *         compared with the elements currently in this set
      * @throws NullPointerException if the specified element is null
@@ -215,15 +225,15 @@
 
     /**
      * Adds the specified element to this set if it is not already present.
-     * More formally, adds the specified element <tt>e</tt> to this set if
-     * the set contains no element <tt>e2</tt> such that <tt>e.equals(e2)</tt>.
+     * More formally, adds the specified element {@code e} to this set if
+     * the set contains no element {@code e2} such that {@code e.equals(e2)}.
      * If this set already contains the element, the call leaves the set
-     * unchanged and returns <tt>false</tt>.
+     * unchanged and returns {@code false}.
      *
      * @param e element to be added to this set
-     * @return <tt>true</tt> if this set did not already contain the
+     * @return {@code true} if this set did not already contain the
      *         specified element
-     * @throws ClassCastException if <tt>e</tt> cannot be compared
+     * @throws ClassCastException if {@code e} cannot be compared
      *         with the elements currently in this set
      * @throws NullPointerException if the specified element is null
      */
@@ -233,15 +243,15 @@
 
     /**
      * Removes the specified element from this set if it is present.
-     * More formally, removes an element <tt>e</tt> such that
-     * <tt>o.equals(e)</tt>, if this set contains such an element.
-     * Returns <tt>true</tt> if this set contained the element (or
+     * More formally, removes an element {@code e} such that
+     * {@code o.equals(e)}, if this set contains such an element.
+     * Returns {@code true} if this set contained the element (or
      * equivalently, if this set changed as a result of the call).
      * (This set will not contain the element once the call returns.)
      *
      * @param o object to be removed from this set, if present
-     * @return <tt>true</tt> if this set contained the specified element
-     * @throws ClassCastException if <tt>o</tt> cannot be compared
+     * @return {@code true} if this set contained the specified element
+     * @throws ClassCastException if {@code o} cannot be compared
      *         with the elements currently in this set
      * @throws NullPointerException if the specified element is null
      */
@@ -279,7 +289,7 @@
 
     /**
      * Compares the specified object with this set for equality.  Returns
-     * <tt>true</tt> if the specified object is also a set, the two sets
+     * {@code true} if the specified object is also a set, the two sets
      * have the same size, and every member of the specified set is
      * contained in this set (or equivalently, every member of this set is
      * contained in the specified set).  This definition ensures that the
@@ -287,7 +297,7 @@
      * set interface.
      *
      * @param o the object to be compared for equality with this set
-     * @return <tt>true</tt> if the specified object is equal to this set
+     * @return {@code true} if the specified object is equal to this set
      */
     public boolean equals(Object o) {
         // Override AbstractSet version to avoid calling size()
@@ -312,7 +322,7 @@
      * value is the <i>asymmetric set difference</i> of the two sets.
      *
      * @param  c collection containing elements to be removed from this set
-     * @return <tt>true</tt> if this set changed as a result of the call
+     * @return {@code true} if this set changed as a result of the call
      * @throws ClassCastException if the types of one or more elements in this
      *         set are incompatible with the specified collection
      * @throws NullPointerException if the specified collection or any
@@ -380,14 +390,14 @@
     }
 
     /**
-     * @throws NoSuchElementException {@inheritDoc}
+     * @throws java.util.NoSuchElementException {@inheritDoc}
      */
     public E first() {
         return m.firstKey();
     }
 
     /**
-     * @throws NoSuchElementException {@inheritDoc}
+     * @throws java.util.NoSuchElementException {@inheritDoc}
      */
     public E last() {
         return m.lastKey();
@@ -460,7 +470,7 @@
      * reflected in the descending set, and vice-versa.
      *
      * <p>The returned set has an ordering equivalent to
-     * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
+     * {@link Collections#reverseOrder(Comparator) Collections.reverseOrder}{@code (comparator())}.
      * The expression {@code s.descendingSet().descendingSet()} returns a
      * view of {@code s} essentially equivalent to {@code s}.
      *
@@ -470,6 +480,14 @@
         return new ConcurrentSkipListSet<E>(m.descendingMap());
     }
 
+    @SuppressWarnings("unchecked")
+    public Spliterator<E> spliterator() {
+        if (m instanceof ConcurrentSkipListMap)
+            return ((ConcurrentSkipListMap<E,?>)m).keySpliterator();
+        else
+            return (Spliterator<E>)((ConcurrentSkipListMap.SubMap<E,?>)m).keyIterator();
+    }
+
     // Support for resetting map in clone
     private void setMap(ConcurrentNavigableMap<E,Object> map) {
         UNSAFE.putObjectVolatile(this, mapOffset, map);
--- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,4 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +33,19 @@
  */
 
 package java.util.concurrent;
-import java.util.*;
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.RandomAccess;
+import java.util.Spliterator;
+import java.util.Spliterators;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
@@ -42,10 +53,10 @@
 
 /**
  * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
- * operations (<tt>add</tt>, <tt>set</tt>, and so on) are implemented by
+ * operations ({@code add}, {@code set}, and so on) are implemented by
  * making a fresh copy of the underlying array.
  *
- * <p> This is ordinarily too costly, but may be <em>more</em> efficient
+ * <p>This is ordinarily too costly, but may be <em>more</em> efficient
  * than alternatives when traversal operations vastly outnumber
  * mutations, and is useful when you cannot or don't want to
  * synchronize traversals, yet need to preclude interference among
@@ -53,14 +64,14 @@
  * reference to the state of the array at the point that the iterator
  * was created. This array never changes during the lifetime of the
  * iterator, so interference is impossible and the iterator is
- * guaranteed not to throw <tt>ConcurrentModificationException</tt>.
+ * guaranteed not to throw {@code ConcurrentModificationException}.
  * The iterator will not reflect additions, removals, or changes to
  * the list since the iterator was created.  Element-changing
- * operations on iterators themselves (<tt>remove</tt>, <tt>set</tt>, and
- * <tt>add</tt>) are not supported. These methods throw
- * <tt>UnsupportedOperationException</tt>.
+ * operations on iterators themselves ({@code remove}, {@code set}, and
+ * {@code add}) are not supported. These methods throw
+ * {@code UnsupportedOperationException}.
  *
- * <p>All elements are permitted, including <tt>null</tt>.
+ * <p>All elements are permitted, including {@code null}.
  *
  * <p>Memory consistency effects: As with other concurrent
  * collections, actions in a thread prior to placing an object into a
@@ -82,10 +93,10 @@
     private static final long serialVersionUID = 8673264195747942595L;
 
     /** The lock protecting all mutators */
-    transient final ReentrantLock lock = new ReentrantLock();
+    final transient ReentrantLock lock = new ReentrantLock();
 
     /** The array, accessed only via getArray/setArray. */
-    private volatile transient Object[] array;
+    private transient volatile Object[] array;
 
     /**
      * Gets the array.  Non-private so as to also be accessible
@@ -118,10 +129,15 @@
      * @throws NullPointerException if the specified collection is null
      */
     public CopyOnWriteArrayList(Collection<? extends E> c) {
-        Object[] elements = c.toArray();
-        // c.toArray might (incorrectly) not return Object[] (see 6260652)
-        if (elements.getClass() != Object[].class)
-            elements = Arrays.copyOf(elements, elements.length, Object[].class);
+        Object[] elements;
+        if (c.getClass() == CopyOnWriteArrayList.class)
+            elements = ((CopyOnWriteArrayList<?>)c).getArray();
+        else {
+            elements = c.toArray();
+            // c.toArray might (incorrectly) not return Object[] (see 6260652)
+            if (elements.getClass() != Object[].class)
+                elements = Arrays.copyOf(elements, elements.length, Object[].class);
+        }
         setArray(elements);
     }
 
@@ -146,9 +162,9 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this list contains no elements.
+     * Returns {@code true} if this list contains no elements.
      *
-     * @return <tt>true</tt> if this list contains no elements
+     * @return {@code true} if this list contains no elements
      */
     public boolean isEmpty() {
         return size() == 0;
@@ -158,7 +174,7 @@
      * Tests for equality, coping with nulls.
      */
     private static boolean eq(Object o1, Object o2) {
-        return (o1 == null ? o2 == null : o1.equals(o2));
+        return (o1 == null) ? o2 == null : o1.equals(o2);
     }
 
     /**
@@ -205,13 +221,13 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this list contains the specified element.
-     * More formally, returns <tt>true</tt> if and only if this list contains
-     * at least one element <tt>e</tt> such that
+     * Returns {@code true} if this list contains the specified element.
+     * More formally, returns {@code true} if and only if this list contains
+     * at least one element {@code e} such that
      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
      *
      * @param o element whose presence in this list is to be tested
-     * @return <tt>true</tt> if this list contains the specified element
+     * @return {@code true} if this list contains the specified element
      */
     public boolean contains(Object o) {
         Object[] elements = getArray();
@@ -228,17 +244,17 @@
 
     /**
      * Returns the index of the first occurrence of the specified element in
-     * this list, searching forwards from <tt>index</tt>, or returns -1 if
+     * this list, searching forwards from {@code index}, or returns -1 if
      * the element is not found.
-     * More formally, returns the lowest index <tt>i</tt> such that
+     * More formally, returns the lowest index {@code i} such that
      * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
      * or -1 if there is no such index.
      *
      * @param e element to search for
      * @param index index to start searching from
      * @return the index of the first occurrence of the element in
-     *         this list at position <tt>index</tt> or later in the list;
-     *         <tt>-1</tt> if the element is not found.
+     *         this list at position {@code index} or later in the list;
+     *         {@code -1} if the element is not found.
      * @throws IndexOutOfBoundsException if the specified index is negative
      */
     public int indexOf(E e, int index) {
@@ -256,16 +272,16 @@
 
     /**
      * Returns the index of the last occurrence of the specified element in
-     * this list, searching backwards from <tt>index</tt>, or returns -1 if
+     * this list, searching backwards from {@code index}, or returns -1 if
      * the element is not found.
-     * More formally, returns the highest index <tt>i</tt> such that
+     * More formally, returns the highest index {@code i} such that
      * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
      * or -1 if there is no such index.
      *
      * @param e element to search for
      * @param index index to start searching backwards from
      * @return the index of the last occurrence of the element at position
-     *         less than or equal to <tt>index</tt> in this list;
+     *         less than or equal to {@code index} in this list;
      *         -1 if the element is not found.
      * @throws IndexOutOfBoundsException if the specified index is greater
      *         than or equal to the current size of this list
@@ -323,7 +339,7 @@
      * <p>If this list fits in the specified array with room to spare
      * (i.e., the array has more elements than this list), the element in
      * the array immediately following the end of the list is set to
-     * <tt>null</tt>.  (This is useful in determining the length of this
+     * {@code null}.  (This is useful in determining the length of this
      * list <i>only</i> if the caller knows that this list does not contain
      * any null elements.)
      *
@@ -332,14 +348,14 @@
      * precise control over the runtime type of the output array, and may,
      * under certain circumstances, be used to save allocation costs.
      *
-     * <p>Suppose <tt>x</tt> is a list known to contain only strings.
+     * <p>Suppose {@code x} is a list known to contain only strings.
      * The following code can be used to dump the list into a newly
-     * allocated array of <tt>String</tt>:
+     * allocated array of {@code String}:
      *
      *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
-     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
-     * <tt>toArray()</tt>.
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
      *
      * @param a the array into which the elements of the list are to
      *          be stored, if it is big enough; otherwise, a new array of the
@@ -412,7 +428,7 @@
      * Appends the specified element to the end of this list.
      *
      * @param e element to be appended to this list
-     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     * @return {@code true} (as specified by {@link Collection#add})
      */
     public boolean add(E e) {
         final ReentrantLock lock = this.lock;
@@ -496,45 +512,54 @@
      * Removes the first occurrence of the specified element from this list,
      * if it is present.  If this list does not contain the element, it is
      * unchanged.  More formally, removes the element with the lowest index
-     * <tt>i</tt> such that
+     * {@code i} such that
      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
-     * (if such an element exists).  Returns <tt>true</tt> if this list
+     * (if such an element exists).  Returns {@code true} if this list
      * contained the specified element (or equivalently, if this list
      * changed as a result of the call).
      *
      * @param o element to be removed from this list, if present
-     * @return <tt>true</tt> if this list contained the specified element
+     * @return {@code true} if this list contained the specified element
      */
     public boolean remove(Object o) {
+        Object[] snapshot = getArray();
+        int index = indexOf(o, snapshot, 0, snapshot.length);
+        return (index < 0) ? false : remove(o, snapshot, index);
+    }
+
+    /**
+     * A version of remove(Object) using the strong hint that given
+     * recent snapshot contains o at the given index.
+     */
+    private boolean remove(Object o, Object[] snapshot, int index) {
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            Object[] elements = getArray();
-            int len = elements.length;
-            if (len != 0) {
-                // Copy while searching for element to remove
-                // This wins in the normal case of element being present
-                int newlen = len - 1;
-                Object[] newElements = new Object[newlen];
-
-                for (int i = 0; i < newlen; ++i) {
-                    if (eq(o, elements[i])) {
-                        // found one;  copy remaining and exit
-                        for (int k = i + 1; k < len; ++k)
-                            newElements[k-1] = elements[k];
-                        setArray(newElements);
-                        return true;
-                    } else
-                        newElements[i] = elements[i];
+            Object[] current = getArray();
+            int len = current.length;
+            if (snapshot != current) findIndex: {
+                int prefix = Math.min(index, len);
+                for (int i = 0; i < prefix; i++) {
+                    if (current[i] != snapshot[i] && eq(o, current[i])) {
+                        index = i;
+                        break findIndex;
+                    }
                 }
-
-                // special handling for last cell
-                if (eq(o, elements[newlen])) {
-                    setArray(newElements);
-                    return true;
-                }
+                if (index >= len)
+                    return false;
+                if (current[index] == o)
+                    break findIndex;
+                index = indexOf(o, current, index, len);
+                if (index < 0)
+                    return false;
             }
-            return false;
+            Object[] newElements = new Object[len - 1];
+            System.arraycopy(current, 0, newElements, 0, index);
+            System.arraycopy(current, index + 1,
+                             newElements, index,
+                             len - index - 1);
+            setArray(newElements);
+            return true;
         } finally {
             lock.unlock();
         }
@@ -542,10 +567,10 @@
 
     /**
      * Removes from this list all of the elements whose index is between
-     * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
+     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
      * Shifts any succeeding elements to the left (reduces their index).
-     * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements.
-     * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.)
+     * This call shortens the list by {@code (toIndex - fromIndex)} elements.
+     * (If {@code toIndex==fromIndex}, this operation has no effect.)
      *
      * @param fromIndex index of first element to be removed
      * @param toIndex index after last element to be removed
@@ -581,23 +606,34 @@
      * Appends the element, if not present.
      *
      * @param e element to be added to this list, if absent
-     * @return <tt>true</tt> if the element was added
+     * @return {@code true} if the element was added
      */
     public boolean addIfAbsent(E e) {
+        Object[] snapshot = getArray();
+        return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
+            addIfAbsent(e, snapshot);
+    }
+
+    /**
+     * A version of addIfAbsent using the strong hint that given
+     * recent snapshot does not contain e.
+     */
+    private boolean addIfAbsent(E e, Object[] snapshot) {
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            // Copy while checking if already present.
-            // This wins in the most common case where it is not present
-            Object[] elements = getArray();
-            int len = elements.length;
-            Object[] newElements = new Object[len + 1];
-            for (int i = 0; i < len; ++i) {
-                if (eq(e, elements[i]))
-                    return false; // exit, throwing away copy
-                else
-                    newElements[i] = elements[i];
+            Object[] current = getArray();
+            int len = current.length;
+            if (snapshot != current) {
+                // Optimize for lost race to another addXXX operation
+                int common = Math.min(snapshot.length, len);
+                for (int i = 0; i < common; i++)
+                    if (current[i] != snapshot[i] && eq(e, current[i]))
+                        return false;
+                if (indexOf(e, current, common, len) >= 0)
+                        return false;
             }
+            Object[] newElements = Arrays.copyOf(current, len + 1);
             newElements[len] = e;
             setArray(newElements);
             return true;
@@ -607,11 +643,11 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this list contains all of the elements of the
+     * Returns {@code true} if this list contains all of the elements of the
      * specified collection.
      *
      * @param c collection to be checked for containment in this list
-     * @return <tt>true</tt> if this list contains all of the elements of the
+     * @return {@code true} if this list contains all of the elements of the
      *         specified collection
      * @throws NullPointerException if the specified collection is null
      * @see #contains(Object)
@@ -632,7 +668,7 @@
      * in this class because of the need for an internal temporary array.
      *
      * @param c collection containing elements to be removed from this list
-     * @return <tt>true</tt> if this list changed as a result of the call
+     * @return {@code true} if this list changed as a result of the call
      * @throws ClassCastException if the class of an element of this list
      *         is incompatible with the specified collection
      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
@@ -675,7 +711,7 @@
      * its elements that are not contained in the specified collection.
      *
      * @param c collection containing elements to be retained in this list
-     * @return <tt>true</tt> if this list changed as a result of the call
+     * @return {@code true} if this list changed as a result of the call
      * @throws ClassCastException if the class of an element of this list
      *         is incompatible with the specified collection
      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
@@ -727,22 +763,22 @@
         Object[] cs = c.toArray();
         if (cs.length == 0)
             return 0;
-        Object[] uniq = new Object[cs.length];
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
             Object[] elements = getArray();
             int len = elements.length;
             int added = 0;
-            for (int i = 0; i < cs.length; ++i) { // scan for duplicates
+            // uniquify and compact elements in cs
+            for (int i = 0; i < cs.length; ++i) {
                 Object e = cs[i];
                 if (indexOf(e, elements, 0, len) < 0 &&
-                    indexOf(e, uniq, 0, added) < 0)
-                    uniq[added++] = e;
+                    indexOf(e, cs, 0, added) < 0)
+                    cs[added++] = e;
             }
             if (added > 0) {
                 Object[] newElements = Arrays.copyOf(elements, len + added);
-                System.arraycopy(uniq, 0, newElements, len, added);
+                System.arraycopy(cs, 0, newElements, len, added);
                 setArray(newElements);
             }
             return added;
@@ -771,12 +807,13 @@
      * collection's iterator.
      *
      * @param c collection containing elements to be added to this list
-     * @return <tt>true</tt> if this list changed as a result of the call
+     * @return {@code true} if this list changed as a result of the call
      * @throws NullPointerException if the specified collection is null
      * @see #add(Object)
      */
     public boolean addAll(Collection<? extends E> c) {
-        Object[] cs = c.toArray();
+        Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ?
+            ((CopyOnWriteArrayList<?>)c).getArray() : c.toArray();
         if (cs.length == 0)
             return false;
         final ReentrantLock lock = this.lock;
@@ -784,9 +821,13 @@
         try {
             Object[] elements = getArray();
             int len = elements.length;
-            Object[] newElements = Arrays.copyOf(elements, len + cs.length);
-            System.arraycopy(cs, 0, newElements, len, cs.length);
-            setArray(newElements);
+            if (len == 0 && cs.getClass() == Object[].class)
+                setArray(cs);
+            else {
+                Object[] newElements = Arrays.copyOf(elements, len + cs.length);
+                System.arraycopy(cs, 0, newElements, len, cs.length);
+                setArray(newElements);
+            }
             return true;
         } finally {
             lock.unlock();
@@ -804,7 +845,7 @@
      * @param index index at which to insert the first element
      *        from the specified collection
      * @param c collection containing elements to be added to this list
-     * @return <tt>true</tt> if this list changed as a result of the call
+     * @return {@code true} if this list changed as a result of the call
      * @throws IndexOutOfBoundsException {@inheritDoc}
      * @throws NullPointerException if the specified collection is null
      * @see #add(int,Object)
@@ -840,6 +881,74 @@
         }
     }
 
+    public void forEach(Consumer<? super E> action) {
+        if (action == null) throw new NullPointerException();
+        Object[] elements = getArray();
+        int len = elements.length;
+        for (int i = 0; i < len; ++i) {
+            @SuppressWarnings("unchecked") E e = (E) elements[i];
+            action.accept(e);
+        }
+    }
+
+    public boolean removeIf(Predicate<? super E> filter) {
+        if (filter == null) throw new NullPointerException();
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (len != 0) {
+                int newlen = 0;
+                Object[] temp = new Object[len];
+                for (int i = 0; i < len; ++i) {
+                    @SuppressWarnings("unchecked") E e = (E) elements[i];
+                    if (!filter.test(e))
+                        temp[newlen++] = e;
+                }
+                if (newlen != len) {
+                    setArray(Arrays.copyOf(temp, newlen));
+                    return true;
+                }
+            }
+            return false;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public void replaceAll(UnaryOperator<E> operator) {
+        if (operator == null) throw new NullPointerException();
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+            Object[] newElements = Arrays.copyOf(elements, len);
+            for (int i = 0; i < len; ++i) {
+                @SuppressWarnings("unchecked") E e = (E) elements[i];
+                newElements[i] = operator.apply(e);
+            }
+            setArray(newElements);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public void sort(Comparator<? super E> c) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            Object[] newElements = Arrays.copyOf(elements, elements.length);
+            @SuppressWarnings("unchecked") E[] es = (E[])newElements;
+            Arrays.sort(es, c);
+            setArray(newElements);
+        } finally {
+            lock.unlock();
+        }
+    }
+
     /**
      * Saves this list to a stream (that is, serializes it).
      *
@@ -886,8 +995,8 @@
      * Returns a string representation of this list.  The string
      * representation consists of the string representations of the list's
      * elements in the order they are returned by its iterator, enclosed in
-     * square brackets (<tt>"[]"</tt>).  Adjacent elements are separated by
-     * the characters <tt>", "</tt> (comma and space).  Elements are
+     * square brackets ({@code "[]"}).  Adjacent elements are separated by
+     * the characters {@code ", "} (comma and space).  Elements are
      * converted to strings as by {@link String#valueOf(Object)}.
      *
      * @return a string representation of this list
@@ -953,7 +1062,7 @@
      * <p>The returned iterator provides a snapshot of the state of the list
      * when the iterator was constructed. No synchronization is needed while
      * traversing the iterator. The iterator does <em>NOT</em> support the
-     * <tt>remove</tt> method.
+     * {@code remove} method.
      *
      * @return an iterator over the elements in this list in proper sequence
      */
@@ -967,7 +1076,7 @@
      * <p>The returned iterator provides a snapshot of the state of the list
      * when the iterator was constructed. No synchronization is needed while
      * traversing the iterator. The iterator does <em>NOT</em> support the
-     * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
+     * {@code remove}, {@code set} or {@code add} methods.
      */
     public ListIterator<E> listIterator() {
         return new COWIterator<E>(getArray(), 0);
@@ -979,7 +1088,7 @@
      * <p>The returned iterator provides a snapshot of the state of the list
      * when the iterator was constructed. No synchronization is needed while
      * traversing the iterator. The iterator does <em>NOT</em> support the
-     * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
+     * {@code remove}, {@code set} or {@code add} methods.
      *
      * @throws IndexOutOfBoundsException {@inheritDoc}
      */
@@ -992,7 +1101,12 @@
         return new COWIterator<E>(elements, index);
     }
 
-    private static class COWIterator<E> implements ListIterator<E> {
+    public Spliterator<E> spliterator() {
+        return Spliterators.spliterator
+            (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED);
+    }
+
+    static final class COWIterator<E> implements ListIterator<E> {
         /** Snapshot of the array */
         private final Object[] snapshot;
         /** Index of element to be returned by subsequent call to next.  */
@@ -1035,7 +1149,7 @@
 
         /**
          * Not supported. Always throws UnsupportedOperationException.
-         * @throws UnsupportedOperationException always; <tt>remove</tt>
+         * @throws UnsupportedOperationException always; {@code remove}
          *         is not supported by this iterator.
          */
         public void remove() {
@@ -1044,7 +1158,7 @@
 
         /**
          * Not supported. Always throws UnsupportedOperationException.
-         * @throws UnsupportedOperationException always; <tt>set</tt>
+         * @throws UnsupportedOperationException always; {@code set}
          *         is not supported by this iterator.
          */
         public void set(E e) {
@@ -1053,7 +1167,7 @@
 
         /**
          * Not supported. Always throws UnsupportedOperationException.
-         * @throws UnsupportedOperationException always; <tt>add</tt>
+         * @throws UnsupportedOperationException always; {@code add}
          *         is not supported by this iterator.
          */
         public void add(E e) {
@@ -1061,12 +1175,13 @@
         }
 
         @Override
-        @SuppressWarnings("unchecked")
         public void forEachRemaining(Consumer<? super E> action) {
             Objects.requireNonNull(action);
-            final int size = snapshot.length;
-            for (int i=cursor; i < size; i++) {
-                action.accept((E) snapshot[i]);
+            Object[] elements = snapshot;
+            final int size = elements.length;
+            for (int i = cursor; i < size; i++) {
+                @SuppressWarnings("unchecked") E e = (E) elements[i];
+                action.accept(e);
             }
             cursor = size;
         }
@@ -1074,7 +1189,7 @@
 
     /**
      * Returns a view of the portion of this list between
-     * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
+     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
      * The returned list is backed by this list, so changes in the
      * returned list are reflected in this list.
      *
@@ -1274,55 +1389,196 @@
             }
         }
 
-        @Override
         public void forEach(Consumer<? super E> action) {
-            @SuppressWarnings("unchecked")
-            final E[] elements = (E[]) l.getArray();
-            checkForComodification();
-            l.forEach(action, elements, offset, offset + size);
+            if (action == null) throw new NullPointerException();
+            int lo = offset;
+            int hi = offset + size;
+            Object[] a = expectedArray;
+            if (l.getArray() != a)
+                throw new ConcurrentModificationException();
+            if (lo < 0 || hi > a.length)
+                throw new IndexOutOfBoundsException();
+            for (int i = lo; i < hi; ++i) {
+                @SuppressWarnings("unchecked") E e = (E) a[i];
+                action.accept(e);
+            }
         }
 
-        @Override
+        public void replaceAll(UnaryOperator<E> operator) {
+            if (operator == null) throw new NullPointerException();
+            final ReentrantLock lock = l.lock;
+            lock.lock();
+            try {
+                int lo = offset;
+                int hi = offset + size;
+                Object[] elements = expectedArray;
+                if (l.getArray() != elements)
+                    throw new ConcurrentModificationException();
+                int len = elements.length;
+                if (lo < 0 || hi > len)
+                    throw new IndexOutOfBoundsException();
+                Object[] newElements = Arrays.copyOf(elements, len);
+                for (int i = lo; i < hi; ++i) {
+                    @SuppressWarnings("unchecked") E e = (E) elements[i];
+                    newElements[i] = operator.apply(e);
+                }
+                l.setArray(expectedArray = newElements);
+            } finally {
+                lock.unlock();
+            }
+        }
+
         public void sort(Comparator<? super E> c) {
             final ReentrantLock lock = l.lock;
             lock.lock();
             try {
-                checkForComodification();
-                l.sort(c, offset, offset + size);
-                expectedArray = l.getArray();
+                int lo = offset;
+                int hi = offset + size;
+                Object[] elements = expectedArray;
+                if (l.getArray() != elements)
+                    throw new ConcurrentModificationException();
+                int len = elements.length;
+                if (lo < 0 || hi > len)
+                    throw new IndexOutOfBoundsException();
+                Object[] newElements = Arrays.copyOf(elements, len);
+                @SuppressWarnings("unchecked") E[] es = (E[])newElements;
+                Arrays.sort(es, lo, hi, c);
+                l.setArray(expectedArray = newElements);
             } finally {
                 lock.unlock();
             }
         }
 
-        @Override
-        public boolean removeIf(Predicate<? super E> filter) {
-            Objects.requireNonNull(filter);
+        public boolean removeAll(Collection<?> c) {
+            if (c == null) throw new NullPointerException();
+            boolean removed = false;
+            final ReentrantLock lock = l.lock;
+            lock.lock();
+            try {
+                int n = size;
+                if (n > 0) {
+                    int lo = offset;
+                    int hi = offset + n;
+                    Object[] elements = expectedArray;
+                    if (l.getArray() != elements)
+                        throw new ConcurrentModificationException();
+                    int len = elements.length;
+                    if (lo < 0 || hi > len)
+                        throw new IndexOutOfBoundsException();
+                    int newSize = 0;
+                    Object[] temp = new Object[n];
+                    for (int i = lo; i < hi; ++i) {
+                        Object element = elements[i];
+                        if (!c.contains(element))
+                            temp[newSize++] = element;
+                    }
+                    if (newSize != n) {
+                        Object[] newElements = new Object[len - n + newSize];
+                        System.arraycopy(elements, 0, newElements, 0, lo);
+                        System.arraycopy(temp, 0, newElements, lo, newSize);
+                        System.arraycopy(elements, hi, newElements,
+                                         lo + newSize, len - hi);
+                        size = newSize;
+                        removed = true;
+                        l.setArray(expectedArray = newElements);
+                    }
+                }
+            } finally {
+                lock.unlock();
+            }
+            return removed;
+        }
+
+        public boolean retainAll(Collection<?> c) {
+            if (c == null) throw new NullPointerException();
+            boolean removed = false;
             final ReentrantLock lock = l.lock;
             lock.lock();
             try {
-                checkForComodification();
-                final int removeCount =
-                        l.removeIf(filter, offset, offset + size);
-                expectedArray = l.getArray();
-                size -= removeCount;
-                return removeCount > 0;
+                int n = size;
+                if (n > 0) {
+                    int lo = offset;
+                    int hi = offset + n;
+                    Object[] elements = expectedArray;
+                    if (l.getArray() != elements)
+                        throw new ConcurrentModificationException();
+                    int len = elements.length;
+                    if (lo < 0 || hi > len)
+                        throw new IndexOutOfBoundsException();
+                    int newSize = 0;
+                    Object[] temp = new Object[n];
+                    for (int i = lo; i < hi; ++i) {
+                        Object element = elements[i];
+                        if (c.contains(element))
+                            temp[newSize++] = element;
+                    }
+                    if (newSize != n) {
+                        Object[] newElements = new Object[len - n + newSize];
+                        System.arraycopy(elements, 0, newElements, 0, lo);
+                        System.arraycopy(temp, 0, newElements, lo, newSize);
+                        System.arraycopy(elements, hi, newElements,
+                                         lo + newSize, len - hi);
+                        size = newSize;
+                        removed = true;
+                        l.setArray(expectedArray = newElements);
+                    }
+                }
             } finally {
                 lock.unlock();
             }
+            return removed;
         }
 
-        @Override
-        public void replaceAll(UnaryOperator<E> operator) {
+        public boolean removeIf(Predicate<? super E> filter) {
+            if (filter == null) throw new NullPointerException();
+            boolean removed = false;
             final ReentrantLock lock = l.lock;
             lock.lock();
             try {
-                checkForComodification();
-                l.replaceAll(operator, offset, offset + size);
-                expectedArray = l.getArray();
+                int n = size;
+                if (n > 0) {
+                    int lo = offset;
+                    int hi = offset + n;
+                    Object[] elements = expectedArray;
+                    if (l.getArray() != elements)
+                        throw new ConcurrentModificationException();
+                    int len = elements.length;
+                    if (lo < 0 || hi > len)
+                        throw new IndexOutOfBoundsException();
+                    int newSize = 0;
+                    Object[] temp = new Object[n];
+                    for (int i = lo; i < hi; ++i) {
+                        @SuppressWarnings("unchecked") E e = (E) elements[i];
+                        if (!filter.test(e))
+                            temp[newSize++] = e;
+                    }
+                    if (newSize != n) {
+                        Object[] newElements = new Object[len - n + newSize];
+                        System.arraycopy(elements, 0, newElements, 0, lo);
+                        System.arraycopy(temp, 0, newElements, lo, newSize);
+                        System.arraycopy(elements, hi, newElements,
+                                         lo + newSize, len - hi);
+                        size = newSize;
+                        removed = true;
+                        l.setArray(expectedArray = newElements);
+                    }
+                }
             } finally {
                 lock.unlock();
             }
+            return removed;
+        }
+
+        public Spliterator<E> spliterator() {
+            int lo = offset;
+            int hi = offset + size;
+            Object[] a = expectedArray;
+            if (l.getArray() != a)
+                throw new ConcurrentModificationException();
+            if (lo < 0 || hi > a.length)
+                throw new IndexOutOfBoundsException();
+            return Spliterators.spliterator
+                (a, lo, hi, Spliterator.IMMUTABLE | Spliterator.ORDERED);
         }
     }
 
@@ -1380,11 +1636,12 @@
         }
 
         @Override
-        @SuppressWarnings("unchecked")
         public void forEachRemaining(Consumer<? super E> action) {
             Objects.requireNonNull(action);
-            while (nextIndex() < size) {
-                action.accept(it.next());
+            int s = size;
+            ListIterator<E> i = it;
+            while (nextIndex() < s) {
+                action.accept(i.next());
             }
         }
     }
@@ -1405,139 +1662,4 @@
             throw new Error(e);
         }
     }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void forEach(Consumer<? super E> action) {
-        forEach(action, (E[]) getArray(), 0, size());
-    }
-
-    private void forEach(Consumer<? super E> action,
-                         final E[] elements,
-                         final int from, final int to) {
-        Objects.requireNonNull(action);
-        for (int i = from; i < to; i++) {
-            action.accept(elements[i]);
-        }
-    }
-
-    @Override
-    public void sort(Comparator<? super E> c) {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            sort(c, 0, size());
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    // must be called with this.lock held
-    @SuppressWarnings("unchecked")
-    private void sort(Comparator<? super E> c, final int from, final int to) {
-        final E[] elements = (E[]) getArray();
-        final E[] newElements = Arrays.copyOf(elements, elements.length);
-        // only elements [from, to) are sorted
-        Arrays.sort(newElements, from, to, c);
-        setArray(newElements);
-    }
-
-    @Override
-    public boolean removeIf(Predicate<? super E> filter) {
-        Objects.requireNonNull(filter);
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            return removeIf(filter, 0, size()) > 0;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    // must be called with this.lock held
-    private int removeIf(Predicate<? super E> filter, final int from, final int to) {
-        Objects.requireNonNull(filter);
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            @SuppressWarnings("unchecked")
-            final E[] elements = (E[]) getArray();
-
-            // figure out which elements are to be removed
-            // any exception thrown from the filter predicate at this stage
-            // will leave the collection unmodified
-            int removeCount = 0;
-            final int range = to - from;
-            final BitSet removeSet = new BitSet(range);
-            for (int i = 0; i < range; i++) {
-                final E element = elements[from + i];
-                if (filter.test(element)) {
-                    // removeSet is zero-based to keep its size small
-                    removeSet.set(i);
-                    removeCount++;
-                }
-            }
-
-            // copy surviving elements into a new array
-            if (removeCount > 0) {
-                final int newSize = elements.length - removeCount;
-                final int newRange = newSize - from;
-                @SuppressWarnings("unchecked")
-                final E[] newElements = (E[]) new Object[newSize];
-                // copy elements before [from, to) unmodified
-                for (int i = 0; i < from; i++) {
-                    newElements[i] = elements[i];
-                }
-                // elements [from, to) are subject to removal
-                int j = 0;
-                for (int i = 0; (i < range) && (j < newRange); i++) {
-                    i = removeSet.nextClearBit(i);
-                    if (i >= range) {
-                        break;
-                    }
-                    newElements[from + (j++)] = elements[from + i];
-                }
-                // copy any remaining elements beyond [from, to)
-                j += from;
-                for (int i = to; (i < elements.length) && (j < newSize); i++) {
-                    newElements[j++] = elements[i];
-                }
-                setArray(newElements);
-            }
-
-            return removeCount;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    @Override
-    public void replaceAll(UnaryOperator<E> operator) {
-        Objects.requireNonNull(operator);
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            replaceAll(operator, 0, size());
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    // must be called with this.lock held
-    @SuppressWarnings("unchecked")
-    private void replaceAll(UnaryOperator<E> operator, final int from, final int to) {
-        final E[] elements = (E[]) getArray();
-        final E[] newElements = (E[]) new Object[elements.length];
-        for (int i = 0; i < from; i++) {
-            newElements[i] = elements[i];
-        }
-        // the operator is only applied to elements [from, to)
-        for (int i = from; i < to; i++) {
-            newElements[i] = operator.apply(elements[i]);
-        }
-        for (int i = to; i < elements.length; i++) {
-            newElements[i] = elements[i];
-        }
-        setArray(newElements);
-    }
 }
--- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java	Wed Jul 03 14:35:10 2013 -0700
@@ -34,7 +34,14 @@
  */
 
 package java.util.concurrent;
-import java.util.*;
+import java.util.Collection;
+import java.util.Set;
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Predicate;
+import java.util.function.Consumer;
 
 /**
  * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList}
@@ -45,17 +52,17 @@
  *       vastly outnumber mutative operations, and you need
  *       to prevent interference among threads during traversal.
  *  <li>It is thread-safe.
- *  <li>Mutative operations (<tt>add</tt>, <tt>set</tt>, <tt>remove</tt>, etc.)
+ *  <li>Mutative operations ({@code add}, {@code set}, {@code remove}, etc.)
  *      are expensive since they usually entail copying the entire underlying
  *      array.
- *  <li>Iterators do not support the mutative <tt>remove</tt> operation.
+ *  <li>Iterators do not support the mutative {@code remove} operation.
  *  <li>Traversal via iterators is fast and cannot encounter
  *      interference from other threads. Iterators rely on
  *      unchanging snapshots of the array at the time the iterators were
  *      constructed.
  * </ul>
  *
- * <p> <b>Sample Usage.</b> The following code sketch uses a
+ * <p><b>Sample Usage.</b> The following code sketch uses a
  * copy-on-write set to maintain a set of Handler objects that
  * perform some action upon state updates.
  *
@@ -73,7 +80,7 @@
  *   public void update() {
  *     changeState();
  *     for (Handler handler : handlers)
- *        handler.handle();
+ *       handler.handle();
  *   }
  * }}</pre>
  *
@@ -107,8 +114,15 @@
      * @throws NullPointerException if the specified collection is null
      */
     public CopyOnWriteArraySet(Collection<? extends E> c) {
-        al = new CopyOnWriteArrayList<E>();
-        al.addAllAbsent(c);
+        if (c.getClass() == CopyOnWriteArraySet.class) {
+            @SuppressWarnings("unchecked") CopyOnWriteArraySet<E> cc =
+                (CopyOnWriteArraySet<E>)c;
+            al = new CopyOnWriteArrayList<E>(cc.al);
+        }
+        else {
+            al = new CopyOnWriteArrayList<E>();
+            al.addAllAbsent(c);
+        }
     }
 
     /**
@@ -121,22 +135,22 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this set contains no elements.
+     * Returns {@code true} if this set contains no elements.
      *
-     * @return <tt>true</tt> if this set contains no elements
+     * @return {@code true} if this set contains no elements
      */
     public boolean isEmpty() {
         return al.isEmpty();
     }
 
     /**
-     * Returns <tt>true</tt> if this set contains the specified element.
-     * More formally, returns <tt>true</tt> if and only if this set
-     * contains an element <tt>e</tt> such that
+     * Returns {@code true} if this set contains the specified element.
+     * More formally, returns {@code true} if and only if this set
+     * contains an element {@code e} such that
      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
      *
      * @param o element whose presence in this set is to be tested
-     * @return <tt>true</tt> if this set contains the specified element
+     * @return {@code true} if this set contains the specified element
      */
     public boolean contains(Object o) {
         return al.contains(o);
@@ -172,7 +186,7 @@
      * <p>If this set fits in the specified array with room to spare
      * (i.e., the array has more elements than this set), the element in
      * the array immediately following the end of the set is set to
-     * <tt>null</tt>.  (This is useful in determining the length of this
+     * {@code null}.  (This is useful in determining the length of this
      * set <i>only</i> if the caller knows that this set does not contain
      * any null elements.)
      *
@@ -185,14 +199,14 @@
      * precise control over the runtime type of the output array, and may,
      * under certain circumstances, be used to save allocation costs.
      *
-     * <p>Suppose <tt>x</tt> is a set known to contain only strings.
+     * <p>Suppose {@code x} is a set known to contain only strings.
      * The following code can be used to dump the set into a newly allocated
-     * array of <tt>String</tt>:
+     * array of {@code String}:
      *
      *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
-     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
-     * <tt>toArray()</tt>.
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
      *
      * @param a the array into which the elements of this set are to be
      *        stored, if it is big enough; otherwise, a new array of the same
@@ -217,15 +231,15 @@
 
     /**
      * Removes the specified element from this set if it is present.
-     * More formally, removes an element <tt>e</tt> such that
+     * More formally, removes an element {@code e} such that
      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>,
-     * if this set contains such an element.  Returns <tt>true</tt> if
+     * if this set contains such an element.  Returns {@code true} if
      * this set contained the element (or equivalently, if this set
      * changed as a result of the call).  (This set will not contain the
      * element once the call returns.)
      *
      * @param o object to be removed from this set, if present
-     * @return <tt>true</tt> if this set contained the specified element
+     * @return {@code true} if this set contained the specified element
      */
     public boolean remove(Object o) {
         return al.remove(o);
@@ -233,14 +247,14 @@
 
     /**
      * Adds the specified element to this set if it is not already present.
-     * More formally, adds the specified element <tt>e</tt> to this set if
-     * the set contains no element <tt>e2</tt> such that
+     * More formally, adds the specified element {@code e} to this set if
+     * the set contains no element {@code e2} such that
      * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
      * If this set already contains the element, the call leaves the set
-     * unchanged and returns <tt>false</tt>.
+     * unchanged and returns {@code false}.
      *
      * @param e element to be added to this set
-     * @return <tt>true</tt> if this set did not already contain the specified
+     * @return {@code true} if this set did not already contain the specified
      *         element
      */
     public boolean add(E e) {
@@ -248,12 +262,12 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this set contains all of the elements of the
+     * Returns {@code true} if this set contains all of the elements of the
      * specified collection.  If the specified collection is also a set, this
-     * method returns <tt>true</tt> if it is a <i>subset</i> of this set.
+     * method returns {@code true} if it is a <i>subset</i> of this set.
      *
      * @param  c collection to be checked for containment in this set
-     * @return <tt>true</tt> if this set contains all of the elements of the
+     * @return {@code true} if this set contains all of the elements of the
      *         specified collection
      * @throws NullPointerException if the specified collection is null
      * @see #contains(Object)
@@ -265,13 +279,13 @@
     /**
      * Adds all of the elements in the specified collection to this set if
      * they're not already present.  If the specified collection is also a
-     * set, the <tt>addAll</tt> operation effectively modifies this set so
+     * set, the {@code addAll} operation effectively modifies this set so
      * that its value is the <i>union</i> of the two sets.  The behavior of
      * this operation is undefined if the specified collection is modified
      * while the operation is in progress.
      *
      * @param  c collection containing elements to be added to this set
-     * @return <tt>true</tt> if this set changed as a result of the call
+     * @return {@code true} if this set changed as a result of the call
      * @throws NullPointerException if the specified collection is null
      * @see #add(Object)
      */
@@ -286,7 +300,7 @@
      * <i>asymmetric set difference</i> of the two sets.
      *
      * @param  c collection containing elements to be removed from this set
-     * @return <tt>true</tt> if this set changed as a result of the call
+     * @return {@code true} if this set changed as a result of the call
      * @throws ClassCastException if the class of an element of this set
      *         is incompatible with the specified collection (optional)
      * @throws NullPointerException if this set contains a null element and the
@@ -307,7 +321,7 @@
      * two sets.
      *
      * @param  c collection containing elements to be retained in this set
-     * @return <tt>true</tt> if this set changed as a result of the call
+     * @return {@code true} if this set changed as a result of the call
      * @throws ClassCastException if the class of an element of this set
      *         is incompatible with the specified collection (optional)
      * @throws NullPointerException if this set contains a null element and the
@@ -326,7 +340,7 @@
      * <p>The returned iterator provides a snapshot of the state of the set
      * when the iterator was constructed. No synchronization is needed while
      * traversing the iterator. The iterator does <em>NOT</em> support the
-     * <tt>remove</tt> method.
+     * {@code remove} method.
      *
      * @return an iterator over the elements in this set
      */
@@ -338,7 +352,7 @@
      * Compares the specified object with this set for equality.
      * Returns {@code true} if the specified object is the same object
      * as this object, or if it is also a {@link Set} and the elements
-     * returned by an {@linkplain List#iterator() iterator} over the
+     * returned by an {@linkplain Set#iterator() iterator} over the
      * specified set are the same as the elements returned by an
      * iterator over this set.  More formally, the two iterators are
      * considered to return the same elements if they return the same
@@ -382,6 +396,19 @@
         return k == len;
     }
 
+    public boolean removeIf(Predicate<? super E> filter) {
+        return al.removeIf(filter);
+    }
+
+    public void forEach(Consumer<? super E> action) {
+        al.forEach(action);
+    }
+
+    public Spliterator<E> spliterator() {
+        return Spliterators.spliterator
+            (al.getArray(), Spliterator.IMMUTABLE | Spliterator.DISTINCT);
+    }
+
     /**
      * Tests for equality, coping with nulls.
      */
--- a/jdk/src/share/classes/java/util/concurrent/CountDownLatch.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CountDownLatch.java	Wed Jul 03 14:35:10 2013 -0700
@@ -92,15 +92,15 @@
  *   private final CountDownLatch startSignal;
  *   private final CountDownLatch doneSignal;
  *   Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
- *      this.startSignal = startSignal;
- *      this.doneSignal = doneSignal;
+ *     this.startSignal = startSignal;
+ *     this.doneSignal = doneSignal;
  *   }
  *   public void run() {
- *      try {
- *        startSignal.await();
- *        doWork();
- *        doneSignal.countDown();
- *      } catch (InterruptedException ex) {} // return;
+ *     try {
+ *       startSignal.await();
+ *       doWork();
+ *       doneSignal.countDown();
+ *     } catch (InterruptedException ex) {} // return;
  *   }
  *
  *   void doWork() { ... }
@@ -130,14 +130,14 @@
  *   private final CountDownLatch doneSignal;
  *   private final int i;
  *   WorkerRunnable(CountDownLatch doneSignal, int i) {
- *      this.doneSignal = doneSignal;
- *      this.i = i;
+ *     this.doneSignal = doneSignal;
+ *     this.i = i;
  *   }
  *   public void run() {
- *      try {
- *        doWork(i);
- *        doneSignal.countDown();
- *      } catch (InterruptedException ex) {} // return;
+ *     try {
+ *       doWork(i);
+ *       doneSignal.countDown();
+ *     } catch (InterruptedException ex) {} // return;
  *   }
  *
  *   void doWork() { ... }
--- a/jdk/src/share/classes/java/util/concurrent/CyclicBarrier.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CyclicBarrier.java	Wed Jul 03 14:35:10 2013 -0700
@@ -45,14 +45,14 @@
  * <em>cyclic</em> because it can be re-used after the waiting threads
  * are released.
  *
- * <p>A <tt>CyclicBarrier</tt> supports an optional {@link Runnable} command
+ * <p>A {@code CyclicBarrier} supports an optional {@link Runnable} command
  * that is run once per barrier point, after the last thread in the party
  * arrives, but before any threads are released.
  * This <em>barrier action</em> is useful
  * for updating shared-state before any of the parties continue.
  *
- * <p><b>Sample usage:</b> Here is an example of
- *  using a barrier in a parallel decomposition design:
+ * <p><b>Sample usage:</b> Here is an example of using a barrier in a
+ * parallel decomposition design:
  *
  *  <pre> {@code
  * class Solver {
@@ -81,16 +81,20 @@
  *   public Solver(float[][] matrix) {
  *     data = matrix;
  *     N = matrix.length;
- *     barrier = new CyclicBarrier(N,
- *                                 new Runnable() {
- *                                   public void run() {
- *                                     mergeRows(...);
- *                                   }
- *                                 });
- *     for (int i = 0; i < N; ++i)
- *       new Thread(new Worker(i)).start();
+ *     Runnable barrierAction =
+ *       new Runnable() { public void run() { mergeRows(...); }};
+ *     barrier = new CyclicBarrier(N, barrierAction);
  *
- *     waitUntilDone();
+ *     List<Thread> threads = new ArrayList<Thread>(N);
+ *     for (int i = 0; i < N; i++) {
+ *       Thread thread = new Thread(new Worker(i));
+ *       threads.add(thread);
+ *       thread.start();
+ *     }
+ *
+ *     // wait until done
+ *     for (Thread thread : threads)
+ *       thread.join();
  *   }
  * }}</pre>
  *
@@ -98,8 +102,8 @@
  * barrier until all rows have been processed. When all rows are processed
  * the supplied {@link Runnable} barrier action is executed and merges the
  * rows. If the merger
- * determines that a solution has been found then <tt>done()</tt> will return
- * <tt>true</tt> and each worker will terminate.
+ * determines that a solution has been found then {@code done()} will return
+ * {@code true} and each worker will terminate.
  *
  * <p>If the barrier action does not rely on the parties being suspended when
  * it is executed, then any of the threads in the party could execute that
@@ -112,7 +116,7 @@
  *   // log the completion of this iteration
  * }}</pre>
  *
- * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model
+ * <p>The {@code CyclicBarrier} uses an all-or-none breakage model
  * for failed synchronization attempts: If a thread leaves a barrier
  * point prematurely because of interruption, failure, or timeout, all
  * other threads waiting at that barrier point will also leave
@@ -139,7 +143,7 @@
      * is reset. There can be many generations associated with threads
      * using the barrier - due to the non-deterministic way the lock
      * may be allocated to waiting threads - but only one of these
-     * can be active at a time (the one to which <tt>count</tt> applies)
+     * can be active at a time (the one to which {@code count} applies)
      * and all the rest are either broken or tripped.
      * There need not be an active generation if there has been a break
      * but no subsequent reset.
@@ -259,7 +263,7 @@
     }
 
     /**
-     * Creates a new <tt>CyclicBarrier</tt> that will trip when the
+     * Creates a new {@code CyclicBarrier} that will trip when the
      * given number of parties (threads) are waiting upon it, and which
      * will execute the given barrier action when the barrier is tripped,
      * performed by the last thread entering the barrier.
@@ -278,7 +282,7 @@
     }
 
     /**
-     * Creates a new <tt>CyclicBarrier</tt> that will trip when the
+     * Creates a new {@code CyclicBarrier} that will trip when the
      * given number of parties (threads) are waiting upon it, and
      * does not perform a predefined action when the barrier is tripped.
      *
@@ -301,7 +305,7 @@
 
     /**
      * Waits until all {@linkplain #getParties parties} have invoked
-     * <tt>await</tt> on this barrier.
+     * {@code await} on this barrier.
      *
      * <p>If the current thread is not the last to arrive then it is
      * disabled for thread scheduling purposes and lies dormant until
@@ -326,7 +330,7 @@
      *
      * <p>If the barrier is {@link #reset} while any thread is waiting,
      * or if the barrier {@linkplain #isBroken is broken} when
-     * <tt>await</tt> is invoked, or while any thread is waiting, then
+     * {@code await} is invoked, or while any thread is waiting, then
      * {@link BrokenBarrierException} is thrown.
      *
      * <p>If any thread is {@linkplain Thread#interrupt interrupted} while waiting,
@@ -343,7 +347,7 @@
      * the broken state.
      *
      * @return the arrival index of the current thread, where index
-     *         <tt>{@link #getParties()} - 1</tt> indicates the first
+     *         {@code getParties() - 1} indicates the first
      *         to arrive and zero indicates the last to arrive
      * @throws InterruptedException if the current thread was interrupted
      *         while waiting
@@ -351,7 +355,7 @@
      *         interrupted or timed out while the current thread was
      *         waiting, or the barrier was reset, or the barrier was
      *         broken when {@code await} was called, or the barrier
-     *         action (if present) failed due an exception.
+     *         action (if present) failed due to an exception
      */
     public int await() throws InterruptedException, BrokenBarrierException {
         try {
@@ -363,7 +367,7 @@
 
     /**
      * Waits until all {@linkplain #getParties parties} have invoked
-     * <tt>await</tt> on this barrier, or the specified waiting time elapses.
+     * {@code await} on this barrier, or the specified waiting time elapses.
      *
      * <p>If the current thread is not the last to arrive then it is
      * disabled for thread scheduling purposes and lies dormant until
@@ -393,7 +397,7 @@
      *
      * <p>If the barrier is {@link #reset} while any thread is waiting,
      * or if the barrier {@linkplain #isBroken is broken} when
-     * <tt>await</tt> is invoked, or while any thread is waiting, then
+     * {@code await} is invoked, or while any thread is waiting, then
      * {@link BrokenBarrierException} is thrown.
      *
      * <p>If any thread is {@linkplain Thread#interrupt interrupted} while
@@ -412,16 +416,17 @@
      * @param timeout the time to wait for the barrier
      * @param unit the time unit of the timeout parameter
      * @return the arrival index of the current thread, where index
-     *         <tt>{@link #getParties()} - 1</tt> indicates the first
+     *         {@code getParties() - 1} indicates the first
      *         to arrive and zero indicates the last to arrive
      * @throws InterruptedException if the current thread was interrupted
      *         while waiting
-     * @throws TimeoutException if the specified timeout elapses
+     * @throws TimeoutException if the specified timeout elapses.
+     *         In this case the barrier will be broken.
      * @throws BrokenBarrierException if <em>another</em> thread was
      *         interrupted or timed out while the current thread was
      *         waiting, or the barrier was reset, or the barrier was broken
      *         when {@code await} was called, or the barrier action (if
-     *         present) failed due an exception
+     *         present) failed due to an exception
      */
     public int await(long timeout, TimeUnit unit)
         throws InterruptedException,
--- a/jdk/src/share/classes/java/util/concurrent/DelayQueue.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/DelayQueue.java	Wed Jul 03 14:35:10 2013 -0700
@@ -33,28 +33,31 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-
 package java.util.concurrent;
-import java.util.concurrent.locks.*;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
 import java.util.*;
 
 /**
  * An unbounded {@linkplain BlockingQueue blocking queue} of
- * <tt>Delayed</tt> elements, in which an element can only be taken
+ * {@code Delayed} elements, in which an element can only be taken
  * when its delay has expired.  The <em>head</em> of the queue is that
- * <tt>Delayed</tt> element whose delay expired furthest in the
- * past.  If no delay has expired there is no head and <tt>poll</tt>
- * will return <tt>null</tt>. Expiration occurs when an element's
- * <tt>getDelay(TimeUnit.NANOSECONDS)</tt> method returns a value less
+ * {@code Delayed} element whose delay expired furthest in the
+ * past.  If no delay has expired there is no head and {@code poll}
+ * will return {@code null}. Expiration occurs when an element's
+ * {@code getDelay(TimeUnit.NANOSECONDS)} method returns a value less
  * than or equal to zero.  Even though unexpired elements cannot be
- * removed using <tt>take</tt> or <tt>poll</tt>, they are otherwise
- * treated as normal elements. For example, the <tt>size</tt> method
+ * removed using {@code take} or {@code poll}, they are otherwise
+ * treated as normal elements. For example, the {@code size} method
  * returns the count of both expired and unexpired elements.
  * This queue does not permit null elements.
  *
  * <p>This class and its iterator implement all of the
  * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.
+ * Iterator} interfaces.  The Iterator provided in method {@link
+ * #iterator()} is <em>not</em> guaranteed to traverse the elements of
+ * the DelayQueue in any particular order.
  *
  * <p>This class is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
@@ -64,11 +67,10 @@
  * @author Doug Lea
  * @param <E> the type of elements held in this collection
  */
-
 public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
     implements BlockingQueue<E> {
 
-    private transient final ReentrantLock lock = new ReentrantLock();
+    private final transient ReentrantLock lock = new ReentrantLock();
     private final PriorityQueue<E> q = new PriorityQueue<E>();
 
     /**
@@ -97,12 +99,12 @@
     private final Condition available = lock.newCondition();
 
     /**
-     * Creates a new <tt>DelayQueue</tt> that is initially empty.
+     * Creates a new {@code DelayQueue} that is initially empty.
      */
     public DelayQueue() {}
 
     /**
-     * Creates a <tt>DelayQueue</tt> initially containing the elements of the
+     * Creates a {@code DelayQueue} initially containing the elements of the
      * given collection of {@link Delayed} instances.
      *
      * @param c the collection of elements to initially contain
@@ -117,7 +119,7 @@
      * Inserts the specified element into this delay queue.
      *
      * @param e the element to add
-     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     * @return {@code true} (as specified by {@link Collection#add})
      * @throws NullPointerException if the specified element is null
      */
     public boolean add(E e) {
@@ -128,7 +130,7 @@
      * Inserts the specified element into this delay queue.
      *
      * @param e the element to add
-     * @return <tt>true</tt>
+     * @return {@code true}
      * @throws NullPointerException if the specified element is null
      */
     public boolean offer(E e) {
@@ -164,7 +166,7 @@
      * @param e the element to add
      * @param timeout This parameter is ignored as the method never blocks
      * @param unit This parameter is ignored as the method never blocks
-     * @return <tt>true</tt>
+     * @return {@code true}
      * @throws NullPointerException {@inheritDoc}
      */
     public boolean offer(E e, long timeout, TimeUnit unit) {
@@ -172,10 +174,10 @@
     }
 
     /**
-     * Retrieves and removes the head of this queue, or returns <tt>null</tt>
+     * Retrieves and removes the head of this queue, or returns {@code null}
      * if this queue has no elements with an expired delay.
      *
-     * @return the head of this queue, or <tt>null</tt> if this
+     * @return the head of this queue, or {@code null} if this
      *         queue has no elements with an expired delay
      */
     public E poll() {
@@ -183,7 +185,7 @@
         lock.lock();
         try {
             E first = q.peek();
-            if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
+            if (first == null || first.getDelay(NANOSECONDS) > 0)
                 return null;
             else
                 return q.poll();
@@ -208,10 +210,11 @@
                 if (first == null)
                     available.await();
                 else {
-                    long delay = first.getDelay(TimeUnit.NANOSECONDS);
+                    long delay = first.getDelay(NANOSECONDS);
                     if (delay <= 0)
                         return q.poll();
-                    else if (leader != null)
+                    first = null; // don't retain ref while waiting
+                    if (leader != null)
                         available.await();
                     else {
                         Thread thisThread = Thread.currentThread();
@@ -237,7 +240,7 @@
      * until an element with an expired delay is available on this queue,
      * or the specified wait time expires.
      *
-     * @return the head of this queue, or <tt>null</tt> if the
+     * @return the head of this queue, or {@code null} if the
      *         specified waiting time elapses before an element with
      *         an expired delay becomes available
      * @throws InterruptedException {@inheritDoc}
@@ -255,11 +258,12 @@
                     else
                         nanos = available.awaitNanos(nanos);
                 } else {
-                    long delay = first.getDelay(TimeUnit.NANOSECONDS);
+                    long delay = first.getDelay(NANOSECONDS);
                     if (delay <= 0)
                         return q.poll();
                     if (nanos <= 0)
                         return null;
+                    first = null; // don't retain ref while waiting
                     if (nanos < delay || leader != null)
                         nanos = available.awaitNanos(nanos);
                     else {
@@ -284,13 +288,13 @@
 
     /**
      * Retrieves, but does not remove, the head of this queue, or
-     * returns <tt>null</tt> if this queue is empty.  Unlike
-     * <tt>poll</tt>, if no expired elements are available in the queue,
+     * returns {@code null} if this queue is empty.  Unlike
+     * {@code poll}, if no expired elements are available in the queue,
      * this method returns the element that will expire next,
      * if one exists.
      *
-     * @return the head of this queue, or <tt>null</tt> if this
-     *         queue is empty.
+     * @return the head of this queue, or {@code null} if this
+     *         queue is empty
      */
     public E peek() {
         final ReentrantLock lock = this.lock;
@@ -313,6 +317,17 @@
     }
 
     /**
+     * Returns first element only if it is expired.
+     * Used only by drainTo.  Call only when holding lock.
+     */
+    private E peekExpired() {
+        // assert lock.isHeldByCurrentThread();
+        E first = q.peek();
+        return (first == null || first.getDelay(NANOSECONDS) > 0) ?
+            null : first;
+    }
+
+    /**
      * @throws UnsupportedOperationException {@inheritDoc}
      * @throws ClassCastException            {@inheritDoc}
      * @throws NullPointerException          {@inheritDoc}
@@ -327,11 +342,9 @@
         lock.lock();
         try {
             int n = 0;
-            for (;;) {
-                E first = q.peek();
-                if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
-                    break;
-                c.add(q.poll());
+            for (E e; (e = peekExpired()) != null;) {
+                c.add(e);       // In this order, in case add() throws.
+                q.poll();
                 ++n;
             }
             return n;
@@ -357,11 +370,9 @@
         lock.lock();
         try {
             int n = 0;
-            while (n < maxElements) {
-                E first = q.peek();
-                if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
-                    break;
-                c.add(q.poll());
+            for (E e; n < maxElements && (e = peekExpired()) != null;) {
+                c.add(e);       // In this order, in case add() throws.
+                q.poll();
                 ++n;
             }
             return n;
@@ -387,10 +398,10 @@
     }
 
     /**
-     * Always returns <tt>Integer.MAX_VALUE</tt> because
-     * a <tt>DelayQueue</tt> is not capacity constrained.
+     * Always returns {@code Integer.MAX_VALUE} because
+     * a {@code DelayQueue} is not capacity constrained.
      *
-     * @return <tt>Integer.MAX_VALUE</tt>
+     * @return {@code Integer.MAX_VALUE}
      */
     public int remainingCapacity() {
         return Integer.MAX_VALUE;
@@ -430,7 +441,7 @@
      * <p>If this queue fits in the specified array with room to spare
      * (i.e., the array has more elements than this queue), the element in
      * the array immediately following the end of the queue is set to
-     * <tt>null</tt>.
+     * {@code null}.
      *
      * <p>Like the {@link #toArray()} method, this method acts as bridge between
      * array-based and collection-based APIs.  Further, this method allows
@@ -438,13 +449,12 @@
      * under certain circumstances, be used to save allocation costs.
      *
      * <p>The following code can be used to dump a delay queue into a newly
-     * allocated array of <tt>Delayed</tt>:
+     * allocated array of {@code Delayed}:
      *
-     * <pre>
-     *     Delayed[] a = q.toArray(new Delayed[0]);</pre>
+     * <pre> {@code Delayed[] a = q.toArray(new Delayed[0]);}</pre>
      *
-     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
-     * <tt>toArray()</tt>.
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
      *
      * @param a the array into which the elements of the queue are to
      *          be stored, if it is big enough; otherwise, a new array of the
@@ -480,6 +490,24 @@
     }
 
     /**
+     * Identity-based version for use in Itr.remove
+     */
+    void removeEQ(Object o) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            for (Iterator<E> it = q.iterator(); it.hasNext(); ) {
+                if (o == it.next()) {
+                    it.remove();
+                    break;
+                }
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
      * Returns an iterator over all the elements (both expired and
      * unexpired) in this queue. The iterator does not return the
      * elements in any particular order.
@@ -502,7 +530,7 @@
      */
     private class Itr implements Iterator<E> {
         final Object[] array; // Array of all elements
-        int cursor;           // index of next element to return;
+        int cursor;           // index of next element to return
         int lastRet;          // index of last element, or -1 if no such
 
         Itr(Object[] array) {
@@ -525,21 +553,8 @@
         public void remove() {
             if (lastRet < 0)
                 throw new IllegalStateException();
-            Object x = array[lastRet];
+            removeEQ(array[lastRet]);
             lastRet = -1;
-            // Traverse underlying queue to find == element,
-            // not just a .equals element.
-            lock.lock();
-            try {
-                for (Iterator<E> it = q.iterator(); it.hasNext(); ) {
-                    if (it.next() == x) {
-                        it.remove();
-                        return;
-                    }
-                }
-            } finally {
-                lock.unlock();
-            }
         }
     }
 
--- a/jdk/src/share/classes/java/util/concurrent/Delayed.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Delayed.java	Wed Jul 03 14:35:10 2013 -0700
@@ -40,8 +40,8 @@
  * acted upon after a given delay.
  *
  * <p>An implementation of this interface must define a
- * <tt>compareTo</tt> method that provides an ordering consistent with
- * its <tt>getDelay</tt> method.
+ * {@code compareTo} method that provides an ordering consistent with
+ * its {@code getDelay} method.
  *
  * @since 1.5
  * @author Doug Lea
--- a/jdk/src/share/classes/java/util/concurrent/Exchanger.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Exchanger.java	Wed Jul 03 14:35:10 2013 -0700
@@ -35,7 +35,8 @@
  */
 
 package java.util.concurrent;
-import java.util.concurrent.atomic.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.LockSupport;
 
 /**
@@ -52,7 +53,7 @@
  * to swap buffers between threads so that the thread filling the
  * buffer gets a freshly emptied one when it needs it, handing off the
  * filled one to the thread emptying the buffer.
- * <pre>{@code
+ *  <pre> {@code
  * class FillAndEmpty {
  *   Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
  *   DataBuffer initialEmptyBuffer = ... a made-up type
@@ -88,8 +89,7 @@
  *     new Thread(new FillingLoop()).start();
  *     new Thread(new EmptyingLoop()).start();
  *   }
- * }
- * }</pre>
+ * }}</pre>
  *
  * <p>Memory consistency effects: For each pair of threads that
  * successfully exchange objects via an {@code Exchanger}, actions
@@ -103,486 +103,425 @@
  * @param <V> The type of objects that may be exchanged
  */
 public class Exchanger<V> {
+
     /*
-     * Algorithm Description:
+     * Overview: The core algorithm is, for an exchange "slot",
+     * and a participant (caller) with an item:
      *
-     * The basic idea is to maintain a "slot", which is a reference to
-     * a Node containing both an Item to offer and a "hole" waiting to
-     * get filled in.  If an incoming "occupying" thread sees that the
-     * slot is null, it CAS'es (compareAndSets) a Node there and waits
-     * for another to invoke exchange.  That second "fulfilling" thread
-     * sees that the slot is non-null, and so CASes it back to null,
-     * also exchanging items by CASing the hole, plus waking up the
-     * occupying thread if it is blocked.  In each case CAS'es may
-     * fail because a slot at first appears non-null but is null upon
-     * CAS, or vice-versa.  So threads may need to retry these
-     * actions.
+     * for (;;) {
+     *   if (slot is empty) {                       // offer
+     *     place item in a Node;
+     *     if (can CAS slot from empty to node) {
+     *       wait for release;
+     *       return matching item in node;
+     *     }
+     *   }
+     *   else if (can CAS slot from node to empty) { // release
+     *     get the item in node;
+     *     set matching item in node;
+     *     release waiting thread;
+     *   }
+     *   // else retry on CAS failure
+     * }
+     *
+     * This is among the simplest forms of a "dual data structure" --
+     * see Scott and Scherer's DISC 04 paper and
+     * http://www.cs.rochester.edu/research/synchronization/pseudocode/duals.html
      *
-     * This simple approach works great when there are only a few
-     * threads using an Exchanger, but performance rapidly
-     * deteriorates due to CAS contention on the single slot when
-     * there are lots of threads using an exchanger.  So instead we use
-     * an "arena"; basically a kind of hash table with a dynamically
-     * varying number of slots, any one of which can be used by
-     * threads performing an exchange.  Incoming threads pick slots
-     * based on a hash of their Thread ids.  If an incoming thread
-     * fails to CAS in its chosen slot, it picks an alternative slot
-     * instead.  And similarly from there.  If a thread successfully
-     * CASes into a slot but no other thread arrives, it tries
-     * another, heading toward the zero slot, which always exists even
-     * if the table shrinks.  The particular mechanics controlling this
-     * are as follows:
+     * This works great in principle. But in practice, like many
+     * algorithms centered on atomic updates to a single location, it
+     * scales horribly when there are more than a few participants
+     * using the same Exchanger. So the implementation instead uses a
+     * form of elimination arena, that spreads out this contention by
+     * arranging that some threads typically use different slots,
+     * while still ensuring that eventually, any two parties will be
+     * able to exchange items. That is, we cannot completely partition
+     * across threads, but instead give threads arena indices that
+     * will on average grow under contention and shrink under lack of
+     * contention. We approach this by defining the Nodes that we need
+     * anyway as ThreadLocals, and include in them per-thread index
+     * and related bookkeeping state. (We can safely reuse per-thread
+     * nodes rather than creating them fresh each time because slots
+     * alternate between pointing to a node vs null, so cannot
+     * encounter ABA problems. However, we do need some care in
+     * resetting them between uses.)
      *
-     * Waiting: Slot zero is special in that it is the only slot that
-     * exists when there is no contention.  A thread occupying slot
-     * zero will block if no thread fulfills it after a short spin.
-     * In other cases, occupying threads eventually give up and try
-     * another slot.  Waiting threads spin for a while (a period that
-     * should be a little less than a typical context-switch time)
-     * before either blocking (if slot zero) or giving up (if other
-     * slots) and restarting.  There is no reason for threads to block
-     * unless there are unlikely to be any other threads present.
-     * Occupants are mainly avoiding memory contention so sit there
-     * quietly polling for a shorter period than it would take to
-     * block and then unblock them.  Non-slot-zero waits that elapse
-     * because of lack of other threads waste around one extra
-     * context-switch time per try, which is still on average much
-     * faster than alternative approaches.
+     * Implementing an effective arena requires allocating a bunch of
+     * space, so we only do so upon detecting contention (except on
+     * uniprocessors, where they wouldn't help, so aren't used).
+     * Otherwise, exchanges use the single-slot slotExchange method.
+     * On contention, not only must the slots be in different
+     * locations, but the locations must not encounter memory
+     * contention due to being on the same cache line (or more
+     * generally, the same coherence unit).  Because, as of this
+     * writing, there is no way to determine cacheline size, we define
+     * a value that is enough for common platforms.  Additionally,
+     * extra care elsewhere is taken to avoid other false/unintended
+     * sharing and to enhance locality, including adding padding (via
+     * sun.misc.Contended) to Nodes, embedding "bound" as an Exchanger
+     * field, and reworking some park/unpark mechanics compared to
+     * LockSupport versions.
+     *
+     * The arena starts out with only one used slot. We expand the
+     * effective arena size by tracking collisions; i.e., failed CASes
+     * while trying to exchange. By nature of the above algorithm, the
+     * only kinds of collision that reliably indicate contention are
+     * when two attempted releases collide -- one of two attempted
+     * offers can legitimately fail to CAS without indicating
+     * contention by more than one other thread. (Note: it is possible
+     * but not worthwhile to more precisely detect contention by
+     * reading slot values after CAS failures.)  When a thread has
+     * collided at each slot within the current arena bound, it tries
+     * to expand the arena size by one. We track collisions within
+     * bounds by using a version (sequence) number on the "bound"
+     * field, and conservatively reset collision counts when a
+     * participant notices that bound has been updated (in either
+     * direction).
      *
-     * Sizing: Usually, using only a few slots suffices to reduce
-     * contention.  Especially with small numbers of threads, using
-     * too many slots can lead to just as poor performance as using
-     * too few of them, and there's not much room for error.  The
-     * variable "max" maintains the number of slots actually in
-     * use.  It is increased when a thread sees too many CAS
-     * failures.  (This is analogous to resizing a regular hash table
-     * based on a target load factor, except here, growth steps are
-     * just one-by-one rather than proportional.)  Growth requires
-     * contention failures in each of three tried slots.  Requiring
-     * multiple failures for expansion copes with the fact that some
-     * failed CASes are not due to contention but instead to simple
-     * races between two threads or thread pre-emptions occurring
-     * between reading and CASing.  Also, very transient peak
-     * contention can be much higher than the average sustainable
-     * levels.  An attempt to decrease the max limit is usually made
-     * when a non-slot-zero wait elapses without being fulfilled.
-     * Threads experiencing elapsed waits move closer to zero, so
-     * eventually find existing (or future) threads even if the table
-     * has been shrunk due to inactivity.  The chosen mechanics and
-     * thresholds for growing and shrinking are intrinsically
-     * entangled with indexing and hashing inside the exchange code,
-     * and can't be nicely abstracted out.
+     * The effective arena size is reduced (when there is more than
+     * one slot) by giving up on waiting after a while and trying to
+     * decrement the arena size on expiration. The value of "a while"
+     * is an empirical matter.  We implement by piggybacking on the
+     * use of spin->yield->block that is essential for reasonable
+     * waiting performance anyway -- in a busy exchanger, offers are
+     * usually almost immediately released, in which case context
+     * switching on multiprocessors is extremely slow/wasteful.  Arena
+     * waits just omit the blocking part, and instead cancel. The spin
+     * count is empirically chosen to be a value that avoids blocking
+     * 99% of the time under maximum sustained exchange rates on a
+     * range of test machines. Spins and yields entail some limited
+     * randomness (using a cheap xorshift) to avoid regular patterns
+     * that can induce unproductive grow/shrink cycles. (Using a
+     * pseudorandom also helps regularize spin cycle duration by
+     * making branches unpredictable.)  Also, during an offer, a
+     * waiter can "know" that it will be released when its slot has
+     * changed, but cannot yet proceed until match is set.  In the
+     * mean time it cannot cancel the offer, so instead spins/yields.
+     * Note: It is possible to avoid this secondary check by changing
+     * the linearization point to be a CAS of the match field (as done
+     * in one case in the Scott & Scherer DISC paper), which also
+     * increases asynchrony a bit, at the expense of poorer collision
+     * detection and inability to always reuse per-thread nodes. So
+     * the current scheme is typically a better tradeoff.
+     *
+     * On collisions, indices traverse the arena cyclically in reverse
+     * order, restarting at the maximum index (which will tend to be
+     * sparsest) when bounds change. (On expirations, indices instead
+     * are halved until reaching 0.) It is possible (and has been
+     * tried) to use randomized, prime-value-stepped, or double-hash
+     * style traversal instead of simple cyclic traversal to reduce
+     * bunching.  But empirically, whatever benefits these may have
+     * don't overcome their added overhead: We are managing operations
+     * that occur very quickly unless there is sustained contention,
+     * so simpler/faster control policies work better than more
+     * accurate but slower ones.
+     *
+     * Because we use expiration for arena size control, we cannot
+     * throw TimeoutExceptions in the timed version of the public
+     * exchange method until the arena size has shrunken to zero (or
+     * the arena isn't enabled). This may delay response to timeout
+     * but is still within spec.
      *
-     * Hashing: Each thread picks its initial slot to use in accord
-     * with a simple hashcode.  The sequence is the same on each
-     * encounter by any given thread, but effectively random across
-     * threads.  Using arenas encounters the classic cost vs quality
-     * tradeoffs of all hash tables.  Here, we use a one-step FNV-1a
-     * hash code based on the current thread's Thread.getId(), along
-     * with a cheap approximation to a mod operation to select an
-     * index.  The downside of optimizing index selection in this way
-     * is that the code is hardwired to use a maximum table size of
-     * 32.  But this value more than suffices for known platforms and
-     * applications.
+     * Essentially all of the implementation is in methods
+     * slotExchange and arenaExchange. These have similar overall
+     * structure, but differ in too many details to combine. The
+     * slotExchange method uses the single Exchanger field "slot"
+     * rather than arena array elements. However, it still needs
+     * minimal collision detection to trigger arena construction.
+     * (The messiest part is making sure interrupt status and
+     * InterruptedExceptions come out right during transitions when
+     * both methods may be called. This is done by using null return
+     * as a sentinel to recheck interrupt status.)
      *
-     * Probing: On sensed contention of a selected slot, we probe
-     * sequentially through the table, analogously to linear probing
-     * after collision in a hash table.  (We move circularly, in
-     * reverse order, to mesh best with table growth and shrinkage
-     * rules.)  Except that to minimize the effects of false-alarms
-     * and cache thrashing, we try the first selected slot twice
-     * before moving.
-     *
-     * Padding: Even with contention management, slots are heavily
-     * contended, so use cache-padding to avoid poor memory
-     * performance.  Because of this, slots are lazily constructed
-     * only when used, to avoid wasting this space unnecessarily.
-     * While isolation of locations is not much of an issue at first
-     * in an application, as time goes on and garbage-collectors
-     * perform compaction, slots are very likely to be moved adjacent
-     * to each other, which can cause much thrashing of cache lines on
-     * MPs unless padding is employed.
-     *
-     * This is an improvement of the algorithm described in the paper
-     * "A Scalable Elimination-based Exchange Channel" by William
-     * Scherer, Doug Lea, and Michael Scott in Proceedings of SCOOL05
-     * workshop.  Available at: http://hdl.handle.net/1802/2104
+     * As is too common in this sort of code, methods are monolithic
+     * because most of the logic relies on reads of fields that are
+     * maintained as local variables so can't be nicely factored --
+     * mainly, here, bulky spin->yield->block/cancel code), and
+     * heavily dependent on intrinsics (Unsafe) to use inlined
+     * embedded CAS and related memory access operations (that tend
+     * not to be as readily inlined by dynamic compilers when they are
+     * hidden behind other methods that would more nicely name and
+     * encapsulate the intended effects). This includes the use of
+     * putOrderedX to clear fields of the per-thread Nodes between
+     * uses. Note that field Node.item is not declared as volatile
+     * even though it is read by releasing threads, because they only
+     * do so after CAS operations that must precede access, and all
+     * uses by the owning thread are otherwise acceptably ordered by
+     * other operations. (Because the actual points of atomicity are
+     * slot CASes, it would also be legal for the write to Node.match
+     * in a release to be weaker than a full volatile write. However,
+     * this is not done because it could allow further postponement of
+     * the write, delaying progress.)
      */
 
+    /**
+     * The byte distance (as a shift value) between any two used slots
+     * in the arena.  1 << ASHIFT should be at least cacheline size.
+     */
+    private static final int ASHIFT = 7;
+
+    /**
+     * The maximum supported arena index. The maximum allocatable
+     * arena size is MMASK + 1. Must be a power of two minus one, less
+     * than (1<<(31-ASHIFT)). The cap of 255 (0xff) more than suffices
+     * for the expected scaling limits of the main algorithms.
+     */
+    private static final int MMASK = 0xff;
+
+    /**
+     * Unit for sequence/version bits of bound field. Each successful
+     * change to the bound also adds SEQ.
+     */
+    private static final int SEQ = MMASK + 1;
+
     /** The number of CPUs, for sizing and spin control */
     private static final int NCPU = Runtime.getRuntime().availableProcessors();
 
     /**
-     * The capacity of the arena.  Set to a value that provides more
-     * than enough space to handle contention.  On small machines
-     * most slots won't be used, but it is still not wasted because
-     * the extra space provides some machine-level address padding
-     * to minimize interference with heavily CAS'ed Slot locations.
-     * And on very large machines, performance eventually becomes
-     * bounded by memory bandwidth, not numbers of threads/CPUs.
-     * This constant cannot be changed without also modifying
-     * indexing and hashing algorithms.
+     * The maximum slot index of the arena: The number of slots that
+     * can in principle hold all threads without contention, or at
+     * most the maximum indexable value.
      */
-    private static final int CAPACITY = 32;
-
-    /**
-     * The value of "max" that will hold all threads without
-     * contention.  When this value is less than CAPACITY, some
-     * otherwise wasted expansion can be avoided.
-     */
-    private static final int FULL =
-        Math.max(0, Math.min(CAPACITY, NCPU / 2) - 1);
+    static final int FULL = (NCPU >= (MMASK << 1)) ? MMASK : NCPU >>> 1;
 
     /**
-     * The number of times to spin (doing nothing except polling a
-     * memory location) before blocking or giving up while waiting to
-     * be fulfilled.  Should be zero on uniprocessors.  On
-     * multiprocessors, this value should be large enough so that two
-     * threads exchanging items as fast as possible block only when
-     * one of them is stalled (due to GC or preemption), but not much
-     * longer, to avoid wasting CPU resources.  Seen differently, this
-     * value is a little over half the number of cycles of an average
-     * context switch time on most systems.  The value here is
-     * approximately the average of those across a range of tested
-     * systems.
+     * The bound for spins while waiting for a match. The actual
+     * number of iterations will on average be about twice this value
+     * due to randomization. Note: Spinning is disabled when NCPU==1.
      */
-    private static final int SPINS = (NCPU == 1) ? 0 : 2000;
-
-    /**
-     * The number of times to spin before blocking in timed waits.
-     * Timed waits spin more slowly because checking the time takes
-     * time.  The best value relies mainly on the relative rate of
-     * System.nanoTime vs memory accesses.  The value is empirically
-     * derived to work well across a variety of systems.
-     */
-    private static final int TIMED_SPINS = SPINS / 20;
-
-    /**
-     * Sentinel item representing cancellation of a wait due to
-     * interruption, timeout, or elapsed spin-waits.  This value is
-     * placed in holes on cancellation, and used as a return value
-     * from waiting methods to indicate failure to set or get hole.
-     */
-    private static final Object CANCEL = new Object();
+    private static final int SPINS = 1 << 10;
 
     /**
      * Value representing null arguments/returns from public
-     * methods.  This disambiguates from internal requirement that
-     * holes start out as null to mean they are not yet set.
+     * methods. Needed because the API originally didn't disallow null
+     * arguments, which it should have.
      */
     private static final Object NULL_ITEM = new Object();
 
     /**
-     * Nodes hold partially exchanged data.  This class
-     * opportunistically subclasses AtomicReference to represent the
-     * hole.  So get() returns hole, and compareAndSet CAS'es value
-     * into hole.  This class cannot be parameterized as "V" because
-     * of the use of non-V CANCEL sentinels.
+     * Sentinel value returned by internal exchange methods upon
+     * timeout, to avoid need for separate timed versions of these
+     * methods.
      */
-    @SuppressWarnings("serial")
-    private static final class Node extends AtomicReference<Object> {
-        /** The element offered by the Thread creating this node. */
-        public final Object item;
+    private static final Object TIMED_OUT = new Object();
 
-        /** The Thread waiting to be signalled; null until waiting. */
-        public volatile Thread waiter;
-
-        /**
-         * Creates node with given item and empty hole.
-         * @param item the item
-         */
-        public Node(Object item) {
-            this.item = item;
-        }
+    /**
+     * Nodes hold partially exchanged data, plus other per-thread
+     * bookkeeping. Padded via @sun.misc.Contended to reduce memory
+     * contention.
+     */
+    @sun.misc.Contended static final class Node {
+        int index;              // Arena index
+        int bound;              // Last recorded value of Exchanger.bound
+        int collides;           // Number of CAS failures at current bound
+        int hash;               // Pseudo-random for spins
+        Object item;            // This thread's current item
+        volatile Object match;  // Item provided by releasing thread
+        volatile Thread parked; // Set to this thread when parked, else null
     }
 
-    /**
-     * A Slot is an AtomicReference with heuristic padding to lessen
-     * cache effects of this heavily CAS'ed location.  While the
-     * padding adds noticeable space, all slots are created only on
-     * demand, and there will be more than one of them only when it
-     * would improve throughput more than enough to outweigh using
-     * extra space.
-     */
-    @SuppressWarnings("serial")
-    private static final class Slot extends AtomicReference<Object> {
-        // Improve likelihood of isolation on <= 64 byte cache lines
-        long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe;
+    /** The corresponding thread local class */
+    static final class Participant extends ThreadLocal<Node> {
+        public Node initialValue() { return new Node(); }
     }
 
     /**
-     * Slot array.  Elements are lazily initialized when needed.
-     * Declared volatile to enable double-checked lazy construction.
+     * Per-thread state
      */
-    private volatile Slot[] arena = new Slot[CAPACITY];
+    private final Participant participant;
+
+    /**
+     * Elimination array; null until enabled (within slotExchange).
+     * Element accesses use emulation of volatile gets and CAS.
+     */
+    private volatile Node[] arena;
 
     /**
-     * The maximum slot index being used.  The value sometimes
-     * increases when a thread experiences too many CAS contentions,
-     * and sometimes decreases when a spin-wait elapses.  Changes
-     * are performed only via compareAndSet, to avoid stale values
-     * when a thread happens to stall right before setting.
+     * Slot used until contention detected.
      */
-    private final AtomicInteger max = new AtomicInteger();
+    private volatile Node slot;
 
     /**
-     * Main exchange function, handling the different policy variants.
-     * Uses Object, not "V" as argument and return value to simplify
-     * handling of sentinel values.  Callers from public methods decode
-     * and cast accordingly.
+     * The index of the largest valid arena position, OR'ed with SEQ
+     * number in high bits, incremented on each update.  The initial
+     * update from 0 to SEQ is used to ensure that the arena array is
+     * constructed only once.
+     */
+    private volatile int bound;
+
+    /**
+     * Exchange function when arenas enabled. See above for explanation.
      *
      * @param item the (non-null) item to exchange
      * @param timed true if the wait is timed
-     * @param nanos if timed, the maximum wait time
-     * @return the other thread's item, or CANCEL if interrupted or timed out
+     * @param ns if timed, the maximum wait time, else 0L
+     * @return the other thread's item; or null if interrupted; or
+     * TIMED_OUT if timed and timed out
      */
-    private Object doExchange(Object item, boolean timed, long nanos) {
-        Node me = new Node(item);                 // Create in case occupying
-        int index = hashIndex();                  // Index of current slot
-        int fails = 0;                            // Number of CAS failures
-
-        for (;;) {
-            Object y;                             // Contents of current slot
-            Slot slot = arena[index];
-            if (slot == null)                     // Lazily initialize slots
-                createSlot(index);                // Continue loop to reread
-            else if ((y = slot.get()) != null &&  // Try to fulfill
-                     slot.compareAndSet(y, null)) {
-                Node you = (Node)y;               // Transfer item
-                if (you.compareAndSet(null, item)) {
-                    LockSupport.unpark(you.waiter);
-                    return you.item;
-                }                                 // Else cancelled; continue
+    private final Object arenaExchange(Object item, boolean timed, long ns) {
+        Node[] a = arena;
+        Node p = participant.get();
+        for (int i = p.index;;) {                      // access slot at i
+            int b, m, c; long j;                       // j is raw array offset
+            Node q = (Node)U.getObjectVolatile(a, j = (i << ASHIFT) + ABASE);
+            if (q != null && U.compareAndSwapObject(a, j, q, null)) {
+                Object v = q.item;                     // release
+                q.match = item;
+                Thread w = q.parked;
+                if (w != null)
+                    U.unpark(w);
+                return v;
             }
-            else if (y == null &&                 // Try to occupy
-                     slot.compareAndSet(null, me)) {
-                if (index == 0)                   // Blocking wait for slot 0
-                    return timed ?
-                        awaitNanos(me, slot, nanos) :
-                        await(me, slot);
-                Object v = spinWait(me, slot);    // Spin wait for non-0
-                if (v != CANCEL)
-                    return v;
-                me = new Node(item);              // Throw away cancelled node
-                int m = max.get();
-                if (m > (index >>>= 1))           // Decrease index
-                    max.compareAndSet(m, m - 1);  // Maybe shrink table
+            else if (i <= (m = (b = bound) & MMASK) && q == null) {
+                p.item = item;                         // offer
+                if (U.compareAndSwapObject(a, j, null, p)) {
+                    long end = (timed && m == 0) ? System.nanoTime() + ns : 0L;
+                    Thread t = Thread.currentThread(); // wait
+                    for (int h = p.hash, spins = SPINS;;) {
+                        Object v = p.match;
+                        if (v != null) {
+                            U.putOrderedObject(p, MATCH, null);
+                            p.item = null;             // clear for next use
+                            p.hash = h;
+                            return v;
+                        }
+                        else if (spins > 0) {
+                            h ^= h << 1; h ^= h >>> 3; h ^= h << 10; // xorshift
+                            if (h == 0)                // initialize hash
+                                h = SPINS | (int)t.getId();
+                            else if (h < 0 &&          // approx 50% true
+                                     (--spins & ((SPINS >>> 1) - 1)) == 0)
+                                Thread.yield();        // two yields per wait
+                        }
+                        else if (U.getObjectVolatile(a, j) != p)
+                            spins = SPINS;       // releaser hasn't set match yet
+                        else if (!t.isInterrupted() && m == 0 &&
+                                 (!timed ||
+                                  (ns = end - System.nanoTime()) > 0L)) {
+                            U.putObject(t, BLOCKER, this); // emulate LockSupport
+                            p.parked = t;              // minimize window
+                            if (U.getObjectVolatile(a, j) == p)
+                                U.park(false, ns);
+                            p.parked = null;
+                            U.putObject(t, BLOCKER, null);
+                        }
+                        else if (U.getObjectVolatile(a, j) == p &&
+                                 U.compareAndSwapObject(a, j, p, null)) {
+                            if (m != 0)                // try to shrink
+                                U.compareAndSwapInt(this, BOUND, b, b + SEQ - 1);
+                            p.item = null;
+                            p.hash = h;
+                            i = p.index >>>= 1;        // descend
+                            if (Thread.interrupted())
+                                return null;
+                            if (timed && m == 0 && ns <= 0L)
+                                return TIMED_OUT;
+                            break;                     // expired; restart
+                        }
+                    }
+                }
+                else
+                    p.item = null;                     // clear offer
             }
-            else if (++fails > 1) {               // Allow 2 fails on 1st slot
-                int m = max.get();
-                if (fails > 3 && m < FULL && max.compareAndSet(m, m + 1))
-                    index = m + 1;                // Grow on 3rd failed slot
-                else if (--index < 0)
-                    index = m;                    // Circularly traverse
+            else {
+                if (p.bound != b) {                    // stale; reset
+                    p.bound = b;
+                    p.collides = 0;
+                    i = (i != m || m == 0) ? m : m - 1;
+                }
+                else if ((c = p.collides) < m || m == FULL ||
+                         !U.compareAndSwapInt(this, BOUND, b, b + SEQ + 1)) {
+                    p.collides = c + 1;
+                    i = (i == 0) ? m : i - 1;          // cyclically traverse
+                }
+                else
+                    i = m + 1;                         // grow
+                p.index = i;
             }
         }
     }
 
     /**
-     * Returns a hash index for the current thread.  Uses a one-step
-     * FNV-1a hash code (http://www.isthe.com/chongo/tech/comp/fnv/)
-     * based on the current thread's Thread.getId().  These hash codes
-     * have more uniform distribution properties with respect to small
-     * moduli (here 1-31) than do other simple hashing functions.
-     *
-     * <p>To return an index between 0 and max, we use a cheap
-     * approximation to a mod operation, that also corrects for bias
-     * due to non-power-of-2 remaindering (see {@link
-     * java.util.Random#nextInt}).  Bits of the hashcode are masked
-     * with "nbits", the ceiling power of two of table size (looked up
-     * in a table packed into three ints).  If too large, this is
-     * retried after rotating the hash by nbits bits, while forcing new
-     * top bit to 0, which guarantees eventual termination (although
-     * with a non-random-bias).  This requires an average of less than
-     * 2 tries for all table sizes, and has a maximum 2% difference
-     * from perfectly uniform slot probabilities when applied to all
-     * possible hash codes for sizes less than 32.
+     * Exchange function used until arenas enabled. See above for explanation.
      *
-     * @return a per-thread-random index, 0 <= index < max
-     */
-    private final int hashIndex() {
-        long id = Thread.currentThread().getId();
-        int hash = (((int)(id ^ (id >>> 32))) ^ 0x811c9dc5) * 0x01000193;
-
-        int m = max.get();
-        int nbits = (((0xfffffc00  >> m) & 4) | // Compute ceil(log2(m+1))
-                     ((0x000001f8 >>> m) & 2) | // The constants hold
-                     ((0xffff00f2 >>> m) & 1)); // a lookup table
-        int index;
-        while ((index = hash & ((1 << nbits) - 1)) > m)       // May retry on
-            hash = (hash >>> nbits) | (hash << (33 - nbits)); // non-power-2 m
-        return index;
-    }
-
-    /**
-     * Creates a new slot at given index.  Called only when the slot
-     * appears to be null.  Relies on double-check using builtin
-     * locks, since they rarely contend.  This in turn relies on the
-     * arena array being declared volatile.
-     *
-     * @param index the index to add slot at
+     * @param item the item to exchange
+     * @param timed true if the wait is timed
+     * @param ns if timed, the maximum wait time, else 0L
+     * @return the other thread's item; or null if either the arena
+     * was enabled or the thread was interrupted before completion; or
+     * TIMED_OUT if timed and timed out
      */
-    private void createSlot(int index) {
-        // Create slot outside of lock to narrow sync region
-        Slot newSlot = new Slot();
-        Slot[] a = arena;
-        synchronized (a) {
-            if (a[index] == null)
-                a[index] = newSlot;
-        }
-    }
-
-    /**
-     * Tries to cancel a wait for the given node waiting in the given
-     * slot, if so, helping clear the node from its slot to avoid
-     * garbage retention.
-     *
-     * @param node the waiting node
-     * @param the slot it is waiting in
-     * @return true if successfully cancelled
-     */
-    private static boolean tryCancel(Node node, Slot slot) {
-        if (!node.compareAndSet(null, CANCEL))
-            return false;
-        if (slot.get() == node) // pre-check to minimize contention
-            slot.compareAndSet(node, null);
-        return true;
-    }
-
-    // Three forms of waiting. Each just different enough not to merge
-    // code with others.
-
-    /**
-     * Spin-waits for hole for a non-0 slot.  Fails if spin elapses
-     * before hole filled.  Does not check interrupt, relying on check
-     * in public exchange method to abort if interrupted on entry.
-     *
-     * @param node the waiting node
-     * @return on success, the hole; on failure, CANCEL
-     */
-    private static Object spinWait(Node node, Slot slot) {
-        int spins = SPINS;
-        for (;;) {
-            Object v = node.get();
-            if (v != null)
-                return v;
-            else if (spins > 0)
-                --spins;
-            else
-                tryCancel(node, slot);
-        }
-    }
+    private final Object slotExchange(Object item, boolean timed, long ns) {
+        Node p = participant.get();
+        Thread t = Thread.currentThread();
+        if (t.isInterrupted()) // preserve interrupt status so caller can recheck
+            return null;
 
-    /**
-     * Waits for (by spinning and/or blocking) and gets the hole
-     * filled in by another thread.  Fails if interrupted before
-     * hole filled.
-     *
-     * When a node/thread is about to block, it sets its waiter field
-     * and then rechecks state at least one more time before actually
-     * parking, thus covering race vs fulfiller noticing that waiter
-     * is non-null so should be woken.
-     *
-     * Thread interruption status is checked only surrounding calls to
-     * park.  The caller is assumed to have checked interrupt status
-     * on entry.
-     *
-     * @param node the waiting node
-     * @return on success, the hole; on failure, CANCEL
-     */
-    private static Object await(Node node, Slot slot) {
-        Thread w = Thread.currentThread();
-        int spins = SPINS;
-        for (;;) {
-            Object v = node.get();
-            if (v != null)
-                return v;
-            else if (spins > 0)                 // Spin-wait phase
-                --spins;
-            else if (node.waiter == null)       // Set up to block next
-                node.waiter = w;
-            else if (w.isInterrupted())         // Abort on interrupt
-                tryCancel(node, slot);
-            else                                // Block
-                LockSupport.park(node);
-        }
-    }
-
-    /**
-     * Waits for (at index 0) and gets the hole filled in by another
-     * thread.  Fails if timed out or interrupted before hole filled.
-     * Same basic logic as untimed version, but a bit messier.
-     *
-     * @param node the waiting node
-     * @param nanos the wait time
-     * @return on success, the hole; on failure, CANCEL
-     */
-    private Object awaitNanos(Node node, Slot slot, long nanos) {
-        int spins = TIMED_SPINS;
-        long lastTime = 0;
-        Thread w = null;
-        for (;;) {
-            Object v = node.get();
-            if (v != null)
-                return v;
-            long now = System.nanoTime();
-            if (w == null)
-                w = Thread.currentThread();
-            else
-                nanos -= now - lastTime;
-            lastTime = now;
-            if (nanos > 0) {
-                if (spins > 0)
-                    --spins;
-                else if (node.waiter == null)
-                    node.waiter = w;
-                else if (w.isInterrupted())
-                    tryCancel(node, slot);
-                else
-                    LockSupport.parkNanos(node, nanos);
+        for (Node q;;) {
+            if ((q = slot) != null) {
+                if (U.compareAndSwapObject(this, SLOT, q, null)) {
+                    Object v = q.item;
+                    q.match = item;
+                    Thread w = q.parked;
+                    if (w != null)
+                        U.unpark(w);
+                    return v;
+                }
+                // create arena on contention, but continue until slot null
+                if (NCPU > 1 && bound == 0 &&
+                    U.compareAndSwapInt(this, BOUND, 0, SEQ))
+                    arena = new Node[(FULL + 2) << ASHIFT];
             }
-            else if (tryCancel(node, slot) && !w.isInterrupted())
-                return scanOnTimeout(node);
-        }
-    }
-
-    /**
-     * Sweeps through arena checking for any waiting threads.  Called
-     * only upon return from timeout while waiting in slot 0.  When a
-     * thread gives up on a timed wait, it is possible that a
-     * previously-entered thread is still waiting in some other
-     * slot.  So we scan to check for any.  This is almost always
-     * overkill, but decreases the likelihood of timeouts when there
-     * are other threads present to far less than that in lock-based
-     * exchangers in which earlier-arriving threads may still be
-     * waiting on entry locks.
-     *
-     * @param node the waiting node
-     * @return another thread's item, or CANCEL
-     */
-    private Object scanOnTimeout(Node node) {
-        Object y;
-        for (int j = arena.length - 1; j >= 0; --j) {
-            Slot slot = arena[j];
-            if (slot != null) {
-                while ((y = slot.get()) != null) {
-                    if (slot.compareAndSet(y, null)) {
-                        Node you = (Node)y;
-                        if (you.compareAndSet(null, node.item)) {
-                            LockSupport.unpark(you.waiter);
-                            return you.item;
-                        }
-                    }
-                }
+            else if (arena != null)
+                return null; // caller must reroute to arenaExchange
+            else {
+                p.item = item;
+                if (U.compareAndSwapObject(this, SLOT, null, p))
+                    break;
+                p.item = null;
             }
         }
-        return CANCEL;
+
+        // await release
+        int h = p.hash;
+        long end = timed ? System.nanoTime() + ns : 0L;
+        int spins = (NCPU > 1) ? SPINS : 1;
+        Object v;
+        while ((v = p.match) == null) {
+            if (spins > 0) {
+                h ^= h << 1; h ^= h >>> 3; h ^= h << 10;
+                if (h == 0)
+                    h = SPINS | (int)t.getId();
+                else if (h < 0 && (--spins & ((SPINS >>> 1) - 1)) == 0)
+                    Thread.yield();
+            }
+            else if (slot != p)
+                spins = SPINS;
+            else if (!t.isInterrupted() && arena == null &&
+                     (!timed || (ns = end - System.nanoTime()) > 0L)) {
+                U.putObject(t, BLOCKER, this);
+                p.parked = t;
+                if (slot == p)
+                    U.park(false, ns);
+                p.parked = null;
+                U.putObject(t, BLOCKER, null);
+            }
+            else if (U.compareAndSwapObject(this, SLOT, p, null)) {
+                v = timed && ns <= 0L && !t.isInterrupted() ? TIMED_OUT : null;
+                break;
+            }
+        }
+        U.putOrderedObject(p, MATCH, null);
+        p.item = null;
+        p.hash = h;
+        return v;
     }
 
     /**
      * Creates a new Exchanger.
      */
     public Exchanger() {
+        participant = new Participant();
     }
 
     /**
@@ -620,15 +559,14 @@
      */
     @SuppressWarnings("unchecked")
     public V exchange(V x) throws InterruptedException {
-        if (!Thread.interrupted()) {
-            Object o = doExchange((x == null) ? NULL_ITEM : x, false, 0);
-            if (o == NULL_ITEM)
-                return null;
-            if (o != CANCEL)
-                return (V)o;
-            Thread.interrupted(); // Clear interrupt status on IE throw
-        }
-        throw new InterruptedException();
+        Object v;
+        Object item = (x == null) ? NULL_ITEM : x; // translate null args
+        if ((arena != null ||
+             (v = slotExchange(item, false, 0L)) == null) &&
+            ((Thread.interrupted() || // disambiguates null return
+              (v = arenaExchange(item, false, 0L)) == null)))
+            throw new InterruptedException();
+        return (v == NULL_ITEM) ? null : (V)v;
     }
 
     /**
@@ -666,7 +604,7 @@
      *
      * @param x the object to exchange
      * @param timeout the maximum time to wait
-     * @param unit the time unit of the <tt>timeout</tt> argument
+     * @param unit the time unit of the {@code timeout} argument
      * @return the object provided by the other thread
      * @throws InterruptedException if the current thread was
      *         interrupted while waiting
@@ -676,16 +614,51 @@
     @SuppressWarnings("unchecked")
     public V exchange(V x, long timeout, TimeUnit unit)
         throws InterruptedException, TimeoutException {
-        if (!Thread.interrupted()) {
-            Object o = doExchange((x == null) ? NULL_ITEM : x,
-                                  true, unit.toNanos(timeout));
-            if (o == NULL_ITEM)
-                return null;
-            if (o != CANCEL)
-                return (V)o;
-            if (!Thread.interrupted())
-                throw new TimeoutException();
+        Object v;
+        Object item = (x == null) ? NULL_ITEM : x;
+        long ns = unit.toNanos(timeout);
+        if ((arena != null ||
+             (v = slotExchange(item, true, ns)) == null) &&
+            ((Thread.interrupted() ||
+              (v = arenaExchange(item, true, ns)) == null)))
+            throw new InterruptedException();
+        if (v == TIMED_OUT)
+            throw new TimeoutException();
+        return (v == NULL_ITEM) ? null : (V)v;
+    }
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe U;
+    private static final long BOUND;
+    private static final long SLOT;
+    private static final long MATCH;
+    private static final long BLOCKER;
+    private static final int ABASE;
+    static {
+        int s;
+        try {
+            U = sun.misc.Unsafe.getUnsafe();
+            Class<?> ek = Exchanger.class;
+            Class<?> nk = Node.class;
+            Class<?> ak = Node[].class;
+            Class<?> tk = Thread.class;
+            BOUND = U.objectFieldOffset
+                (ek.getDeclaredField("bound"));
+            SLOT = U.objectFieldOffset
+                (ek.getDeclaredField("slot"));
+            MATCH = U.objectFieldOffset
+                (nk.getDeclaredField("match"));
+            BLOCKER = U.objectFieldOffset
+                (tk.getDeclaredField("parkBlocker"));
+            s = U.arrayIndexScale(ak);
+            // ABASE absorbs padding in front of element 0
+            ABASE = U.arrayBaseOffset(ak) + (1 << ASHIFT);
+
+        } catch (Exception e) {
+            throw new Error(e);
         }
-        throw new InterruptedException();
+        if ((s & (s-1)) != 0 || s > (1 << ASHIFT))
+            throw new Error("Unsupported array scale");
     }
+
 }
--- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Wed Jul 03 14:35:10 2013 -0700
@@ -41,12 +41,15 @@
 import java.util.NoSuchElementException;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
 
 /**
  * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on
  * linked nodes.
  *
- * <p> The optional capacity bound constructor argument serves as a
+ * <p>The optional capacity bound constructor argument serves as a
  * way to prevent excessive expansion. The capacity, if unspecified,
  * is equal to {@link Integer#MAX_VALUE}.  Linked nodes are
  * dynamically created upon each insertion unless this would bring the
@@ -315,8 +318,8 @@
     // BlockingDeque methods
 
     /**
-     * @throws IllegalStateException {@inheritDoc}
-     * @throws NullPointerException  {@inheritDoc}
+     * @throws IllegalStateException if this deque is full
+     * @throws NullPointerException {@inheritDoc}
      */
     public void addFirst(E e) {
         if (!offerFirst(e))
@@ -324,7 +327,7 @@
     }
 
     /**
-     * @throws IllegalStateException {@inheritDoc}
+     * @throws IllegalStateException if this deque is full
      * @throws NullPointerException  {@inheritDoc}
      */
     public void addLast(E e) {
@@ -623,8 +626,7 @@
      *
      * <p>This method is equivalent to {@link #addLast}.
      *
-     * @throws IllegalStateException if the element cannot be added at this
-     *         time due to capacity restrictions
+     * @throws IllegalStateException if this deque is full
      * @throws NullPointerException if the specified element is null
      */
     public boolean add(E e) {
@@ -761,8 +763,8 @@
     // Stack methods
 
     /**
-     * @throws IllegalStateException {@inheritDoc}
-     * @throws NullPointerException  {@inheritDoc}
+     * @throws IllegalStateException if this deque is full
+     * @throws NullPointerException {@inheritDoc}
      */
     public void push(E e) {
         addFirst(e);
@@ -852,7 +854,7 @@
 //      * @throws ClassCastException            {@inheritDoc}
 //      * @throws NullPointerException          {@inheritDoc}
 //      * @throws IllegalArgumentException      {@inheritDoc}
-//      * @throws IllegalStateException         {@inheritDoc}
+//      * @throws IllegalStateException if this deque is full
 //      * @see #add(Object)
 //      */
 //     public boolean addAll(Collection<? extends E> c) {
@@ -1151,6 +1153,127 @@
         Node<E> nextNode(Node<E> n) { return n.prev; }
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class LBDSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final LinkedBlockingDeque<E> queue;
+        Node<E> current;    // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        long est;           // size estimate
+        LBDSpliterator(LinkedBlockingDeque<E> queue) {
+            this.queue = queue;
+            this.est = queue.size();
+        }
+
+        public long estimateSize() { return est; }
+
+        public Spliterator<E> trySplit() {
+            Node<E> h;
+            final LinkedBlockingDeque<E> q = this.queue;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((h = current) != null || (h = q.first) != null) &&
+                h.next != null) {
+                Object[] a = new Object[n];
+                final ReentrantLock lock = q.lock;
+                int i = 0;
+                Node<E> p = current;
+                lock.lock();
+                try {
+                    if (p != null || (p = q.first) != null) {
+                        do {
+                            if ((a[i] = p.item) != null)
+                                ++i;
+                        } while ((p = p.next) != null && i < n);
+                    }
+                } finally {
+                    lock.unlock();
+                }
+                if ((current = p) == null) {
+                    est = 0L;
+                    exhausted = true;
+                }
+                else if ((est -= i) < 0L)
+                    est = 0L;
+                if (i > 0) {
+                    batch = i;
+                    return Spliterators.spliterator
+                        (a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL |
+                         Spliterator.CONCURRENT);
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            if (action == null) throw new NullPointerException();
+            final LinkedBlockingDeque<E> q = this.queue;
+            final ReentrantLock lock = q.lock;
+            if (!exhausted) {
+                exhausted = true;
+                Node<E> p = current;
+                do {
+                    E e = null;
+                    lock.lock();
+                    try {
+                        if (p == null)
+                            p = q.first;
+                        while (p != null) {
+                            e = p.item;
+                            p = p.next;
+                            if (e != null)
+                                break;
+                        }
+                    } finally {
+                        lock.unlock();
+                    }
+                    if (e != null)
+                        action.accept(e);
+                } while (p != null);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null) throw new NullPointerException();
+            final LinkedBlockingDeque<E> q = this.queue;
+            final ReentrantLock lock = q.lock;
+            if (!exhausted) {
+                E e = null;
+                lock.lock();
+                try {
+                    if (current == null)
+                        current = q.first;
+                    while (current != null) {
+                        e = current.item;
+                        current = current.next;
+                        if (e != null)
+                            break;
+                    }
+                } finally {
+                    lock.unlock();
+                }
+                if (current == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept(e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
+    public Spliterator<E> spliterator() {
+        return new LBDSpliterator<E>(this);
+    }
+
     /**
      * Saves this deque to a stream (that is, serializes it).
      *
--- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Wed Jul 03 14:35:10 2013 -0700
@@ -42,6 +42,9 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
 
 /**
  * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on
@@ -56,7 +59,7 @@
  * Linked queues typically have higher throughput than array-based queues but
  * less predictable performance in most concurrent applications.
  *
- * <p> The optional capacity bound constructor argument serves as a
+ * <p>The optional capacity bound constructor argument serves as a
  * way to prevent excessive queue expansion. The capacity, if unspecified,
  * is equal to {@link Integer#MAX_VALUE}.  Linked nodes are
  * dynamically created upon each insertion unless this would bring the
@@ -216,7 +219,7 @@
     }
 
     /**
-     * Lock to prevent both puts and takes.
+     * Locks to prevent both puts and takes.
      */
     void fullyLock() {
         putLock.lock();
@@ -224,7 +227,7 @@
     }
 
     /**
-     * Unlock to allow both puts and takes.
+     * Unlocks to allow both puts and takes.
      */
     void fullyUnlock() {
         takeLock.unlock();
@@ -362,7 +365,7 @@
      * necessary up to the specified wait time for space to become available.
      *
      * @return {@code true} if successful, or {@code false} if
-     *         the specified waiting time elapses before space is available.
+     *         the specified waiting time elapses before space is available
      * @throws InterruptedException {@inheritDoc}
      * @throws NullPointerException {@inheritDoc}
      */
@@ -782,6 +785,7 @@
          * item to hand out so that if hasNext() reports true, we will
          * still have it to return even if lost race with a take etc.
          */
+
         private Node<E> current;
         private Node<E> lastRet;
         private E currentElement;
@@ -855,6 +859,124 @@
         }
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class LBQSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final LinkedBlockingQueue<E> queue;
+        Node<E> current;    // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        long est;           // size estimate
+        LBQSpliterator(LinkedBlockingQueue<E> queue) {
+            this.queue = queue;
+            this.est = queue.size();
+        }
+
+        public long estimateSize() { return est; }
+
+        public Spliterator<E> trySplit() {
+            Node<E> h;
+            final LinkedBlockingQueue<E> q = this.queue;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((h = current) != null || (h = q.head.next) != null) &&
+                h.next != null) {
+                Object[] a = new Object[n];
+                int i = 0;
+                Node<E> p = current;
+                q.fullyLock();
+                try {
+                    if (p != null || (p = q.head.next) != null) {
+                        do {
+                            if ((a[i] = p.item) != null)
+                                ++i;
+                        } while ((p = p.next) != null && i < n);
+                    }
+                } finally {
+                    q.fullyUnlock();
+                }
+                if ((current = p) == null) {
+                    est = 0L;
+                    exhausted = true;
+                }
+                else if ((est -= i) < 0L)
+                    est = 0L;
+                if (i > 0) {
+                    batch = i;
+                    return Spliterators.spliterator
+                        (a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL |
+                         Spliterator.CONCURRENT);
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            if (action == null) throw new NullPointerException();
+            final LinkedBlockingQueue<E> q = this.queue;
+            if (!exhausted) {
+                exhausted = true;
+                Node<E> p = current;
+                do {
+                    E e = null;
+                    q.fullyLock();
+                    try {
+                        if (p == null)
+                            p = q.head.next;
+                        while (p != null) {
+                            e = p.item;
+                            p = p.next;
+                            if (e != null)
+                                break;
+                        }
+                    } finally {
+                        q.fullyUnlock();
+                    }
+                    if (e != null)
+                        action.accept(e);
+                } while (p != null);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null) throw new NullPointerException();
+            final LinkedBlockingQueue<E> q = this.queue;
+            if (!exhausted) {
+                E e = null;
+                q.fullyLock();
+                try {
+                    if (current == null)
+                        current = q.head.next;
+                    while (current != null) {
+                        e = current.item;
+                        current = current.next;
+                        if (e != null)
+                            break;
+                    }
+                } finally {
+                    q.fullyUnlock();
+                }
+                if (current == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept(e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
+    public Spliterator<E> spliterator() {
+        return new LBQSpliterator<E>(this);
+    }
+
     /**
      * Saves this queue to a stream (that is, serializes it).
      *
--- a/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java	Wed Jul 03 14:35:10 2013 -0700
@@ -40,8 +40,10 @@
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 import java.util.Queue;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.LockSupport;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
 
 /**
  * An unbounded {@link TransferQueue} based on linked nodes.
@@ -777,6 +779,24 @@
     }
 
     /**
+     * Version of firstOfMode used by Spliterator
+     */
+    final Node firstDataNode() {
+        for (Node p = head; p != null;) {
+            Object item = p.item;
+            if (p.isData) {
+                if (item != null && item != p)
+                    return p;
+            }
+            else if (item == null)
+                break;
+            if (p == (p = p.next))
+                p = head;
+        }
+        return null;
+    }
+
+    /**
      * Returns the item in the first unmatched node with isData; or
      * null if none.  Used by peek.
      */
@@ -910,6 +930,98 @@
         }
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class LTQSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final LinkedTransferQueue<E> queue;
+        Node current;    // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        LTQSpliterator(LinkedTransferQueue<E> queue) {
+            this.queue = queue;
+        }
+
+        public Spliterator<E> trySplit() {
+            Node p;
+            final LinkedTransferQueue<E> q = this.queue;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.firstDataNode()) != null) &&
+                p.next != null) {
+                Object[] a = new Object[n];
+                int i = 0;
+                do {
+                    if ((a[i] = p.item) != null)
+                        ++i;
+                    if (p == (p = p.next))
+                        p = q.firstDataNode();
+                } while (p != null && i < n);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (i > 0) {
+                    batch = i;
+                    return Spliterators.spliterator
+                        (a, 0, i, Spliterator.ORDERED | Spliterator.NONNULL |
+                         Spliterator.CONCURRENT);
+                }
+            }
+            return null;
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super E> action) {
+            Node p;
+            if (action == null) throw new NullPointerException();
+            final LinkedTransferQueue<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.firstDataNode()) != null)) {
+                exhausted = true;
+                do {
+                    Object e = p.item;
+                    if (p == (p = p.next))
+                        p = q.firstDataNode();
+                    if (e != null)
+                        action.accept((E)e);
+                } while (p != null);
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        public boolean tryAdvance(Consumer<? super E> action) {
+            Node p;
+            if (action == null) throw new NullPointerException();
+            final LinkedTransferQueue<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.firstDataNode()) != null)) {
+                Object e;
+                do {
+                    e = p.item;
+                    if (p == (p = p.next))
+                        p = q.firstDataNode();
+                } while (e == null && p != null);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept((E)e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public long estimateSize() { return Long.MAX_VALUE; }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
+    public Spliterator<E> spliterator() {
+        return new LTQSpliterator<E>(this);
+    }
+
     /* -------------- Removal methods -------------- */
 
     /**
--- a/jdk/src/share/classes/java/util/concurrent/Phaser.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Phaser.java	Wed Jul 03 14:35:10 2013 -0700
@@ -46,7 +46,7 @@
  * {@link java.util.concurrent.CountDownLatch CountDownLatch}
  * but supporting more flexible usage.
  *
- * <p> <b>Registration.</b> Unlike the case for other barriers, the
+ * <p><b>Registration.</b> Unlike the case for other barriers, the
  * number of parties <em>registered</em> to synchronize on a phaser
  * may vary over time.  Tasks may be registered at any time (using
  * methods {@link #register}, {@link #bulkRegister}, or forms of
@@ -59,7 +59,7 @@
  * (However, you can introduce such bookkeeping by subclassing this
  * class.)
  *
- * <p> <b>Synchronization.</b> Like a {@code CyclicBarrier}, a {@code
+ * <p><b>Synchronization.</b> Like a {@code CyclicBarrier}, a {@code
  * Phaser} may be repeatedly awaited.  Method {@link
  * #arriveAndAwaitAdvance} has effect analogous to {@link
  * java.util.concurrent.CyclicBarrier#await CyclicBarrier.await}. Each
@@ -103,7 +103,7 @@
  *
  * </ul>
  *
- * <p> <b>Termination.</b> A phaser may enter a <em>termination</em>
+ * <p><b>Termination.</b> A phaser may enter a <em>termination</em>
  * state, that may be checked using method {@link #isTerminated}. Upon
  * termination, all synchronization methods immediately return without
  * waiting for advance, as indicated by a negative return value.
@@ -118,7 +118,7 @@
  * also available to abruptly release waiting threads and allow them
  * to terminate.
  *
- * <p> <b>Tiering.</b> Phasers may be <em>tiered</em> (i.e.,
+ * <p><b>Tiering.</b> Phasers may be <em>tiered</em> (i.e.,
  * constructed in tree structures) to reduce contention. Phasers with
  * large numbers of parties that would otherwise experience heavy
  * synchronization contention costs may instead be set up so that
@@ -300,18 +300,20 @@
     private static final int  PHASE_SHIFT     = 32;
     private static final int  UNARRIVED_MASK  = 0xffff;      // to mask ints
     private static final long PARTIES_MASK    = 0xffff0000L; // to mask longs
+    private static final long COUNTS_MASK     = 0xffffffffL;
     private static final long TERMINATION_BIT = 1L << 63;
 
     // some special values
     private static final int  ONE_ARRIVAL     = 1;
     private static final int  ONE_PARTY       = 1 << PARTIES_SHIFT;
+    private static final int  ONE_DEREGISTER  = ONE_ARRIVAL|ONE_PARTY;
     private static final int  EMPTY           = 1;
 
     // The following unpacking methods are usually manually inlined
 
     private static int unarrivedOf(long s) {
         int counts = (int)s;
-        return (counts == EMPTY) ? 0 : counts & UNARRIVED_MASK;
+        return (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);
     }
 
     private static int partiesOf(long s) {
@@ -372,37 +374,44 @@
      * Manually tuned to speed up and minimize race windows for the
      * common case of just decrementing unarrived field.
      *
-     * @param deregister false for arrive, true for arriveAndDeregister
+     * @param adjust value to subtract from state;
+     *               ONE_ARRIVAL for arrive,
+     *               ONE_DEREGISTER for arriveAndDeregister
      */
-    private int doArrive(boolean deregister) {
-        int adj = deregister ? ONE_ARRIVAL|ONE_PARTY : ONE_ARRIVAL;
+    private int doArrive(int adjust) {
         final Phaser root = this.root;
         for (;;) {
             long s = (root == this) ? state : reconcileState();
             int phase = (int)(s >>> PHASE_SHIFT);
-            int counts = (int)s;
-            int unarrived = (counts & UNARRIVED_MASK) - 1;
             if (phase < 0)
                 return phase;
-            else if (counts == EMPTY || unarrived < 0) {
-                if (root == this || reconcileState() == s)
-                    throw new IllegalStateException(badArrive(s));
-            }
-            else if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adj)) {
-                if (unarrived == 0) {
+            int counts = (int)s;
+            int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);
+            if (unarrived <= 0)
+                throw new IllegalStateException(badArrive(s));
+            if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adjust)) {
+                if (unarrived == 1) {
                     long n = s & PARTIES_MASK;  // base of next state
                     int nextUnarrived = (int)n >>> PARTIES_SHIFT;
-                    if (root != this)
-                        return parent.doArrive(nextUnarrived == 0);
-                    if (onAdvance(phase, nextUnarrived))
-                        n |= TERMINATION_BIT;
-                    else if (nextUnarrived == 0)
-                        n |= EMPTY;
+                    if (root == this) {
+                        if (onAdvance(phase, nextUnarrived))
+                            n |= TERMINATION_BIT;
+                        else if (nextUnarrived == 0)
+                            n |= EMPTY;
+                        else
+                            n |= nextUnarrived;
+                        int nextPhase = (phase + 1) & MAX_PHASE;
+                        n |= (long)nextPhase << PHASE_SHIFT;
+                        UNSAFE.compareAndSwapLong(this, stateOffset, s, n);
+                        releaseWaiters(phase);
+                    }
+                    else if (nextUnarrived == 0) { // propagate deregistration
+                        phase = parent.doArrive(ONE_DEREGISTER);
+                        UNSAFE.compareAndSwapLong(this, stateOffset,
+                                                  s, s | EMPTY);
+                    }
                     else
-                        n |= nextUnarrived;
-                    n |= (long)((phase + 1) & MAX_PHASE) << PHASE_SHIFT;
-                    UNSAFE.compareAndSwapLong(this, stateOffset, s, n);
-                    releaseWaiters(phase);
+                        phase = parent.doArrive(ONE_ARRIVAL);
                 }
                 return phase;
             }
@@ -417,42 +426,49 @@
      */
     private int doRegister(int registrations) {
         // adjustment to state
-        long adj = ((long)registrations << PARTIES_SHIFT) | registrations;
+        long adjust = ((long)registrations << PARTIES_SHIFT) | registrations;
         final Phaser parent = this.parent;
         int phase;
         for (;;) {
-            long s = state;
+            long s = (parent == null) ? state : reconcileState();
             int counts = (int)s;
             int parties = counts >>> PARTIES_SHIFT;
             int unarrived = counts & UNARRIVED_MASK;
             if (registrations > MAX_PARTIES - parties)
                 throw new IllegalStateException(badRegister(s));
-            else if ((phase = (int)(s >>> PHASE_SHIFT)) < 0)
+            phase = (int)(s >>> PHASE_SHIFT);
+            if (phase < 0)
                 break;
-            else if (counts != EMPTY) {             // not 1st registration
+            if (counts != EMPTY) {                  // not 1st registration
                 if (parent == null || reconcileState() == s) {
                     if (unarrived == 0)             // wait out advance
                         root.internalAwaitAdvance(phase, null);
                     else if (UNSAFE.compareAndSwapLong(this, stateOffset,
-                                                       s, s + adj))
+                                                       s, s + adjust))
                         break;
                 }
             }
             else if (parent == null) {              // 1st root registration
-                long next = ((long)phase << PHASE_SHIFT) | adj;
+                long next = ((long)phase << PHASE_SHIFT) | adjust;
                 if (UNSAFE.compareAndSwapLong(this, stateOffset, s, next))
                     break;
             }
             else {
                 synchronized (this) {               // 1st sub registration
                     if (state == s) {               // recheck under lock
-                        parent.doRegister(1);
-                        do {                        // force current phase
+                        phase = parent.doRegister(1);
+                        if (phase < 0)
+                            break;
+                        // finish registration whenever parent registration
+                        // succeeded, even when racing with termination,
+                        // since these are part of the same "transaction".
+                        while (!UNSAFE.compareAndSwapLong
+                               (this, stateOffset, s,
+                                ((long)phase << PHASE_SHIFT) | adjust)) {
+                            s = state;
                             phase = (int)(root.state >>> PHASE_SHIFT);
-                            // assert phase < 0 || (int)state == EMPTY;
-                        } while (!UNSAFE.compareAndSwapLong
-                                 (this, stateOffset, state,
-                                  ((long)phase << PHASE_SHIFT) | adj));
+                            // assert (int)s == EMPTY;
+                        }
                         break;
                     }
                 }
@@ -467,10 +483,6 @@
      * subphasers have not yet done so, in which case they must finish
      * their own advance by setting unarrived to parties (or if
      * parties is zero, resetting to unregistered EMPTY state).
-     * However, this method may also be called when "floating"
-     * subphasers with possibly some unarrived parties are merely
-     * catching up to current phase, in which case counts are
-     * unaffected.
      *
      * @return reconciled state
      */
@@ -478,16 +490,16 @@
         final Phaser root = this.root;
         long s = state;
         if (root != this) {
-            int phase, u, p;
-            // CAS root phase with current parties; possibly trip unarrived
+            int phase, p;
+            // CAS to root phase with current parties, tripping unarrived
             while ((phase = (int)(root.state >>> PHASE_SHIFT)) !=
                    (int)(s >>> PHASE_SHIFT) &&
                    !UNSAFE.compareAndSwapLong
                    (this, stateOffset, s,
                     s = (((long)phase << PHASE_SHIFT) |
-                         (s & PARTIES_MASK) |
-                         ((p = (int)s >>> PARTIES_SHIFT) == 0 ? EMPTY :
-                          (u = (int)s & UNARRIVED_MASK) == 0 ? p : u))))
+                         ((phase < 0) ? (s & COUNTS_MASK) :
+                          (((p = (int)s >>> PARTIES_SHIFT) == 0) ? EMPTY :
+                           ((s & PARTIES_MASK) | p))))))
                 s = state;
         }
         return s;
@@ -619,7 +631,7 @@
      * of unarrived parties would become negative
      */
     public int arrive() {
-        return doArrive(false);
+        return doArrive(ONE_ARRIVAL);
     }
 
     /**
@@ -639,7 +651,7 @@
      * of registered or unarrived parties would become negative
      */
     public int arriveAndDeregister() {
-        return doArrive(true);
+        return doArrive(ONE_DEREGISTER);
     }
 
     /**
@@ -666,17 +678,15 @@
         for (;;) {
             long s = (root == this) ? state : reconcileState();
             int phase = (int)(s >>> PHASE_SHIFT);
-            int counts = (int)s;
-            int unarrived = (counts & UNARRIVED_MASK) - 1;
             if (phase < 0)
                 return phase;
-            else if (counts == EMPTY || unarrived < 0) {
-                if (reconcileState() == s)
-                    throw new IllegalStateException(badArrive(s));
-            }
-            else if (UNSAFE.compareAndSwapLong(this, stateOffset, s,
-                                               s -= ONE_ARRIVAL)) {
-                if (unarrived != 0)
+            int counts = (int)s;
+            int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);
+            if (unarrived <= 0)
+                throw new IllegalStateException(badArrive(s));
+            if (UNSAFE.compareAndSwapLong(this, stateOffset, s,
+                                          s -= ONE_ARRIVAL)) {
+                if (unarrived > 1)
                     return root.internalAwaitAdvance(phase, null);
                 if (root != this)
                     return parent.arriveAndAwaitAdvance();
@@ -809,8 +819,8 @@
             if (UNSAFE.compareAndSwapLong(root, stateOffset,
                                           s, s | TERMINATION_BIT)) {
                 // signal all threads
-                releaseWaiters(0);
-                releaseWaiters(1);
+                releaseWaiters(0); // Waiters on evenQ
+                releaseWaiters(1); // Waiters on oddQ
                 return;
             }
         }
@@ -1016,7 +1026,7 @@
 
     /**
      * Possibly blocks and waits for phase to advance unless aborted.
-     * Call only from root node.
+     * Call only on root phaser.
      *
      * @param phase current phase
      * @param node if non-null, the wait node to track interrupt and timeout;
@@ -1024,6 +1034,7 @@
      * @return current phase
      */
     private int internalAwaitAdvance(int phase, QNode node) {
+        // assert root == this;
         releaseWaiters(phase-1);          // ensure old queue clean
         boolean queued = false;           // true when node is enqueued
         int lastUnarrived = 0;            // to increase spins upon change
@@ -1082,7 +1093,7 @@
         final boolean timed;
         boolean wasInterrupted;
         long nanos;
-        long lastTime;
+        final long deadline;
         volatile Thread thread; // nulled to cancel wait
         QNode next;
 
@@ -1093,7 +1104,7 @@
             this.interruptible = interruptible;
             this.nanos = nanos;
             this.timed = timed;
-            this.lastTime = timed ? System.nanoTime() : 0L;
+            this.deadline = timed ? System.nanoTime() + nanos : 0L;
             thread = Thread.currentThread();
         }
 
@@ -1112,9 +1123,7 @@
             }
             if (timed) {
                 if (nanos > 0L) {
-                    long now = System.nanoTime();
-                    nanos -= now - lastTime;
-                    lastTime = now;
+                    nanos = deadline - System.nanoTime();
                 }
                 if (nanos <= 0L) {
                     thread = null;
@@ -1129,7 +1138,7 @@
                 return true;
             else if (!timed)
                 LockSupport.park(this);
-            else if (nanos > 0)
+            else if (nanos > 0L)
                 LockSupport.parkNanos(this, nanos);
             return isReleasable();
         }
--- a/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Wed Jul 03 14:35:10 2013 -0700
@@ -37,7 +37,17 @@
 
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.*;
+import java.util.AbstractQueue;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.PriorityQueue;
+import java.util.Queue;
+import java.util.SortedSet;
+import java.util.Spliterator;
+import java.util.function.Consumer;
 
 /**
  * An unbounded {@linkplain BlockingQueue blocking queue} that uses
@@ -342,7 +352,6 @@
      * @param k the position to fill
      * @param x the item to insert
      * @param array the heap array
-     * @param n heap size
      */
     private static <T> void siftUpComparable(int k, T x, Object[] array) {
         Comparable<? super T> key = (Comparable<? super T>) x;
@@ -936,6 +945,70 @@
         }
     }
 
+    // Similar to Collections.ArraySnapshotSpliterator but avoids
+    // commitment to toArray until needed
+    static final class PBQSpliterator<E> implements Spliterator<E> {
+        final PriorityBlockingQueue<E> queue;
+        Object[] array;
+        int index;
+        int fence;
+
+        PBQSpliterator(PriorityBlockingQueue<E> queue, Object[] array,
+                       int index, int fence) {
+            this.queue = queue;
+            this.array = array;
+            this.index = index;
+            this.fence = fence;
+        }
+
+        final int getFence() {
+            int hi;
+            if ((hi = fence) < 0)
+                hi = fence = (array = queue.toArray()).length;
+            return hi;
+        }
+
+        public Spliterator<E> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid) ? null :
+                new PBQSpliterator<E>(queue, array, lo, index = mid);
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super E> action) {
+            Object[] a; int i, hi; // hoist accesses and checks from loop
+            if (action == null)
+                throw new NullPointerException();
+            if ((a = array) == null)
+                fence = (a = queue.toArray()).length;
+            if ((hi = fence) <= a.length &&
+                (i = index) >= 0 && i < (index = hi)) {
+                do { action.accept((E)a[i]); } while (++i < hi);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null)
+                throw new NullPointerException();
+            if (getFence() > index && index >= 0) {
+                @SuppressWarnings("unchecked") E e = (E) array[index++];
+                action.accept(e);
+                return true;
+            }
+            return false;
+        }
+
+        public long estimateSize() { return (long)(getFence() - index); }
+
+        public int characteristics() {
+            return Spliterator.NONNULL | Spliterator.SIZED | Spliterator.SUBSIZED;
+        }
+    }
+
+    public Spliterator<E> spliterator() {
+        return new PBQSpliterator<E>(this, null, 0, -1);
+    }
+
     // Unsafe mechanics
     private static final sun.misc.Unsafe UNSAFE;
     private static final long allocationSpinLockOffset;
--- a/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java	Wed Jul 03 14:35:10 2013 -0700
@@ -44,17 +44,17 @@
  * operation must wait for a corresponding remove operation by another
  * thread, and vice versa.  A synchronous queue does not have any
  * internal capacity, not even a capacity of one.  You cannot
- * <tt>peek</tt> at a synchronous queue because an element is only
+ * {@code peek} at a synchronous queue because an element is only
  * present when you try to remove it; you cannot insert an element
  * (using any method) unless another thread is trying to remove it;
  * you cannot iterate as there is nothing to iterate.  The
  * <em>head</em> of the queue is the element that the first queued
  * inserting thread is trying to add to the queue; if there is no such
  * queued thread then no element is available for removal and
- * <tt>poll()</tt> will return <tt>null</tt>.  For purposes of other
- * <tt>Collection</tt> methods (for example <tt>contains</tt>), a
- * <tt>SynchronousQueue</tt> acts as an empty collection.  This queue
- * does not permit <tt>null</tt> elements.
+ * {@code poll()} will return {@code null}.  For purposes of other
+ * {@code Collection} methods (for example {@code contains}), a
+ * {@code SynchronousQueue} acts as an empty collection.  This queue
+ * does not permit {@code null} elements.
  *
  * <p>Synchronous queues are similar to rendezvous channels used in
  * CSP and Ada. They are well suited for handoff designs, in which an
@@ -62,10 +62,10 @@
  * in another thread in order to hand it some information, event, or
  * task.
  *
- * <p> This class supports an optional fairness policy for ordering
+ * <p>This class supports an optional fairness policy for ordering
  * waiting producer and consumer threads.  By default, this ordering
  * is not guaranteed. However, a queue constructed with fairness set
- * to <tt>true</tt> grants threads access in FIFO order.
+ * to {@code true} grants threads access in FIFO order.
  *
  * <p>This class and its iterator implement all of the
  * <em>optional</em> methods of the {@link Collection} and {@link
@@ -599,7 +599,7 @@
         /**
          * Reference to a cancelled node that might not yet have been
          * unlinked from queue because it was the last inserted node
-         * when it cancelled.
+         * when it was cancelled.
          */
         transient volatile QNode cleanMe;
 
@@ -847,14 +847,14 @@
     private transient volatile Transferer<E> transferer;
 
     /**
-     * Creates a <tt>SynchronousQueue</tt> with nonfair access policy.
+     * Creates a {@code SynchronousQueue} with nonfair access policy.
      */
     public SynchronousQueue() {
         this(false);
     }
 
     /**
-     * Creates a <tt>SynchronousQueue</tt> with the specified fairness policy.
+     * Creates a {@code SynchronousQueue} with the specified fairness policy.
      *
      * @param fair if true, waiting threads contend in FIFO order for
      *        access; otherwise the order is unspecified.
@@ -882,8 +882,8 @@
      * Inserts the specified element into this queue, waiting if necessary
      * up to the specified wait time for another thread to receive it.
      *
-     * @return <tt>true</tt> if successful, or <tt>false</tt> if the
-     *         specified waiting time elapses before a consumer appears.
+     * @return {@code true} if successful, or {@code false} if the
+     *         specified waiting time elapses before a consumer appears
      * @throws InterruptedException {@inheritDoc}
      * @throws NullPointerException {@inheritDoc}
      */
@@ -902,8 +902,8 @@
      * waiting to receive it.
      *
      * @param e the element to add
-     * @return <tt>true</tt> if the element was added to this queue, else
-     *         <tt>false</tt>
+     * @return {@code true} if the element was added to this queue, else
+     *         {@code false}
      * @throws NullPointerException if the specified element is null
      */
     public boolean offer(E e) {
@@ -931,8 +931,8 @@
      * if necessary up to the specified wait time, for another thread
      * to insert it.
      *
-     * @return the head of this queue, or <tt>null</tt> if the
-     *         specified waiting time elapses before an element is present.
+     * @return the head of this queue, or {@code null} if the
+     *         specified waiting time elapses before an element is present
      * @throws InterruptedException {@inheritDoc}
      */
     public E poll(long timeout, TimeUnit unit) throws InterruptedException {
@@ -946,18 +946,18 @@
      * Retrieves and removes the head of this queue, if another thread
      * is currently making an element available.
      *
-     * @return the head of this queue, or <tt>null</tt> if no
-     *         element is available.
+     * @return the head of this queue, or {@code null} if no
+     *         element is available
      */
     public E poll() {
         return transferer.transfer(null, true, 0);
     }
 
     /**
-     * Always returns <tt>true</tt>.
-     * A <tt>SynchronousQueue</tt> has no internal capacity.
+     * Always returns {@code true}.
+     * A {@code SynchronousQueue} has no internal capacity.
      *
-     * @return <tt>true</tt>
+     * @return {@code true}
      */
     public boolean isEmpty() {
         return true;
@@ -965,9 +965,9 @@
 
     /**
      * Always returns zero.
-     * A <tt>SynchronousQueue</tt> has no internal capacity.
+     * A {@code SynchronousQueue} has no internal capacity.
      *
-     * @return zero.
+     * @return zero
      */
     public int size() {
         return 0;
@@ -975,9 +975,9 @@
 
     /**
      * Always returns zero.
-     * A <tt>SynchronousQueue</tt> has no internal capacity.
+     * A {@code SynchronousQueue} has no internal capacity.
      *
-     * @return zero.
+     * @return zero
      */
     public int remainingCapacity() {
         return 0;
@@ -985,80 +985,80 @@
 
     /**
      * Does nothing.
-     * A <tt>SynchronousQueue</tt> has no internal capacity.
+     * A {@code SynchronousQueue} has no internal capacity.
      */
     public void clear() {
     }
 
     /**
-     * Always returns <tt>false</tt>.
-     * A <tt>SynchronousQueue</tt> has no internal capacity.
+     * Always returns {@code false}.
+     * A {@code SynchronousQueue} has no internal capacity.
      *
      * @param o the element
-     * @return <tt>false</tt>
+     * @return {@code false}
      */
     public boolean contains(Object o) {
         return false;
     }
 
     /**
-     * Always returns <tt>false</tt>.
-     * A <tt>SynchronousQueue</tt> has no internal capacity.
+     * Always returns {@code false}.
+     * A {@code SynchronousQueue} has no internal capacity.
      *
      * @param o the element to remove
-     * @return <tt>false</tt>
+     * @return {@code false}
      */
     public boolean remove(Object o) {
         return false;
     }
 
     /**
-     * Returns <tt>false</tt> unless the given collection is empty.
-     * A <tt>SynchronousQueue</tt> has no internal capacity.
+     * Returns {@code false} unless the given collection is empty.
+     * A {@code SynchronousQueue} has no internal capacity.
      *
      * @param c the collection
-     * @return <tt>false</tt> unless given collection is empty
+     * @return {@code false} unless given collection is empty
      */
     public boolean containsAll(Collection<?> c) {
         return c.isEmpty();
     }
 
     /**
-     * Always returns <tt>false</tt>.
-     * A <tt>SynchronousQueue</tt> has no internal capacity.
+     * Always returns {@code false}.
+     * A {@code SynchronousQueue} has no internal capacity.
      *
      * @param c the collection
-     * @return <tt>false</tt>
+     * @return {@code false}
      */
     public boolean removeAll(Collection<?> c) {
         return false;
     }
 
     /**
-     * Always returns <tt>false</tt>.
-     * A <tt>SynchronousQueue</tt> has no internal capacity.
+     * Always returns {@code false}.
+     * A {@code SynchronousQueue} has no internal capacity.
      *
      * @param c the collection
-     * @return <tt>false</tt>
+     * @return {@code false}
      */
     public boolean retainAll(Collection<?> c) {
         return false;
     }
 
     /**
-     * Always returns <tt>null</tt>.
-     * A <tt>SynchronousQueue</tt> does not return elements
+     * Always returns {@code null}.
+     * A {@code SynchronousQueue} does not return elements
      * unless actively waited on.
      *
-     * @return <tt>null</tt>
+     * @return {@code null}
      */
     public E peek() {
         return null;
     }
 
     /**
-     * Returns an empty iterator in which <tt>hasNext</tt> always returns
-     * <tt>false</tt>.
+     * Returns an empty iterator in which {@code hasNext} always returns
+     * {@code false}.
      *
      * @return an empty iterator
      */
@@ -1077,6 +1077,10 @@
         public void remove() { throw new IllegalStateException(); }
     }
 
+    public Spliterator<E> spliterator() {
+        return Spliterators.emptySpliterator();
+    }
+
     /**
      * Returns a zero-length array.
      * @return a zero-length array
@@ -1086,7 +1090,7 @@
     }
 
     /**
-     * Sets the zeroeth element of the specified array to <tt>null</tt>
+     * Sets the zeroeth element of the specified array to {@code null}
      * (if the array has non-zero length) and returns it.
      *
      * @param a the array
--- a/jdk/src/share/classes/java/util/concurrent/TimeUnit.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/TimeUnit.java	Wed Jul 03 14:35:10 2013 -0700
@@ -36,10 +36,10 @@
 package java.util.concurrent;
 
 /**
- * A <tt>TimeUnit</tt> represents time durations at a given unit of
+ * A {@code TimeUnit} represents time durations at a given unit of
  * granularity and provides utility methods to convert across units,
  * and to perform timing and delay operations in these units.  A
- * <tt>TimeUnit</tt> does not maintain time information, but only
+ * {@code TimeUnit} does not maintain time information, but only
  * helps organize and use time representations that may be maintained
  * separately across various contexts.  A nanosecond is defined as one
  * thousandth of a microsecond, a microsecond as one thousandth of a
@@ -47,7 +47,7 @@
  * as sixty seconds, an hour as sixty minutes, and a day as twenty four
  * hours.
  *
- * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
+ * <p>A {@code TimeUnit} is mainly used to inform time-based methods
  * how a given timing parameter should be interpreted. For example,
  * the following code will timeout in 50 milliseconds if the {@link
  * java.util.concurrent.locks.Lock lock} is not available:
@@ -63,7 +63,7 @@
  *
  * Note however, that there is no guarantee that a particular timeout
  * implementation will be able to notice the passage of time at the
- * same granularity as the given <tt>TimeUnit</tt>.
+ * same granularity as the given {@code TimeUnit}.
  *
  * @since 1.5
  * @author Doug Lea
@@ -174,83 +174,82 @@
     // etc. are not declared abstract but otherwise act as abstract methods.
 
     /**
-     * Convert the given time duration in the given unit to this
-     * unit.  Conversions from finer to coarser granularities
-     * truncate, so lose precision. For example converting
-     * <tt>999</tt> milliseconds to seconds results in
-     * <tt>0</tt>. Conversions from coarser to finer granularities
-     * with arguments that would numerically overflow saturate to
-     * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
-     * if positive.
+     * Converts the given time duration in the given unit to this unit.
+     * Conversions from finer to coarser granularities truncate, so
+     * lose precision. For example, converting {@code 999} milliseconds
+     * to seconds results in {@code 0}. Conversions from coarser to
+     * finer granularities with arguments that would numerically
+     * overflow saturate to {@code Long.MIN_VALUE} if negative or
+     * {@code Long.MAX_VALUE} if positive.
      *
      * <p>For example, to convert 10 minutes to milliseconds, use:
-     * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt>
+     * {@code TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)}
      *
-     * @param sourceDuration the time duration in the given <tt>sourceUnit</tt>
-     * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument
+     * @param sourceDuration the time duration in the given {@code sourceUnit}
+     * @param sourceUnit the unit of the {@code sourceDuration} argument
      * @return the converted duration in this unit,
-     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
-     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+     * or {@code Long.MIN_VALUE} if conversion would negatively
+     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long convert(long sourceDuration, TimeUnit sourceUnit) {
         throw new AbstractMethodError();
     }
 
     /**
-     * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
+     * Equivalent to
+     * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
-     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
-     * @see #convert
+     * or {@code Long.MIN_VALUE} if conversion would negatively
+     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long toNanos(long duration) {
         throw new AbstractMethodError();
     }
 
     /**
-     * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
+     * Equivalent to
+     * {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
-     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
-     * @see #convert
+     * or {@code Long.MIN_VALUE} if conversion would negatively
+     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long toMicros(long duration) {
         throw new AbstractMethodError();
     }
 
     /**
-     * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
+     * Equivalent to
+     * {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
-     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
-     * @see #convert
+     * or {@code Long.MIN_VALUE} if conversion would negatively
+     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long toMillis(long duration) {
         throw new AbstractMethodError();
     }
 
     /**
-     * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
+     * Equivalent to
+     * {@link #convert(long, TimeUnit) SECONDS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
-     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
-     * @see #convert
+     * or {@code Long.MIN_VALUE} if conversion would negatively
+     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long toSeconds(long duration) {
         throw new AbstractMethodError();
     }
 
     /**
-     * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
+     * Equivalent to
+     * {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
-     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
-     * @see #convert
+     * or {@code Long.MIN_VALUE} if conversion would negatively
+     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
      * @since 1.6
      */
     public long toMinutes(long duration) {
@@ -258,12 +257,12 @@
     }
 
     /**
-     * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
+     * Equivalent to
+     * {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
-     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
-     * @see #convert
+     * or {@code Long.MIN_VALUE} if conversion would negatively
+     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
      * @since 1.6
      */
     public long toHours(long duration) {
@@ -271,10 +270,10 @@
     }
 
     /**
-     * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
+     * Equivalent to
+     * {@link #convert(long, TimeUnit) DAYS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration
-     * @see #convert
      * @since 1.6
      */
     public long toDays(long duration) {
@@ -294,9 +293,9 @@
      * Performs a timed {@link Object#wait(long, int) Object.wait}
      * using this time unit.
      * This is a convenience method that converts timeout arguments
-     * into the form required by the <tt>Object.wait</tt> method.
+     * into the form required by the {@code Object.wait} method.
      *
-     * <p>For example, you could implement a blocking <tt>poll</tt>
+     * <p>For example, you could implement a blocking {@code poll}
      * method (see {@link BlockingQueue#poll BlockingQueue.poll})
      * using:
      *
@@ -327,7 +326,7 @@
      * Performs a timed {@link Thread#join(long, int) Thread.join}
      * using this time unit.
      * This is a convenience method that converts time arguments into the
-     * form required by the <tt>Thread.join</tt> method.
+     * form required by the {@code Thread.join} method.
      *
      * @param thread the thread to wait for
      * @param timeout the maximum time to wait. If less than
@@ -347,7 +346,7 @@
      * Performs a {@link Thread#sleep(long, int) Thread.sleep} using
      * this time unit.
      * This is a convenience method that converts time arguments into the
-     * form required by the <tt>Thread.sleep</tt> method.
+     * form required by the {@code Thread.sleep} method.
      *
      * @param timeout the minimum time to sleep. If less than
      * or equal to zero, do not sleep at all.
--- a/jdk/src/share/classes/java/util/concurrent/TimeoutException.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/TimeoutException.java	Wed Jul 03 14:35:10 2013 -0700
@@ -40,7 +40,7 @@
  * operations for which a timeout is specified need a means to
  * indicate that the timeout has occurred. For many such operations it
  * is possible to return a value that indicates timeout; when that is
- * not possible or desirable then <tt>TimeoutException</tt> should be
+ * not possible or desirable then {@code TimeoutException} should be
  * declared and thrown.
  *
  * @since 1.5
@@ -50,13 +50,13 @@
     private static final long serialVersionUID = 1900926677490660714L;
 
     /**
-     * Constructs a <tt>TimeoutException</tt> with no specified detail
+     * Constructs a {@code TimeoutException} with no specified detail
      * message.
      */
     public TimeoutException() {}
 
     /**
-     * Constructs a <tt>TimeoutException</tt> with the specified detail
+     * Constructs a {@code TimeoutException} with the specified detail
      * message.
      *
      * @param message the detail message
--- a/jdk/src/share/classes/java/util/concurrent/package-info.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/package-info.java	Wed Jul 03 14:35:10 2013 -0700
@@ -48,7 +48,7 @@
  *
  * {@link java.util.concurrent.Executor} is a simple standardized
  * interface for defining custom thread-like subsystems, including
- * thread pools, asynchronous IO, and lightweight task frameworks.
+ * thread pools, asynchronous I/O, and lightweight task frameworks.
  * Depending on which concrete Executor class is being used, tasks may
  * execute in a newly created thread, an existing task-execution thread,
  * or the thread calling {@link java.util.concurrent.Executor#execute
@@ -102,8 +102,10 @@
  * <h2>Queues</h2>
  *
  * The {@link java.util.concurrent.ConcurrentLinkedQueue} class
- * supplies an efficient scalable thread-safe non-blocking FIFO
- * queue.
+ * supplies an efficient scalable thread-safe non-blocking FIFO queue.
+ * The {@link java.util.concurrent.ConcurrentLinkedDeque} class is
+ * similar, but additionally supports the {@link java.util.Deque}
+ * interface.
  *
  * <p>Five implementations in {@code java.util.concurrent} support
  * the extended {@link java.util.concurrent.BlockingQueue}
@@ -117,7 +119,7 @@
  * for producer-consumer, messaging, parallel tasking, and
  * related concurrent designs.
  *
- * <p> Extended interface {@link java.util.concurrent.TransferQueue},
+ * <p>Extended interface {@link java.util.concurrent.TransferQueue},
  * and implementation {@link java.util.concurrent.LinkedTransferQueue}
  * introduce a synchronous {@code transfer} method (along with related
  * features) in which a producer may optionally block awaiting its
@@ -216,9 +218,9 @@
  * it may (or may not) reflect any updates since the iterator was
  * created.
  *
- * <h2><a name="MemoryVisibility">Memory Consistency Properties</a></h2>
+ * <h2 id="MemoryVisibility">Memory Consistency Properties</h2>
  *
- * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/index.html">
+ * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5">
  * Chapter 17 of the Java Language Specification</a> defines the
  * <i>happens-before</i> relation on memory operations such as reads and
  * writes of shared variables.  The results of a write by one thread are
--- a/jdk/src/share/classes/java/util/logging/LogManager.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java	Wed Jul 03 14:35:10 2013 -0700
@@ -193,13 +193,27 @@
 
                     // Create and retain Logger for the root of the namespace.
                     manager.rootLogger = manager.new RootLogger();
+                    // since by design the global manager's userContext and
+                    // systemContext don't have their requiresDefaultLoggers
+                    // flag set - we make sure to add the root logger to
+                    // the global manager's default contexts here.
                     manager.addLogger(manager.rootLogger);
-                    manager.systemContext.addLocalLogger(manager.rootLogger);
+                    manager.systemContext.addLocalLogger(manager.rootLogger, false);
+                    manager.userContext.addLocalLogger(manager.rootLogger, false);
 
                     // Adding the global Logger. Doing so in the Logger.<clinit>
                     // would deadlock with the LogManager.<clinit>.
-                    Logger.global.setLogManager(manager);
-                    manager.addLogger(Logger.global);
+                    // Do not call Logger.getGlobal() here as this might trigger
+                    // the deadlock too.
+                    @SuppressWarnings("deprecation")
+                    final Logger global = Logger.global;
+                    global.setLogManager(manager);
+
+                    // Make sure the global logger will be registered in the
+                    // global manager's default contexts.
+                    manager.addLogger(global);
+                    manager.systemContext.addLocalLogger(global, false);
+                    manager.userContext.addLocalLogger(global, false);
 
                     // We don't call readConfiguration() here, as we may be running
                     // very early in the JVM startup sequence.  Instead readConfiguration
@@ -401,7 +415,11 @@
                         if (javaAwtAccess.isMainAppContext()) {
                             context = userContext;
                         } else {
-                            context = new LoggerContext();
+                            // Create a new LoggerContext for the applet.
+                            // The new logger context has its requiresDefaultLoggers
+                            // flag set to true - so that these loggers will be
+                            // lazily added when the context is firt accessed.
+                            context = new LoggerContext(true);
                         }
                         javaAwtAccess.put(ecx, LoggerContext.class, context);
                     }
@@ -508,9 +526,13 @@
         private final Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>();
         // Tree of named Loggers
         private final LogNode root;
-
+        private final boolean requiresDefaultLoggers;
         private LoggerContext() {
+            this(false);
+        }
+        private LoggerContext(boolean requiresDefaultLoggers) {
             this.root = new LogNode(null, this);
+            this.requiresDefaultLoggers = requiresDefaultLoggers;
         }
 
         Logger demandLogger(String name, String resourceBundleName) {
@@ -519,7 +541,27 @@
             return manager.demandLogger(name, resourceBundleName, null);
         }
 
+
+        // Due to subtle deadlock issues getUserContext() no longer
+        // calls addLocalLogger(rootLogger);
+        // Therefore - we need to add the default loggers later on.
+        // Checks that the context is properly initialized
+        // This is necessary before calling e.g. find(name)
+        // or getLoggerNames()
+        //
+        private void ensureInitialized() {
+            if (requiresDefaultLoggers) {
+                // Ensure that the root and global loggers are set.
+                ensureDefaultLogger(manager.rootLogger);
+                ensureDefaultLogger(Logger.global);
+            }
+        }
+
+
         synchronized Logger findLogger(String name) {
+            // ensure that this context is properly initialized before
+            // looking for loggers.
+            ensureInitialized();
             LoggerWeakRef ref = namedLoggers.get(name);
             if (ref == null) {
                 return null;
@@ -533,21 +575,76 @@
             return logger;
         }
 
-        synchronized void ensureRootLogger(Logger logger) {
-            if (logger.getName().isEmpty())
-                return;
+        // This method is called before adding a logger to the
+        // context.
+        // 'logger' is the context that will be added.
+        // This method will ensure that the defaults loggers are added
+        // before adding 'logger'.
+        //
+        private void ensureAllDefaultLoggers(Logger logger) {
+            if (requiresDefaultLoggers) {
+                final String name = logger.getName();
+                if (!name.isEmpty()) {
+                    ensureDefaultLogger(manager.rootLogger);
+                }
+                if (!Logger.GLOBAL_LOGGER_NAME.equals(name)) {
+                    ensureDefaultLogger(Logger.global);
+                }
+            }
+        }
+
+        private void ensureDefaultLogger(Logger logger) {
+            // Used for lazy addition of root logger and global logger
+            // to a LoggerContext.
 
-            // during initialization, rootLogger is null when
-            // instantiating itself RootLogger
-            if (findLogger("") == null && manager.rootLogger != null) {
-                addLocalLogger(manager.rootLogger);
+            // This check is simple sanity: we do not want that this
+            // method be called for anything else than Logger.global
+            // or owner.rootLogger.
+            if (!requiresDefaultLoggers || logger == null
+                    || logger != Logger.global && logger != manager.rootLogger) {
+
+                // the case where we have a non null logger which is neither
+                // Logger.global nor manager.rootLogger indicates a serious
+                // issue - as ensureDefaultLogger should never be called
+                // with any other loggers than one of these two (or null - if
+                // e.g manager.rootLogger is not yet initialized)...
+                assert logger == null;
+
+                return;
             }
+
+            // Adds the logger if it's not already there.
+            if (!namedLoggers.containsKey(logger.getName())) {
+                // It is important to prevent addLocalLogger to
+                // call ensureAllDefaultLoggers when we're in the process
+                // off adding one of those default loggers - as this would
+                // immediately cause a stack overflow.
+                // Therefore we must pass addDefaultLoggersIfNeeded=false,
+                // even if requiresDefaultLoggers is true.
+                addLocalLogger(logger, false);
+            }
+        }
+
+        boolean addLocalLogger(Logger logger) {
+            // no need to add default loggers if it's not required
+            return addLocalLogger(logger, requiresDefaultLoggers);
         }
 
         // Add a logger to this context.  This method will only set its level
         // and process parent loggers.  It doesn't set its handlers.
-        synchronized boolean addLocalLogger(Logger logger) {
-            ensureRootLogger(logger);
+        synchronized boolean addLocalLogger(Logger logger, boolean addDefaultLoggersIfNeeded) {
+            // addDefaultLoggersIfNeeded serves to break recursion when adding
+            // default loggers. If we're adding one of the default loggers
+            // (we're being called from ensureDefaultLogger()) then
+            // addDefaultLoggersIfNeeded will be false: we don't want to
+            // call ensureAllDefaultLoggers again.
+            //
+            // Note: addDefaultLoggersIfNeeded can also be false when
+            //       requiresDefaultLoggers is false - since calling
+            //       ensureAllDefaultLoggers would have no effect in this case.
+            if (addDefaultLoggersIfNeeded) {
+                ensureAllDefaultLoggers(logger);
+            }
 
             final String name = logger.getName();
             if (name == null) {
@@ -615,6 +712,9 @@
         }
 
         synchronized Enumeration<String> getLoggerNames() {
+            // ensure that this context is properly initialized before
+            // returning logger names.
+            ensureInitialized();
             return namedLoggers.keys();
         }
 
--- a/jdk/src/share/classes/java/util/logging/Logger.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/logging/Logger.java	Wed Jul 03 14:35:10 2013 -0700
@@ -232,6 +232,27 @@
      * @since 1.7
      */
     public static final Logger getGlobal() {
+        // In order to break a cyclic dependence between the LogManager
+        // and Logger static initializers causing deadlocks, the global
+        // logger is created with a special constructor that does not
+        // initialize its log manager.
+        //
+        // If an application calls Logger.getGlobal() before any logger
+        // has been initialized, it is therefore possible that the
+        // LogManager class has not been initialized yet, and therefore
+        // Logger.global.manager will be null.
+        //
+        // In order to finish the initialization of the global logger, we
+        // will therefore call LogManager.getLogManager() here.
+        //
+        // Care must be taken *not* to call Logger.getGlobal() in
+        // LogManager static initializers in order to avoid such
+        // deadlocks.
+        //
+        if (global != null && global.manager == null) {
+            // Complete initialization of the global Logger.
+            global.manager = LogManager.getLogManager();
+        }
         return global;
     }
 
--- a/jdk/src/share/classes/java/util/spi/LocaleServiceProvider.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/spi/LocaleServiceProvider.java	Wed Jul 03 14:35:10 2013 -0700
@@ -42,7 +42,7 @@
  * interfaces to offer support for locales beyond the set of locales
  * supported by the Java runtime environment itself.
  * <p>
- * <h4>Packaging of Locale Sensitive Service Provider Implementations</h4>
+ * <h3>Packaging of Locale Sensitive Service Provider Implementations</h3>
  * Implementations of these locale sensitive services are packaged using the
  * <a href="../../../../technotes/guides/extensions/index.html">Java Extension Mechanism</a>
  * as installed extensions.  A provider identifies itself with a
@@ -165,7 +165,7 @@
     /**
      * Returns {@code true} if the given {@code locale} is supported by
      * this locale service provider. The given {@code locale} may contain
-     * <a href="../Locale.html#def_extensions">extensions<a/> that should be
+     * <a href="../Locale.html#def_extensions">extensions</a> that should be
      * taken into account for the support determination.
      *
      * <p>The default implementation returns {@code true} if the given {@code locale}
--- a/jdk/src/share/classes/java/util/stream/SliceOps.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/SliceOps.java	Wed Jul 03 14:35:10 2013 -0700
@@ -598,9 +598,9 @@
                 final Node.Builder<P_OUT> nb = op.makeNodeBuilder(sizeIfKnown, generator);
                 Sink<P_OUT> opSink = op.opWrapSink(helper.getStreamAndOpFlags(), nb);
                 helper.copyIntoWithCancel(helper.wrapSink(opSink), spliterator);
-                // It is necessary to truncate here since the result at the root
-                // can only be set once
-                return doTruncate(nb.build());
+                // There is no need to truncate since the op performs the
+                // skipping and limiting of elements
+                return nb.build();
             }
             else {
                 Node<P_OUT> node = helper.wrapAndCopyInto(helper.makeNodeBuilder(-1, generator),
--- a/jdk/src/share/classes/javax/crypto/Cipher.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/javax/crypto/Cipher.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1135,7 +1135,7 @@
      *
      * <p>If this cipher (including its underlying feedback or padding scheme)
      * requires any random bytes (e.g., for parameter generation), it will get
-     * them using the {@link SecureRandom <code>SecureRandom</code>}
+     * them using the {@link java.security.SecureRandom}
      * implementation of the highest-priority
      * installed provider as the source of randomness.
      * (If none of the installed providers supply an implementation of
@@ -1263,7 +1263,7 @@
      *
      * <p>If this cipher (including its underlying feedback or padding scheme)
      * requires any random bytes (e.g., for parameter generation), it will get
-     * them using the {@link SecureRandom <code>SecureRandom</code>}
+     * them using the {@link java.security.SecureRandom}
      * implementation of the highest-priority
      * installed provider as the source of randomness.
      * (If none of the installed providers supply an implementation of
@@ -1400,7 +1400,7 @@
      *
      * <p>If this cipher (including its underlying feedback or padding scheme)
      * requires any random bytes (e.g., for parameter generation), it will get
-     * them using the {@link SecureRandom <code>SecureRandom</code>}
+     * them using the {@link java.security.SecureRandom}
      * implementation of the highest-priority
      * installed provider as the source of randomness.
      * (If none of the installed providers supply an implementation of
--- a/jdk/src/share/classes/javax/crypto/CipherInputStream.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/javax/crypto/CipherInputStream.java	Wed Jul 03 14:35:10 2013 -0700
@@ -245,7 +245,7 @@
      * <p>Fewer bytes than requested might be skipped.
      * The actual number of bytes skipped is equal to <code>n</code> or
      * the result of a call to
-     * {@link #available() <code>available</code>},
+     * {@link #available() available},
      * whichever is smaller.
      * If <code>n</code> is less than zero, no bytes are skipped.
      *
--- a/jdk/src/share/classes/javax/crypto/ExemptionMechanism.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/javax/crypto/ExemptionMechanism.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, 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
@@ -116,7 +116,7 @@
      * mechanism.
      * See the ExemptionMechanism section in the
      * <a href=
-     *   "{docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
+     *   "{@docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard exemption mechanism names.
      *
@@ -155,7 +155,7 @@
      * @param algorithm the standard name of the requested exemption mechanism.
      * See the ExemptionMechanism section in the
      * <a href=
-     *   "{docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
+     *   "{@docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard exemption mechanism names.
      *
@@ -199,7 +199,7 @@
      * @param algorithm the standard name of the requested exemption mechanism.
      * See the ExemptionMechanism section in the
      * <a href=
-     *   "{docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
+     *   "{@docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard exemption mechanism names.
      *
--- a/jdk/src/share/classes/javax/crypto/KeyAgreement.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/javax/crypto/KeyAgreement.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -149,7 +149,7 @@
      * algorithm.
      * See the KeyAgreement section in the <a href=
      * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
-     * Java Cryptography Architecture Standard Algorithm Name Documentation
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
      * @return the new <code>KeyAgreement</code> object.
@@ -196,7 +196,7 @@
      * algorithm.
      * See the KeyAgreement section in the <a href=
      * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
-     * Java Cryptography Architecture Standard Algorithm Name Documentation
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
      * @param provider the name of the provider.
@@ -240,7 +240,7 @@
      * algorithm.
      * See the KeyAgreement section in the <a href=
      * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
-     * Java Cryptography Architecture Standard Algorithm Name Documentation
+     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
      * for information about standard algorithm names.
      *
      * @param provider the provider.
@@ -418,7 +418,7 @@
      *
      * <p> If this key agreement requires any random bytes, it will get
      * them using the
-     * {@link SecureRandom <code>SecureRandom</code>}
+     * {@link java.security.SecureRandom}
      * implementation of the highest-priority
      * installed provider as the source of randomness.
      * (If none of the installed providers supply an implementation of
@@ -476,7 +476,7 @@
      *
      * <p> If this key agreement requires any random bytes, it will get
      * them using the
-     * {@link SecureRandom <code>SecureRandom</code>}
+     * {@link java.security.SecureRandom}
      * implementation of the highest-priority
      * installed provider as the source of randomness.
      * (If none of the installed providers supply an implementation of
--- a/jdk/src/share/classes/javax/crypto/KeyGenerator.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/javax/crypto/KeyGenerator.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -398,7 +398,7 @@
      *
      * <p> If this key generator requires any random bytes, it will get them
      * using the
-     * {@link SecureRandom <code>SecureRandom</code>}
+     * {@link java.security.SecureRandom}
      * implementation of the highest-priority installed
      * provider as the source of randomness.
      * (If none of the installed providers supply an implementation of
@@ -463,7 +463,7 @@
      *
      * <p> If this key generator requires any random bytes, it will get them
      * using the
-     * {@link SecureRandom <code>SecureRandom</code>}
+     * {@link java.security.SecureRandom}
      * implementation of the highest-priority installed
      * provider as the source of randomness.
      * (If none of the installed providers supply an implementation of
--- a/jdk/src/share/classes/javax/crypto/NullCipher.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/javax/crypto/NullCipher.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -38,6 +38,9 @@
 
 public class NullCipher extends Cipher {
 
+    /**
+     * Creates a NullCipher object.
+     */
     public NullCipher() {
         super(new NullCipherSpi(), null);
     }
--- a/jdk/src/share/classes/javax/security/auth/Subject.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/javax/security/auth/Subject.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -325,6 +325,9 @@
      *                  <code>action</code> will run as.  This parameter
      *                  may be <code>null</code>. <p>
      *
+     * @param <T> the type of the value returned by the PrivilegedAction's
+     *                  {@code run} method.
+     *
      * @param action the code to be run as the specified
      *                  <code>Subject</code>. <p>
      *
@@ -378,6 +381,9 @@
      *                  <code>action</code> will run as.  This parameter
      *                  may be <code>null</code>. <p>
      *
+     * @param <T> the type of the value returned by the
+     *                  PrivilegedExceptionAction's {@code run} method.
+     *
      * @param action the code to be run as the specified
      *                  <code>Subject</code>. <p>
      *
@@ -434,6 +440,9 @@
      *                  <code>action</code> will run as.  This parameter
      *                  may be <code>null</code>. <p>
      *
+     * @param <T> the type of the value returned by the PrivilegedAction's
+     *                  {@code run} method.
+     *
      * @param action the code to be run as the specified
      *                  <code>Subject</code>. <p>
      *
@@ -492,6 +501,9 @@
      *                  <code>action</code> will run as.  This parameter
      *                  may be <code>null</code>. <p>
      *
+     * @param <T> the type of the value returned by the
+     *                  PrivilegedExceptionAction's {@code run} method.
+     *
      * @param action the code to be run as the specified
      *                  <code>Subject</code>. <p>
      *
@@ -590,6 +602,8 @@
      *
      * <p>
      *
+     * @param <T> the type of the class modeled by {@code c}
+     *
      * @param c the returned <code>Set</code> of Principals will all be
      *          instances of this class.
      *
@@ -684,6 +698,8 @@
      *
      * <p>
      *
+     * @param <T> the type of the class modeled by {@code c}
+     *
      * @param c the returned <code>Set</code> of public credentials will all be
      *          instances of this class.
      *
@@ -721,6 +737,8 @@
      *
      * <p>
      *
+     * @param <T> the type of the class modeled by {@code c}
+     *
      * @param c the returned <code>Set</code> of private credentials will all be
      *          instances of this class.
      *
--- a/jdk/src/share/classes/javax/security/cert/X509Certificate.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/javax/security/cert/X509Certificate.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -159,9 +159,9 @@
      * certificate is expected to be in the input stream.
      * Also, all X509Certificate
      * subclasses must provide a constructor of the form:
-     * <code><pre>
-     * public &lt;subClass&gt;(InputStream inStream) ...
-     * </pre></code>
+     * <pre>{@code
+     * public <subClass>(InputStream inStream) ...
+     * }</pre>
      *
      * @param inStream an input stream with the data to be read to
      *        initialize the certificate.
@@ -184,9 +184,9 @@
      *
      * <p>Note: All X509Certificate
      * subclasses must provide a constructor of the form:
-     * <code><pre>
-     * public &lt;subClass&gt;(InputStream inStream) ...
-     * </pre></code>
+     * <pre>{@code
+     * public <subClass>(InputStream inStream) ...
+     * }</pre>
      *
      * @param certData a byte array containing the DER-encoded
      *        certificate.
@@ -255,10 +255,12 @@
      * is valid. It is defined in
      * ASN.1 as:
      * <pre>
-     * validity             Validity<p>
+     * validity             Validity
+     *
      * Validity ::= SEQUENCE {
      *     notBefore      CertificateValidityDate,
-     *     notAfter       CertificateValidityDate }<p>
+     *     notAfter       CertificateValidityDate }
+     *
      * CertificateValidityDate ::= CHOICE {
      *     utcTime        UTCTime,
      *     generalTime    GeneralizedTime }
@@ -291,7 +293,8 @@
      * Gets the <code>version</code> (version number) value from the
      * certificate. The ASN.1 definition for this is:
      * <pre>
-     * version         [0]  EXPLICIT Version DEFAULT v1<p>
+     * version         [0]  EXPLICIT Version DEFAULT v1
+     *
      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
      * </pre>
      *
@@ -307,7 +310,7 @@
      * serial number identify a unique certificate).
      * The ASN.1 definition for this is:
      * <pre>
-     * serialNumber     CertificateSerialNumber<p>
+     * serialNumber     CertificateSerialNumber
      *
      * CertificateSerialNumber  ::=  INTEGER
      * </pre>
@@ -325,7 +328,7 @@
      * X.500 distinguished name (DN).
      * The ASN.1 definition for this is:
      * <pre>
-     * issuer    Name<p>
+     * issuer    Name
      *
      * Name ::= CHOICE { RDNSequence }
      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
@@ -371,11 +374,12 @@
      * the certificate.
      * The relevant ASN.1 definitions are:
      * <pre>
-     * validity             Validity<p>
+     * validity             Validity
      *
      * Validity ::= SEQUENCE {
      *     notBefore      CertificateValidityDate,
-     *     notAfter       CertificateValidityDate }<p>
+     *     notAfter       CertificateValidityDate }
+     *
      * CertificateValidityDate ::= CHOICE {
      *     utcTime        UTCTime,
      *     generalTime    GeneralizedTime }
@@ -401,7 +405,8 @@
      * signature algorithm. An example is the string "SHA-1/DSA".
      * The ASN.1 definition for this is:
      * <pre>
-     * signatureAlgorithm   AlgorithmIdentifier<p>
+     * signatureAlgorithm   AlgorithmIdentifier
+     *
      * AlgorithmIdentifier  ::=  SEQUENCE  {
      *     algorithm               OBJECT IDENTIFIER,
      *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
--- a/jdk/src/share/classes/sun/security/provider/certpath/RevocationChecker.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/RevocationChecker.java	Wed Jul 03 14:35:10 2013 -0700
@@ -675,8 +675,12 @@
                                       responderURI, respCert, params.date(),
                                       ocspExtensions);
             }
-        } catch (IOException e) {
-            throw new CertPathValidatorException(e);
+        } catch (Exception e) {
+            if (e instanceof CertPathValidatorException) {
+                throw (CertPathValidatorException) e;
+            } else {
+                throw new CertPathValidatorException(e);
+            }
         }
 
         RevocationStatus rs =
--- a/jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java	Wed Jul 03 14:35:10 2013 -0700
@@ -22,6 +22,7 @@
  */
 
 /* @test
+ * @bug 7050328 8007035
  * @summary smoke test for invokedynamic instructions
  * @build indify.Indify
  * @compile InvokeDynamicPrintArgs.java
@@ -42,6 +43,7 @@
 import java.io.*;
 
 import java.lang.invoke.*;
+import java.security.*;
 import static java.lang.invoke.MethodHandles.*;
 import static java.lang.invoke.MethodType.*;
 
@@ -62,17 +64,10 @@
     }
 
     private static void checkConstantRefs() throws Throwable {
-        // check some constant references:
+        // check some constant references to its self class
         assertEquals(MT_bsm(), MH_bsm().type());
         assertEquals(MT_bsm2(), MH_bsm2().type());
-        try {
-            assertEquals(MT_bsm(), non_MH_bsm().type());
-            // if SM is installed, must throw before this point
-            assertEquals(false, System.getSecurityManager() != null);
-        } catch (SecurityException ex) {
-            // if SM is installed, must throw to this point
-            assertEquals(true, System.getSecurityManager() != null);
-        }
+        assertEquals(MT_bsm(), non_MH_bsm().type());
     }
     private static void assertEquals(Object exp, Object act) {
         if (exp == act || (exp != null && exp.equals(act)))  return;
@@ -80,21 +75,8 @@
     }
 
     private static void setSM() {
-        // Test for severe security manager interactions (7050328).
-        class SM extends SecurityManager {
-            public void checkPackageAccess(String pkg) {
-                if (pkg.startsWith("test."))
-                    throw new SecurityException("checkPackageAccess "+pkg);
-            }
-            public void checkMemberAccess(Class<?> clazz, int which) {
-                if (clazz == InvokeDynamicPrintArgs.class)
-                    throw new SecurityException("checkMemberAccess "+clazz.getName()+" #"+which);
-            }
-            // allow these others:
-            public void checkPermission(java.security.Permission perm) {
-            }
-        }
-        System.setSecurityManager(new SM());
+        Policy.setPolicy(new TestPolicy());
+        System.setSecurityManager(new SecurityManager());
     }
 
     private static PrintStream oldOut;
@@ -250,4 +232,22 @@
         if (System.getProperty("InvokeDynamicPrintArgs.allow-untransformed") != null)  return;
         throw new AssertionError("this code should be statically transformed away by Indify");
     }
+
+    static class TestPolicy extends Policy {
+        final PermissionCollection permissions = new Permissions();
+        TestPolicy() {
+            permissions.add(new java.io.FilePermission("<<ALL FILES>>", "read"));
+        }
+        public PermissionCollection getPermissions(ProtectionDomain domain) {
+            return permissions;
+        }
+
+        public PermissionCollection getPermissions(CodeSource codesource) {
+            return permissions;
+        }
+
+        public boolean implies(ProtectionDomain domain, Permission perm) {
+            return permissions.implies(perm);
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/TestCatchExceptionWithVarargs.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8019184
+ * @summary MethodHandles.catchException() fails when methods have 8 args + varargs
+ */
+
+import java.util.*;
+import java.lang.invoke.*;
+
+public class TestCatchExceptionWithVarargs {
+
+    private static final Class<?> CLASS = TestCatchExceptionWithVarargs.class;
+    private static final int MAX_MH_ARITY = 254;
+
+    public static MethodHandle target;
+    public static MethodHandle handler;
+
+    private static Object firstArg;
+
+    static class MyException extends Exception {
+    }
+
+    public static Object target(Object... a) throws Exception {
+        if (a[0] != firstArg) {
+            throw new AssertionError("first argument different than expected: " + a[0] + " != " + firstArg);
+        }
+        throw new MyException();
+    }
+
+    public static Object handler(Object... a) {
+        if (a[0] != firstArg) {
+            throw new AssertionError("first argument different than expected: " + a[0] + " != " + firstArg);
+        }
+        return a[0];
+    }
+
+    static {
+        try {
+            MethodType mtype = MethodType.methodType(Object.class, Object[].class);
+            target = MethodHandles.lookup().findStatic(CLASS, "target", mtype);
+            handler = MethodHandles.lookup().findStatic(CLASS, "handler", mtype);
+        } catch (Exception e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        List<Class<?>> ptypes = new LinkedList<>();
+        ptypes.add(Object[].class);
+
+        // We use MAX_MH_ARITY - 1 here to account for the Object[] argument.
+        for (int i = 1; i < MAX_MH_ARITY - 1; i++) {
+            ptypes.add(0, Object.class);
+
+            MethodHandle targetWithArgs = target.asType(MethodType.methodType(Object.class, ptypes));
+            MethodHandle handlerWithArgs = handler.asType(MethodType.methodType(Object.class, ptypes));
+            handlerWithArgs = MethodHandles.dropArguments(handlerWithArgs, 0, MyException.class);
+
+            MethodHandle gwc1 = MethodHandles.catchException(targetWithArgs, MyException.class, handlerWithArgs);
+
+            // The next line throws an IllegalArgumentException if there is a bug.
+            MethodHandle gwc2 = MethodHandles.catchException(gwc1, MyException.class, handlerWithArgs);
+
+            // This is only to verify that the method handles can actually be invoked and do the right thing.
+            firstArg = new Object();
+            Object o = gwc2.asSpreader(Object[].class, ptypes.size() - 1).invoke(firstArg, new Object[i]);
+            if (o != firstArg) {
+                throw new AssertionError("return value different than expected: " + o + " != " + firstArg);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/TestPrivateMember.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,57 @@
+/*
+ * 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.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+/**
+ * @test
+ * @bug 8007035
+ * @summary Test MethodHandle of a private member
+ *
+ * @run main TestPrivateMember
+ */
+
+public class TestPrivateMember {
+    public static void main(String... args) throws Throwable {
+        System.setSecurityManager(new SecurityManager());
+        TestPrivateMember t = new TestPrivateMember();
+        t.test();
+    }
+
+    public TestPrivateMember() {
+    }
+
+    public void test() throws Throwable {
+        MethodHandles.Lookup lookup = MethodHandles.lookup();
+        MethodType mt = MethodType.methodType(void.class);
+        try {
+            MethodHandle mh = lookup.findStatic(Class.class, "checkInitted", mt);
+            throw new RuntimeException("IllegalAccessException not thrown");
+        } catch (IllegalAccessException e) {
+            // okay
+            System.out.println("Expected exception: " + e.getMessage());
+        }
+    }
+}
--- a/jdk/test/java/security/cert/CertPathValidator/OCSP/FailoverToCRL.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/java/security/cert/CertPathValidator/OCSP/FailoverToCRL.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 6383095
+ * @bug 6383095 8019259
  * @summary CRL revoked certificate failures masked by OCSP failures
  *
  * Note that the certificate validity is from Mar 16 14:55:35 2009 GMT to
@@ -254,12 +254,32 @@
         CertPathValidator validator = CertPathValidator.getInstance("PKIX");
 
         try {
+            System.out.println("Validating cert via OCSP: no responder URL");
             validator.validate(path, params);
         } catch (CertPathValidatorException cpve) {
             if (cpve.getReason() != BasicReason.REVOKED) {
                 throw new Exception(
-                    "unexpect exception, should be a REVOKED CPVE", cpve);
+                    "unexpected exception, should be a REVOKED CPVE", cpve);
             }
+            System.out.println("  successful failover to using CRLs");
+        }
+
+        java.security.cert.PKIXRevocationChecker revocationChecker =
+            (java.security.cert.PKIXRevocationChecker)
+                validator.getRevocationChecker();
+        revocationChecker.setOCSPResponder(
+            new java.net.URI("bad_ocsp_responder_url"));
+        params.addCertPathChecker(revocationChecker);
+
+        try {
+            System.out.println("Validating cert via OCSP: bad responder URL");
+            validator.validate(path, params);
+        } catch (CertPathValidatorException cpve) {
+            if (cpve.getReason() != BasicReason.REVOKED) {
+                throw new Exception(
+                    "unexpected exception, should be a REVOKED CPVE", cpve);
+            }
+            System.out.println("  successful failover to using CRLs");
         }
     }
 }
--- a/jdk/test/java/util/logging/LogManagerInstanceTest.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/java/util/logging/LogManagerInstanceTest.java	Wed Jul 03 14:35:10 2013 -0700
@@ -63,7 +63,7 @@
                 if (!super.addLogger(root))
                     throw new RuntimeException("Fail to addLogger " + root);
             } else {
-                System.out.println("Root logger already exists");
+                throw new RuntimeException("Root logger already exists");
             }
             this.base = root;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,73 @@
+/*
+ * 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.Arrays;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * @test
+ * @bug 7184195
+ * @summary checks that java.util.logging.Logger.getGlobal().info() logs without configuration
+ * @build TestGetGlobal testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl
+ * @run main/othervm/timeout=10 TestGetGlobal
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobal
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal
+ * @author danielfuchs
+ */
+public class TestGetGlobal {
+
+    final static String[] messages = {
+        "1. This message should not appear on the console.",
+        "2. This message should appear on the console.",
+        "3. This message should now appear on the console too."
+    };
+
+    static {
+        System.setProperty("java.util.logging.config.file",
+            System.getProperty("test.src", ".") + java.io.File.separator + "logging.properties");
+    }
+
+    public static void main(String... args) {
+
+        Logger.global.info(messages[0]); // at this point LogManager is not
+             // initialized yet, so this message should not appear.
+        Logger.getGlobal().info(messages[1]); // calling getGlobal() will
+             // initialize the LogManager - and thus this message should appear.
+        Logger.global.info(messages[2]); // Now that the LogManager is
+             // initialized, this message should appear too.
+
+        final List<String> expected = Arrays.asList(Arrays.copyOfRange(messages, 1, messages.length));
+        if (!testgetglobal.HandlerImpl.received.equals(expected)) {
+            throw new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalByName.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,73 @@
+/*
+ * 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.Arrays;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * @test
+ * @bug 7184195
+ * @summary checks that java.util.logging.Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info() logs without configuration
+ * @build TestGetGlobalByName testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl
+ * @run main/othervm/timeout=10 TestGetGlobalByName
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobalByName
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalByName
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl TestGetGlobalByName
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName
+ * @author danielfuchs
+ */
+public class TestGetGlobalByName {
+
+    final static String[] messages = {
+        "1. This message should not appear on the console.",
+        "2. This message should appear on the console.",
+        "3. This message should now appear on the console too."
+    };
+
+    static {
+        System.setProperty("java.util.logging.config.file",
+            System.getProperty("test.src", ".") + java.io.File.separator + "logging.properties");
+    }
+
+    public static void main(String... args) {
+
+        Logger.global.info(messages[0]); // at this point LogManager is not
+             // initialized yet, so this message should not appear.
+        Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(messages[1]); // calling getLogger() will
+             // initialize the LogManager - and thus this message should appear.
+        Logger.global.info(messages[2]); // Now that the LogManager is
+             // initialized, this message should appear too.
+
+        final List<String> expected = Arrays.asList(Arrays.copyOfRange(messages, 1, messages.length));
+        if (!testgetglobal.HandlerImpl.received.equals(expected)) {
+            throw new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,184 @@
+/*
+ * 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.Arrays;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * @test
+ * @bug 7184195
+ * @summary checks that java.util.logging.Logger.getGlobal().info() logs without configuration
+ * @build TestGetGlobalConcurrent testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl
+ * @run main/othervm/timeout=10 TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent
+ * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent
+ * @author danielfuchs
+ */
+public class TestGetGlobalConcurrent {
+
+    final static String[] messages = {
+        "1. This message should not appear on the console.",
+        "2. This message should appear on the console.",
+        "3. This message should now appear on the console too.",
+        "4. This message should appear on the console.",
+        "5. This message should now appear on the console too.",
+        "6. This message should appear on the console.",
+        "7. This message should now appear on the console too.",
+        "8. This message should appear on the console.",
+        "9. This message should now appear on the console too."
+    };
+
+    static {
+        System.setProperty("java.util.logging.config.file",
+            System.getProperty("test.src", ".") + java.io.File.separator + "logging.properties");
+    }
+
+    public static void test1() {
+        final int nb = 1;
+        final int i = 2*nb + 1;
+        Logger.getGlobal().info(messages[i]); // calling getGlobal() will
+             // initialize the LogManager - and thus this message should appear.
+        Logger.global.info(messages[i+1]); // Now that the LogManager is
+             // initialized, this message should appear too.
+
+        final List<String> expected = Arrays.asList(Arrays.copyOfRange(messages, i, i+2));
+        if (!testgetglobal.HandlerImpl.received.containsAll(expected)) {
+            fail(new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected));
+        }
+    }
+    public static void test2() {
+        final int nb = 2;
+        final int i = 2*nb + 1;
+        Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info(messages[i]); // calling getGlobal() will
+             // initialize the LogManager - and thus this message should appear.
+        Logger.global.info(messages[i+1]); // Now that the LogManager is
+             // initialized, this message should appear too.
+
+        final List<String> expected = Arrays.asList(Arrays.copyOfRange(messages, i, i+2));
+        if (!testgetglobal.HandlerImpl.received.containsAll(expected)) {
+            fail(new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected));
+        }
+    }
+    public static void test3() {
+        final int nb = 3;
+        final int i = 2*nb + 1;
+        java.util.logging.LogManager.getLogManager();
+        Logger.getGlobal().info(messages[i]); // calling getGlobal() will
+             // initialize the LogManager - and thus this message should appear.
+        Logger.global.info(messages[i+1]); // Now that the LogManager is
+             // initialized, this message should appear too.
+
+        final List<String> expected = Arrays.asList(Arrays.copyOfRange(messages, i, i+2));
+        if (!testgetglobal.HandlerImpl.received.containsAll(expected)) {
+            fail(new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected));
+        }
+    }
+    public static void test4() {
+        log = new MyLogger("foo.bar");
+        java.util.logging.LogManager.getLogManager().addLogger(log);
+    }
+
+
+    private static volatile Throwable failed = null;
+    private static volatile Logger log = null;
+
+    public static class MyLogger extends Logger {
+        public MyLogger(String name) {
+            super(name, null);
+        }
+    }
+
+    public static void fail(Throwable failure) {
+        failure.printStackTrace();
+        if (failed == null) failed = failure;
+    }
+
+    public static class WaitAndRun implements Runnable {
+          private final Runnable run;
+          public WaitAndRun(Runnable run) {
+              this.run = run;
+          }
+          public void run() {
+              try {
+                 Thread.sleep(10);
+                 run.run();
+              } catch (Exception | Error x) {
+                 fail(x);
+              }
+          }
+    }
+
+    final static class Run1 implements Runnable {
+        public void run() { test1(); }
+    }
+    final static class Run2 implements Runnable {
+        public void run() { test2(); }
+    }
+    final static class Run3 implements Runnable {
+        public void run() { test3(); }
+    }
+    final static class Run4 implements Runnable {
+        public void run() { test4(); }
+    }
+
+    public static void main(String... args) throws Exception {
+
+        final Thread t1 = new Thread(new WaitAndRun(new Run1()), "test1");
+        final Thread t2 = new Thread(new WaitAndRun(new Run2()), "test2");
+        final Thread t3 = new Thread(new WaitAndRun(new Run3()), "test3");
+        final Thread t4 = new Thread(new WaitAndRun(new Run4()), "test4");
+
+        t1.setDaemon(true); t2.setDaemon(true); t3.setDaemon(true); t4.setDaemon(true);
+        t1.start(); t2.start(); t3.start(); t4.start();
+
+        Thread.sleep(10);
+
+        Logger.getGlobal().info(messages[1]); // calling getGlobal() will
+             // initialize the LogManager - and thus this message should appear.
+        Logger.global.info(messages[2]); // Now that the LogManager is
+             // initialized, this message should appear too.
+
+        final List<String> expected = Arrays.asList(Arrays.copyOfRange(messages, 1, 3));
+        if (!testgetglobal.HandlerImpl.received.containsAll(expected)) {
+            throw new Error("Unexpected message list: "+testgetglobal.HandlerImpl.received+" vs "+ expected);
+        }
+
+
+        t1.join(); t2.join(); t3.join(); t4.join();
+
+        if (failed != null) {
+             throw new Error("Test failed.", failed);
+        }
+
+        System.out.println("Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/logging.properties	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,2 @@
+.level=INFO
+handlers=testgetglobal.HandlerImpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/policy	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,7 @@
+grant {
+    permission java.util.PropertyPermission "java.util.logging.config.file", "write";
+    permission java.util.PropertyPermission "test.src", "read";
+    permission java.lang.RuntimePermission "setContextClassLoader";
+    permission java.lang.RuntimePermission "shutdownHooks";
+    permission java.util.logging.LoggingPermission "control";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/testgetglobal/BadLogManagerImpl.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * 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 testgetglobal;
+
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+/**
+ * This class is used to verify that calling Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)
+ * in the constructor of a LogManager subclass installed as default
+ * LogManager does not cause issues beyond throwing the expected NPE.
+ * In that case the default LogManager class will simply be used.
+ * @author danielfuchs
+ */
+public class BadLogManagerImpl extends LogManager {
+
+    final Logger globalLogger;
+    public BadLogManagerImpl() {
+        // The call below should generate an NPE, which will be
+        // catched in LogManager initializer.
+        globalLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+        System.err.println("Global is: " + globalLogger);
+        throw new Error("Should not have reached here");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/testgetglobal/DummyLogManagerImpl.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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 testgetglobal;
+
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+/**
+ * A dummy LogManager subclass that does nothing beyond extending LogManager.
+ * @author danielfuchs
+ */
+public class DummyLogManagerImpl extends LogManager {
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/testgetglobal/HandlerImpl.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * 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 testgetglobal;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.List;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.LogRecord;
+
+/**
+ *
+ * @author danielfuchs
+ */
+public class HandlerImpl extends ConsoleHandler {
+
+    public final static List<String> received = new CopyOnWriteArrayList<>();
+
+    public HandlerImpl() {
+    }
+
+    @Override
+    public void publish(LogRecord record) {
+        received.add(record.getMessage());
+        super.publish(record);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/testgetglobal/LogManagerImpl1.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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 testgetglobal;
+
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+/**
+ * This class is used to verify that calling Logger.getGlobal() in the static
+ * initializer of a LogManager subclass installed as default LogManager
+ * does not cause issues.
+ * @author danielfuchs
+ */
+public class LogManagerImpl1 extends LogManager {
+
+    static final Logger global;
+    static {
+        global = Logger.getGlobal();
+        System.err.println("Global is: " + global);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/testgetglobal/LogManagerImpl2.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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 testgetglobal;
+
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+/**
+ * This class is used to verify that calling Logger.getGlobal() in the constructor
+ * initializer of a LogManager subclass installed as default LogManager
+ * does not cause issues.
+ * @author danielfuchs
+ */
+public class LogManagerImpl2 extends LogManager {
+
+    final Logger globalLogger;
+    public LogManagerImpl2() {
+        globalLogger = Logger.getGlobal();
+        System.err.println("Global is: " + globalLogger);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getGlobal/testgetglobal/LogManagerImpl3.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,59 @@
+/*
+ * 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 testgetglobal;
+
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+/**
+ * This class is used to verify that calling Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)
+ * in the static initializer of a LogManager subclass installed as default
+ * LogManager does not cause issues beyond throwing the expected NPE.
+ * @author danielfuchs
+ */
+public class LogManagerImpl3 extends LogManager {
+
+    static final Logger global;
+    static {
+        Logger g = null;
+        try {
+            g = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            throw new Error("Should not have reached here");
+        } catch (Exception x) {
+            // This is to be expected: Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)
+            // will call LogManager.getLogManager() which will return null, since
+            // we haven't manage to do new LogManagerImpl3() yet.
+            //
+            System.err.println("Got expected exception - you cannot call"
+                   + " Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)"
+                   + " in LogManager subclass static initializer: " + x);
+            x.printStackTrace();
+        }
+        if (g == null) {
+            g = Logger.getGlobal();
+        }
+        global = g;
+        System.err.println("Global is: " + global);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/TestAppletLoggerContext.java	Wed Jul 03 14:35:10 2013 -0700
@@ -0,0 +1,610 @@
+/*
+ * 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.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+import java.util.logging.LoggingPermission;
+import sun.misc.JavaAWTAccess;
+import sun.misc.SharedSecrets;
+
+/*
+ * @test
+ * @bug 8017174 8010727
+ * @summary  NPE when using Logger.getAnonymousLogger or
+ *           LogManager.getLogManager().getLogger
+ *
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext LoadingApplet
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext  LoadingApplet
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext LoadingMain
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext  LoadingMain
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext One
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext  One
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext Two
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext  Two
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext Three
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext  Three
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext Four
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext  Four
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext Five
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext  Five
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext Six
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext  Six
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext Seven
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext  Seven
+ * @run main/othervm -Dtest.security=off TestAppletLoggerContext
+ * @run main/othervm -Dtest.security=on TestAppletLoggerContext
+ */
+
+// NOTE: We run in other VM in order to 1. switch security manager and 2. cause
+// LogManager class to be loaded anew.
+public class TestAppletLoggerContext {
+
+    // Avoids the hassle of dealing with files and system props...
+    static class SimplePolicy extends Policy {
+        private final Permissions perms;
+        public SimplePolicy(Permission... permissions) {
+            perms = new Permissions();
+            for (Permission permission : permissions) {
+                perms.add(permission);
+            }
+        }
+        @Override
+        public PermissionCollection getPermissions(CodeSource cs) {
+            return perms;
+        }
+        @Override
+        public PermissionCollection getPermissions(ProtectionDomain pd) {
+            return perms;
+        }
+        @Override
+        public boolean implies(ProtectionDomain pd, Permission p) {
+           return perms.implies(p);
+        }
+    }
+
+    // The bridge class initializes the logging system.
+    // It stubs the applet context in order to simulate context changes.
+    //
+    public static class Bridge {
+
+        private static class JavaAWTAccessStub implements JavaAWTAccess {
+            boolean active = true;
+
+            private static class TestExc {
+                private final Map<Object, Object> map = new HashMap<>();
+                void put(Object key, Object v) { map.put(key, v); }
+                Object get(Object key) { return map.get(key); }
+                void remove(Object o) { map.remove(o); }
+                public static TestExc exc(Object o) {
+                    return TestExc.class.cast(o);
+                }
+            }
+
+            TestExc exc;
+            TestExc global = new TestExc();
+
+            @Override
+            public Object getContext() { return active ? global : null; }
+            @Override
+            public Object getExecutionContext() { return active ? exc : null; }
+            @Override
+            public Object get(Object o, Object o1) { return TestExc.exc(o).get(o1); }
+            @Override
+            public void put(Object o, Object o1, Object o2) { TestExc.exc(o).put(o1, o2); }
+            @Override
+            public void remove(Object o, Object o1) { TestExc.exc(o).remove(o1); }
+            @Override
+            public Object get(Object o) { return global.get(o); }
+            @Override
+            public void put(Object o, Object o1) { global.put(o, o1); }
+            @Override
+            public void remove(Object o) { global.remove(o); }
+            @Override
+            public boolean isDisposed() { return false; }
+            @Override
+            public boolean isMainAppContext() { return exc == null; }
+        }
+
+        final static JavaAWTAccessStub javaAwtAccess = new JavaAWTAccessStub();
+        public static void init() {
+            SharedSecrets.setJavaAWTAccess(javaAwtAccess);
+            if (System.getProperty("test.security", "on").equals("on")) {
+                Policy p = new SimplePolicy(new LoggingPermission("control", null),
+                    new RuntimePermission("setContextClassLoader"),
+                    new RuntimePermission("shutdownHooks"));
+                Policy.setPolicy(p);
+                System.setSecurityManager(new SecurityManager());
+            }
+        }
+
+        public static void changeContext() {
+            System.out.println("... Switching to a new applet context ...");
+            javaAwtAccess.active = true;
+            javaAwtAccess.exc = new JavaAWTAccessStub.TestExc();
+        }
+
+        public static void desactivate() {
+            System.out.println("... Running with no applet context ...");
+            javaAwtAccess.exc = null;
+            javaAwtAccess.active = false;
+        }
+
+        public static class CustomAnonymousLogger extends Logger {
+            public CustomAnonymousLogger() {
+                this("");
+            }
+            public CustomAnonymousLogger(String name) {
+                super(null, null);
+                System.out.println( " LogManager: " +LogManager.getLogManager());
+                System.out.println( " getLogger: " +LogManager.getLogManager().getLogger(name));
+                setParent(LogManager.getLogManager().getLogger(name));
+            }
+        }
+
+        public static class CustomLogger extends Logger {
+            CustomLogger(String name) {
+                super(name, null);
+            }
+        }
+    }
+
+    public static enum TestCase {
+        LoadingApplet, LoadingMain, One, Two, Three, Four, Five, Six, Seven;
+        public void test() {
+            switch(this) {
+                // When run - each of these two tests must be
+                // run before any other tests and before each other.
+                case LoadingApplet: testLoadingApplet(); break;
+                case LoadingMain:   testLoadingMain(); break;
+                case One:   testOne(); break;
+                case Two:   testTwo(); break;
+                case Three: testThree(); break;
+                case Four:  testFour(); break;
+                case Five:  testFive(); break;
+                case Six:   testSix(); break;
+                case Seven: testSeven(); break;
+            }
+        }
+        public String describe() {
+            switch(this) {
+                case LoadingApplet:
+                    return "Test that when the LogManager class is"
+                        + " loaded in  an applet thread first,"
+                        + "\n all LoggerContexts are correctly initialized";
+                case LoadingMain:
+                    return "Test that when the LogManager class is"
+                        + " loaded in  the main thread first,"
+                        + "\n all LoggerContexts are correctly initialized";
+                case One:
+                    return "Test that Logger.getAnonymousLogger()"
+                        + " and new CustomAnonymousLogger() don't throw NPE";
+                case Two:
+                    return "Test that Logger.getLogger(\"\")"
+                            + " does not return null nor throws NPE";
+                case Three:
+                    return "Test that LogManager.getLogManager().getLogger(\"\")"
+                            + " does not return null nor throws NPE";
+                case Four:
+                    return "Test that Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)"
+                            + " does not return null,\n and that"
+                            + " new CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME)"
+                            + " does not throw NPE";
+                case Five:
+                    return "Test that LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME)"
+                            + "\n does not return null nor throws NPE";
+                case Six:
+                    return "Test that manager.getLogger(Logger.GLOBAL_LOGGER_NAME)"
+                            + " returns null\n when manager is not the default"
+                            + " LogManager instance.\n"
+                            + "Test adding a new logger named \"global\" in that"
+                            + " non default instance.";
+                case Seven: return "Test that manager.getLogger(\"\")"
+                            + " returns null\n when manager is not the default"
+                            + " LogManager instance.\n"
+                            + "Test adding a new logger named \"\" in that"
+                            + " non default instance.";
+                default: return "Undefined";
+            }
+        }
+    };
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        Bridge.init();
+        EnumSet<TestCase> tests = EnumSet.noneOf(TestCase.class);
+        for (String arg : args) {
+            tests.add(TestCase.valueOf(arg));
+        }
+        if (args.length == 0) {
+            tests = EnumSet.complementOf(EnumSet.of(TestCase.LoadingMain));
+        }
+        final EnumSet<TestCase> loadingTests =
+            EnumSet.of(TestCase.LoadingApplet, TestCase.LoadingMain);
+        int testrun = 0;
+        for (TestCase test : tests) {
+            if (loadingTests.contains(test)) {
+                if (testrun > 0) {
+                    throw new UnsupportedOperationException("Test case "
+                          + test + " must be executed first!");
+                }
+            }
+            System.out.println("Testing "+ test+": ");
+            System.out.println(test.describe());
+            try {
+                test.test();
+            } catch (Exception x) {
+               throw new Error(String.valueOf(test)
+                   + (System.getSecurityManager() == null ? " without " : " with ")
+                   + "security failed: "+x+"\n "+"FAILED: "+test.describe()+"\n", x);
+            } finally {
+                testrun++;
+            }
+            Bridge.changeContext();
+            System.out.println("PASSED: "+ test);
+        }
+    }
+
+    public static void testLoadingApplet() {
+        Bridge.changeContext();
+
+        Logger bar = new Bridge.CustomLogger("com.foo.Bar");
+        LogManager.getLogManager().addLogger(bar);
+        assertNotNull(bar.getParent());
+        testParent(bar);
+        testParent(LogManager.getLogManager().getLogger("global"));
+        testParent(LogManager.getLogManager().getLogger(bar.getName()));
+
+        Bridge.desactivate();
+
+        Logger foo = new Bridge.CustomLogger("com.foo.Foo");
+        boolean b = LogManager.getLogManager().addLogger(foo);
+        assertEquals(Boolean.TRUE, Boolean.valueOf(b));
+        assertNotNull(foo.getParent());
+        testParent(foo);
+        testParent(LogManager.getLogManager().getLogger("global"));
+        testParent(LogManager.getLogManager().getLogger(foo.getName()));
+    }
+
+    public static void testLoadingMain() {
+        Bridge.desactivate();
+
+        Logger bar = new Bridge.CustomLogger("com.foo.Bar");
+        LogManager.getLogManager().addLogger(bar);
+        assertNotNull(bar.getParent());
+        testParent(bar);
+        testParent(LogManager.getLogManager().getLogger("global"));
+        testParent(LogManager.getLogManager().getLogger(bar.getName()));
+
+        Bridge.changeContext();
+
+        Logger foo = new Bridge.CustomLogger("com.foo.Foo");
+        boolean b = LogManager.getLogManager().addLogger(foo);
+        assertEquals(Boolean.TRUE, Boolean.valueOf(b));
+        assertNotNull(foo.getParent());
+        testParent(foo);
+        testParent(LogManager.getLogManager().getLogger("global"));
+        testParent(LogManager.getLogManager().getLogger(foo.getName()));
+
+    }
+
+    public static void testOne() {
+        for (int i=0; i<3 ; i++) {
+            Logger logger1 = Logger.getAnonymousLogger();
+            Logger logger1b = Logger.getAnonymousLogger();
+            Bridge.changeContext();
+            Logger logger2 = Logger.getAnonymousLogger();
+            Logger logger2b = Logger.getAnonymousLogger();
+            Bridge.changeContext();
+            Logger logger3 = new Bridge.CustomAnonymousLogger();
+            Logger logger3b = new Bridge.CustomAnonymousLogger();
+            Bridge.changeContext();
+            Logger logger4 = new Bridge.CustomAnonymousLogger();
+            Logger logger4b = new Bridge.CustomAnonymousLogger();
+        }
+    }
+
+
+    public static void testTwo() {
+        for (int i=0; i<3 ; i++) {
+            Logger logger1 = Logger.getLogger("");
+            Logger logger1b = Logger.getLogger("");
+            assertNotNull(logger1);
+            assertNotNull(logger1b);
+            assertEquals(logger1, logger1b);
+            Bridge.changeContext();
+            Logger logger2 = Logger.getLogger("");
+            Logger logger2b = Logger.getLogger("");
+            assertNotNull(logger2);
+            assertNotNull(logger2b);
+            assertEquals(logger2, logger2b);
+            assertEquals(logger1, logger2);
+        }
+    }
+
+    public static void testThree() {
+        for (int i=0; i<3 ; i++) {
+            Logger logger1 = LogManager.getLogManager().getLogger("");
+            Logger logger1b = LogManager.getLogManager().getLogger("");
+            assertNotNull(logger1);
+            assertNotNull(logger1b);
+            assertEquals(logger1, logger1b);
+            Bridge.changeContext();
+            Logger logger2 = LogManager.getLogManager().getLogger("");
+            Logger logger2b = LogManager.getLogManager().getLogger("");
+            assertNotNull(logger2);
+            assertNotNull(logger2b);
+            assertEquals(logger2, logger2b);
+            assertEquals(logger1, logger2);
+        }
+    }
+
+    public static void testFour() {
+        for (int i=0; i<3 ; i++) {
+            Logger logger1 = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger1b = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            assertNotNull(logger1);
+            assertNotNull(logger1b);
+            assertEquals(logger1, logger1b);
+            Bridge.changeContext();
+
+            Logger logger2 = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger2b = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            assertNotNull(logger2);
+            assertNotNull(logger2b);
+            assertEquals(logger2, logger2b);
+
+            assertEquals(logger1, logger2);
+
+            Bridge.changeContext();
+            Logger logger3 = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger3b = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME);
+            Bridge.changeContext();
+            Logger logger4 = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger4b = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME);
+        }
+    }
+
+    public static void testFive() {
+        for (int i=0; i<3 ; i++) {
+            Logger logger1 = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger1b = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME);
+            assertNotNull(logger1);
+            assertNotNull(logger1b);
+            assertEquals(logger1, logger1b);
+
+            Bridge.changeContext();
+
+            Logger logger2 = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger2b = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME);
+            assertNotNull(logger2);
+            assertNotNull(logger2b);
+            assertEquals(logger2, logger2b);
+
+            assertEquals(logger1, logger2);
+        }
+    }
+
+    /**
+     * This test is designed to test the behavior of additional LogManager instances.
+     * It must be noted that if the security manager is off, then calling
+     * Bridge.changeContext() has actually no effect - which explains why we have
+     * some differences between the cases security manager on & security manager
+     * off.
+     **/
+    public static void testSix() {
+        for (int i=0; i<3 ; i++) {
+            Bridge.desactivate();
+            LogManager manager = new LogManager() {};
+            Logger logger1 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger1b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            assertNull(logger1);
+            assertNull(logger1b);
+            Logger global = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME);
+            manager.addLogger(global);
+            Logger logger2 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger2b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            assertNotNull(logger2);
+            assertNotNull(logger2b);
+            assertEquals(logger2, global);
+            assertEquals(logger2b, global);
+            assertNull(manager.getLogger(""));
+            assertNull(manager.getLogger(""));
+
+            Bridge.changeContext();
+
+            // this is not a supported configuration:
+            // We are in an applet context with several log managers.
+            // We however need to check our assumptions...
+
+            // Applet context => root logger and global logger are not null.
+            //   root == LogManager.getLogManager().rootLogger
+            //   global == Logger.global
+
+            Logger logger3 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger3b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            assertNotNull(logger3);
+            assertNotNull(logger3b);
+            Logger expected = (System.getSecurityManager() != null
+                  ? Logger.getGlobal()
+                  : global);
+            assertEquals(logger3, expected); // in applet context, we will not see
+                  // the LogManager's custom global logger added above...
+            assertEquals(logger3b, expected); // in applet context, we will not see
+                  // the LogManager's custom global logger added above...
+            Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME);
+            manager.addLogger(global2); // adding a global logger will not work in applet context
+               // we will always get back the global logger.
+               // this could be considered as a bug...
+            Logger logger4 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger4b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            assertNotNull(logger4);
+            assertNotNull(logger4b);
+            assertEquals(logger4,  expected); // adding a global logger will not work in applet context
+            assertEquals(logger4b, expected); // adding a global logger will not work in applet context
+
+            Logger logger5 = manager.getLogger("");
+            Logger logger5b = manager.getLogger("");
+            Logger expectedRoot = (System.getSecurityManager() != null
+                  ? LogManager.getLogManager().getLogger("")
+                  : null);
+            assertEquals(logger5, expectedRoot);
+            assertEquals(logger5b, expectedRoot);
+
+        }
+    }
+
+    /**
+     * This test is designed to test the behavior of additional LogManager instances.
+     * It must be noted that if the security manager is off, then calling
+     * Bridge.changeContext() has actually no effect - which explains why we have
+     * some differences between the cases security manager on & security manager
+     * off.
+     **/
+    public static void testSeven() {
+        for (int i=0; i<3 ; i++) {
+            Bridge.desactivate();
+            LogManager manager = new LogManager() {};
+            Logger logger1 = manager.getLogger("");
+            Logger logger1b = manager.getLogger("");
+            assertNull(logger1);
+            assertNull(logger1b);
+            Logger global = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME);
+            manager.addLogger(global);
+            Logger logger2 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger2b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            assertNotNull(logger2);
+            assertNotNull(logger2b);
+            assertEquals(logger2, global);
+            assertEquals(logger2b, global);
+            Logger logger3 = manager.getLogger("");
+            Logger logger3b = manager.getLogger("");
+            assertNull(logger3);
+            assertNull(logger3b);
+            Logger root = new Bridge.CustomLogger("");
+            manager.addLogger(root);
+            Logger logger4 = manager.getLogger("");
+            Logger logger4b = manager.getLogger("");
+            assertNotNull(logger4);
+            assertNotNull(logger4b);
+            assertEquals(logger4, root);
+            assertEquals(logger4b, root);
+
+            Bridge.changeContext();
+
+            // this is not a supported configuration:
+            // We are in an applet context with several log managers.
+            // We haowever need to check our assumptions...
+
+            // Applet context => root logger and global logger are not null.
+            //   root == LogManager.getLogManager().rootLogger
+            //   global == Logger.global
+
+            Logger logger5 = manager.getLogger("");
+            Logger logger5b = manager.getLogger("");
+            Logger expectedRoot = (System.getSecurityManager() != null
+                  ? LogManager.getLogManager().getLogger("")
+                  : root);
+
+            assertNotNull(logger5);
+            assertNotNull(logger5b);
+            assertEquals(logger5, expectedRoot);
+            assertEquals(logger5b, expectedRoot);
+            if (System.getSecurityManager() != null) {
+                assertNotEquals(logger5, root);
+                assertNotEquals(logger5b, root);
+            }
+
+            Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME);
+            manager.addLogger(global2); // adding a global logger will not work in applet context
+               // we will always get back the global logger.
+               // this could be considered as a bug...
+            Logger logger6 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger logger6b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME);
+            Logger expectedGlobal = (System.getSecurityManager() != null
+                  ? Logger.getGlobal()
+                  : global);
+            assertNotNull(logger6);
+            assertNotNull(logger6b);
+            assertEquals(logger6, expectedGlobal); // adding a global logger will not work in applet context
+            assertEquals(logger6b, expectedGlobal); // adding a global logger will not work in applet context
+
+            Logger root2 = new Bridge.CustomLogger("");
+            manager.addLogger(root2); // adding a root logger will not work in applet context
+               // we will always get back the default manager's root logger.
+               // this could be considered as a bug...
+            Logger logger7 = manager.getLogger("");
+            Logger logger7b = manager.getLogger("");
+            assertNotNull(logger7);
+            assertNotNull(logger7b);
+            assertEquals(logger7, expectedRoot); // adding a global logger will not work in applet context
+            assertEquals(logger7b, expectedRoot); // adding a global logger will not work in applet context
+            assertNotEquals(logger7, root2);
+            assertNotEquals(logger7b, root2);
+        }
+    }
+
+    public static void testParent(Logger logger) {
+        Logger l = logger;
+        while (l.getParent() != null) {
+            l = l.getParent();
+        }
+        assertEquals("", l.getName());
+    }
+
+    public static class TestError extends RuntimeException {
+        public TestError(String msg) {
+            super(msg);
+        }
+    }
+
+    public static void assertNotNull(Object obj) {
+        if (obj == null) throw new NullPointerException();
+    }
+
+    public static void assertNull(Object obj) {
+        if (obj != null) throw new TestError("Null expected, got "+obj);
+    }
+
+    public static void assertEquals(Object o1, Object o2) {
+        if (o1 != o2) {
+            throw new TestError(o1 + " != " + o2);
+        }
+    }
+
+    public static void assertNotEquals(Object o1, Object o2) {
+        if (o1 == o2) {
+            throw new TestError(o1 + " == " + o2);
+        }
+    }
+}
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java	Wed Jul 03 14:35:10 2013 -0700
@@ -26,13 +26,16 @@
 
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 import java.util.stream.DoubleStream;
 import java.util.stream.IntStream;
 import java.util.stream.LambdaTestHelpers;
 import java.util.stream.LongStream;
 import java.util.stream.OpTestCase;
 import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import java.util.stream.StreamTestDataProvider;
 import java.util.stream.TestData;
 
@@ -192,6 +195,53 @@
         }
     }
 
+    public void testSkipLimitOpsWithNonSplittingSpliterator() {
+        class NonSplittingNotSubsizedOrderedSpliterator<T> implements Spliterator<T> {
+            Spliterator<T> s;
+
+            NonSplittingNotSubsizedOrderedSpliterator(Spliterator<T> s) {
+                assert s.hasCharacteristics(Spliterator.ORDERED);
+                this.s = s;
+            }
+
+            @Override
+            public boolean tryAdvance(Consumer<? super T> action) {
+                return s.tryAdvance(action);
+            }
+
+            @Override
+            public void forEachRemaining(Consumer<? super T> action) {
+                s.forEachRemaining(action);
+            }
+
+            @Override
+            public Spliterator<T> trySplit() {
+                return null;
+            }
+
+            @Override
+            public long estimateSize() {
+                return s.estimateSize();
+            }
+
+            @Override
+            public int characteristics() {
+                return s.characteristics() & ~(Spliterator.SUBSIZED);
+            }
+
+            @Override
+            public Comparator<? super T> getComparator() {
+                return s.getComparator();
+            }
+        }
+        List<Integer> list = IntStream.range(0, 100).boxed().collect(Collectors.toList());
+        TestData.OfRef<Integer> data = TestData.Factory.ofSupplier(
+                "Non splitting, not SUBSIZED, ORDERED, stream",
+                () -> StreamSupport.stream(new NonSplittingNotSubsizedOrderedSpliterator<>(list.spliterator())));
+
+        testSkipLimitOps("testSkipLimitOpsWithNonSplittingSpliterator", data);
+    }
+
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
     public void testLimitOps(String name, TestData.OfRef<Integer> data) {
         List<Integer> limits = sizes(data.size());
--- a/jdk/test/tools/pack200/AttributeTests.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/AttributeTests.java	Wed Jul 03 14:35:10 2013 -0700
@@ -37,6 +37,7 @@
     public static void main(String... args) throws Exception {
         test6746111();
         testMethodParameters();
+        Utils.cleanup();
     }
 
     /*
--- a/jdk/test/tools/pack200/BandIntegrity.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/BandIntegrity.java	Wed Jul 03 14:35:10 2013 -0700
@@ -40,7 +40,7 @@
  * the java packer and unpacker must be called in the same java instance.
  */
 public class BandIntegrity {
-        public static void main(String... args)  throws IOException {
+    public static void main(String... args) throws IOException {
         File testFile = new File("test.jar");
         Utils.jar("cvf", testFile.getName(),
                 "-C", Utils.TEST_CLS_DIR.getAbsolutePath(),
@@ -56,6 +56,7 @@
         Utils.createFile(configFile, scratch);
         File outFile = new File("out.jar");
         Utils.repack(testFile, outFile, true,
-                     "-v", "--config-file=" + configFile.getName());
+                "-v", "--config-file=" + configFile.getName());
+        Utils.cleanup();
     }
 }
--- a/jdk/test/tools/pack200/CommandLineTests.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/CommandLineTests.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -83,6 +83,11 @@
             Utils.recursiveCopy(Utils.JavaSDK, EXP_SDK);
             creatConfigFile();
     }
+    // cleanup the test area
+    static void cleanup() throws IOException {
+        Utils.recursiveDelete(EXP_SDK);
+        Utils.cleanup();
+    }
 
     // Hopefully, this should be kept in sync with what the installer does.
     static void creatConfigFile() throws IOException {
@@ -172,6 +177,7 @@
             init();
             testJRE();
             testJDK();
+            cleanup(); // cleanup only if we pass successfully
         } catch (IOException ioe) {
             throw new RuntimeException(ioe);
         }
--- a/jdk/test/tools/pack200/InstructionTests.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/InstructionTests.java	Wed Jul 03 14:35:10 2013 -0700
@@ -35,6 +35,7 @@
 public class InstructionTests {
     public static void main(String... args) throws Exception {
         testInvokeOpCodes();
+        Utils.cleanup();
     }
     /*
      * the following should produce invokestatic and invokespecial
--- a/jdk/test/tools/pack200/Pack200Props.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/Pack200Props.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -31,6 +31,7 @@
  */
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -45,11 +46,12 @@
 
 public class Pack200Props {
 
-    public static void main(String... args) {
+    public static void main(String... args) throws IOException {
         verifyDefaults();
         File out = new File("test" + Utils.PACK_FILE_EXT);
         out.delete();
         verifySegmentLimit(out);
+        Utils.cleanup();
     }
 
     static void verifySegmentLimit(File outFile) {
--- a/jdk/test/tools/pack200/Pack200Test.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/Pack200Test.java	Wed Jul 03 14:35:10 2013 -0700
@@ -66,7 +66,7 @@
         }
     }
 
-    private static void doPackUnpack() {
+    private static void doPackUnpack() throws IOException {
         for (File in : jarList) {
             JarOutputStream javaUnpackerStream = null;
             JarOutputStream nativeUnpackerStream = null;
@@ -117,12 +117,13 @@
                 Utils.close((Closeable) jarFile);
             }
         }
+        Utils.cleanup(); // cleanup artifacts, if successful run
     }
 
     /**
      * @param args the command line arguments
      */
-    public static void main(String[] args) {
+    public static void main(String[] args) throws IOException {
         // select the jars carefully, adding more jars will increase the
         // testing time, especially for jprt.
         jarList.add(Utils.locateJar("tools.jar"));
--- a/jdk/test/tools/pack200/PackageVersionTest.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/PackageVersionTest.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -54,7 +53,7 @@
     public final static int JAVA7_PACKAGE_MAJOR_VERSION = 170;
     public final static int JAVA7_PACKAGE_MINOR_VERSION = 1;
 
-    public static void main(String... args) {
+    public static void main(String... args) throws IOException {
         if (!javaHome.getName().endsWith("jre")) {
             throw new RuntimeException("Error: requires an SDK to run");
         }
@@ -78,6 +77,7 @@
         // test for resource file, ie. no class files
         verifyPack("Test6.java", JAVA5_PACKAGE_MAJOR_VERSION,
                 JAVA5_PACKAGE_MINOR_VERSION);
+        Utils.cleanup();
     }
 
     static void verify6991164() {
--- a/jdk/test/tools/pack200/RepackTest.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/RepackTest.java	Wed Jul 03 14:35:10 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
@@ -36,6 +36,7 @@
 
     public static void main(String... args) throws Exception {
         testRepack();
+        Utils.cleanup();
     }
 
     /*
--- a/jdk/test/tools/pack200/T7007157.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/T7007157.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -63,5 +63,6 @@
             Utils.close(fos);
             Utils.close(jarFile);
         }
+        Utils.cleanup();
     }
 }
--- a/jdk/test/tools/pack200/TestExceptions.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/TestExceptions.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -219,12 +219,13 @@
         }
     }
 
-    public static void main(String... args) {
+    public static void main(String... args) throws IOException {
         init();
         pack200Test1();
         pack200Test2();
         pack200Test3();
         unpack200Test1();
+        Utils.cleanup();
     }
 
     // containers for test inputs and management
--- a/jdk/test/tools/pack200/TimeStamp.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/TimeStamp.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -149,6 +149,7 @@
             Utils.close(jf1);
             Utils.close(jf2);
         }
+        Utils.cleanup();
         if (errors > 0) {
             throw new RuntimeException("FAIL:" + errors + " error(s) encounted");
         }
--- a/jdk/test/tools/pack200/UnpackerMemoryTest.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/UnpackerMemoryTest.java	Wed Jul 03 14:35:10 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -81,6 +81,7 @@
                 Utils.close(fos);
             }
         }
+        Utils.cleanup();
     }
 }
 
--- a/jdk/test/tools/pack200/Utils.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/Utils.java	Wed Jul 03 14:35:10 2013 -0700
@@ -75,6 +75,7 @@
     static final File   TEST_CLS_DIR = new File(System.getProperty("test.classes"));
     static final String VERIFIER_DIR_NAME = "pack200-verifier";
     static final File   VerifierJar = new File(VERIFIER_DIR_NAME + JAR_FILE_EXT);
+    static final File   XCLASSES = new File("xclasses");
 
     private Utils() {} // all static
 
@@ -95,8 +96,7 @@
         }
         List<File> javaFileList = findFiles(srcDir, createFilter(JAVA_FILE_EXT));
         File tmpFile = File.createTempFile("javac", ".tmp");
-        File classesDir = new File("xclasses");
-        classesDir.mkdirs();
+        XCLASSES.mkdirs();
         FileOutputStream fos = null;
         PrintStream ps = null;
         try {
@@ -111,14 +111,14 @@
         }
 
         compiler("-d",
-                "xclasses",
+                XCLASSES.getName(),
                 "@" + tmpFile.getAbsolutePath());
 
         jar("cvfe",
             VerifierJar.getName(),
             "sun.tools.pack.verify.Main",
             "-C",
-            "xclasses",
+            XCLASSES.getName(),
             ".");
     }
 
@@ -175,6 +175,33 @@
         };
     }
 
+    /*
+     * clean up all the usual suspects
+     */
+    static void cleanup() throws IOException {
+        recursiveDelete(XCLASSES);
+        List<File> toDelete = new ArrayList<>();
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".out")));
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".bak")));
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".jar")));
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".pack")));
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".bnd")));
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".txt")));
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".idx")));
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".gidx")));
+        for (File f : toDelete) {
+            f.delete();
+        }
+    }
+
     static final FileFilter DIR_FILTER = new FileFilter() {
         public boolean accept(File pathname) {
             if (pathname.isDirectory()) {
@@ -199,6 +226,9 @@
             Files.createDirectories(parent);
         }
         Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING);
+        if (dst.isDirectory() && !dst.canWrite()) {
+            dst.setWritable(true);
+        }
     }
 
     static String baseName(File file, String extension) {
--- a/jdk/test/tools/pack200/typeannos/TestTypeAnnotations.java	Tue Jul 02 16:38:09 2013 -0700
+++ b/jdk/test/tools/pack200/typeannos/TestTypeAnnotations.java	Wed Jul 03 14:35:10 2013 -0700
@@ -41,5 +41,6 @@
                 "-C", Utils.TEST_CLS_DIR.getAbsolutePath(),
                 ".");
         Utils.testWithRepack(testFile, "--unknown-attribute=error");
+        Utils.cleanup();
     }
 }