changeset 19234:e7d6eeba4967

Merge
author duke
date Wed, 05 Jul 2017 19:07:11 +0200
parents 28e832b479d2 7608cc6b4166
children 45992754c3b7
files hotspot/test/runtime/7196045/Test7196045.java hotspot/test/runtime/8000968/Test8000968.sh jdk/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java jdk/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh
diffstat 282 files changed, 7205 insertions(+), 3304 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags-top-repo	Tue Aug 13 10:34:38 2013 -0700
+++ b/.hgtags-top-repo	Wed Jul 05 19:07:11 2017 +0200
@@ -223,3 +223,4 @@
 59dc9da813794c924a0383c2a6241af94defdfed jdk8-b99
 d2dcb110e9dbaf9903c05b211df800e78e4b394e jdk8-b100
 9f74a220677dc265a724515d8e2617548cef62f1 jdk8-b101
+5eb3c1dc348f72a7f84f7d9d07834e8bbe09a799 jdk8-b102
--- a/hotspot/.hgtags	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/.hgtags	Wed Jul 05 19:07:11 2017 +0200
@@ -365,3 +365,5 @@
 46487ba40ff225654d0c51787ed3839bafcbd9f3 hs25-b43
 f6921c876db192bba389cec062855a66372da01c jdk8-b101
 530fe88b3b2c710f42810b3580d86a0d83ad6c1c hs25-b44
+c4697c1c448416108743b59118b4a2498b339d0c jdk8-b102
+7f55137d6aa81efc6eb0035813709f2cb6a26b8b hs25-b45
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/JVMTIThreadState.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/JVMTIThreadState.java	Wed Jul 05 19:07:11 2017 +0200
@@ -29,11 +29,10 @@
     public static final int JVMTI_THREAD_STATE_ALIVE = 0x0001;
     public static final int JVMTI_THREAD_STATE_TERMINATED = 0x0002;
     public static final int JVMTI_THREAD_STATE_RUNNABLE = 0x0004;
-    public static final int JVMTI_THREAD_STATE_WAITING = 0x0008;
+    public static final int JVMTI_THREAD_STATE_WAITING = 0x0080;
     public static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
     public static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
     public static final int JVMTI_THREAD_STATE_SLEEPING = 0x0040;
-    public static final int JVMTI_THREAD_STATE_WAITING_FOR_NOTIFICATION = 0x0080;
     public static final int JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100;
     public static final int JVMTI_THREAD_STATE_PARKED = 0x0200;
     public static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java	Wed Jul 05 19:07:11 2017 +0200
@@ -32,7 +32,7 @@
 // to the sys_thread_t structure of the classic JVM implementation.
 public class OSThread extends VMObject {
     private static JIntField interruptedField;
-    private static JIntField threadIdField;
+    private static Field threadIdField;
     static {
         VM.registerVMInitializedObserver(new Observer() {
             public void update(Observable o, Object data) {
@@ -44,7 +44,7 @@
     private static synchronized void initialize(TypeDataBase db) {
         Type type = db.lookupType("OSThread");
         interruptedField = type.getJIntField("_interrupted");
-        threadIdField = type.getJIntField("_thread_id");
+        threadIdField = type.getField("_thread_id");
     }
 
     public OSThread(Address addr) {
@@ -56,7 +56,7 @@
     }
 
     public int threadId() {
-        return (int)threadIdField.getValue(addr);
+        return threadIdField.getJInt(addr);
     }
 
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,23 +74,24 @@
     public void run() {
         // Ready to go with the database...
         try {
-            // The name of the filter always comes from a System property.
-            // If we have a pkgList, pass it, otherwise let the filter read
-            // its own System property for the list of classes.
-            String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter",
-                                                        "sun.jvm.hotspot.tools.jcore.PackageNameFilter");
-            try {
-                Class filterClass = Class.forName(filterClassName);
-                if (pkgList == null) {
-                    classFilter = (ClassFilter) filterClass.newInstance();
-                } else {
-                    Constructor con = filterClass.getConstructor(String.class);
-                    classFilter = (ClassFilter) con.newInstance(pkgList);
+            if (classFilter == null) {
+                // If not already set, the name of the filter comes from a System property.
+                // If we have a pkgList, pass it, otherwise let the filter read
+                // its own System property for the list of classes.
+                String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter",
+                                                            "sun.jvm.hotspot.tools.jcore.PackageNameFilter");
+                try {
+                    Class filterClass = Class.forName(filterClassName);
+                    if (pkgList == null) {
+                        classFilter = (ClassFilter) filterClass.newInstance();
+                    } else {
+                        Constructor con = filterClass.getConstructor(String.class);
+                        classFilter = (ClassFilter) con.newInstance(pkgList);
+                    }
+                } catch(Exception exp) {
+                    System.err.println("Warning: Can not create class filter!");
                 }
-            } catch(Exception exp) {
-                System.err.println("Warning: Can not create class filter!");
             }
-
             String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", ".");
             setOutputDirectory(outputDirectory);
 
--- a/hotspot/make/hotspot_version	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/make/hotspot_version	Wed Jul 05 19:07:11 2017 +0200
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=25
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=44
+HS_BUILD_NUMBER=45
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Jul 05 19:07:11 2017 +0200
@@ -2295,7 +2295,7 @@
       if (gen_type_check) {
         // We have determined that offset == referent_offset && src != null.
         // if (src->_klass->_reference_type == REF_NONE) -> continue
-        __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), UseCompressedKlassPointers ? T_OBJECT : T_ADDRESS), src_klass);
+        __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), src_klass);
         LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(InstanceKlass::reference_type_offset()), T_BYTE);
         LIR_Opr reference_type = new_register(T_INT);
         __ move(reference_type_addr, reference_type);
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Jul 05 19:07:11 2017 +0200
@@ -878,7 +878,7 @@
 
 instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
   ResourceMark rm(THREAD);
-  EventMark m("loading class " INTPTR_FORMAT, (address)h_name);
+  EventMark m("loading class %s", h_name->as_C_string());
   ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
 
   stringStream st;
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 19:07:11 2017 +0200
@@ -60,6 +60,28 @@
 #define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp"
 #define DEFAULT_JAVA_LAUNCHER  "generic"
 
+// Disable options not supported in this release, with a warning if they
+// were explicitly requested on the command-line
+#define UNSUPPORTED_OPTION(opt, description)                    \
+do {                                                            \
+  if (opt) {                                                    \
+    if (FLAG_IS_CMDLINE(opt)) {                                 \
+      warning(description " is disabled in this release.");     \
+    }                                                           \
+    FLAG_SET_DEFAULT(opt, false);                               \
+  }                                                             \
+} while(0)
+
+#define UNSUPPORTED_GC_OPTION(gc)                                     \
+do {                                                                  \
+  if (gc) {                                                           \
+    if (FLAG_IS_CMDLINE(gc)) {                                        \
+      warning(#gc " is not supported in this VM.  Using Serial GC."); \
+    }                                                                 \
+    FLAG_SET_DEFAULT(gc, false);                                      \
+  }                                                                   \
+} while(0)
+
 char**  Arguments::_jvm_flags_array             = NULL;
 int     Arguments::_num_jvm_flags               = 0;
 char**  Arguments::_jvm_args_array              = NULL;
@@ -3128,14 +3150,17 @@
     FLAG_SET_DEFAULT(UseLargePages, false);
   }
 
-  // Tiered compilation is undefined with C1.
-  TieredCompilation = false;
 #else
   if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) {
     FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1);
   }
 #endif
 
+#ifndef TIERED
+  // Tiered compilation is undefined.
+  UNSUPPORTED_OPTION(TieredCompilation, "TieredCompilation");
+#endif
+
   // If we are running in a headless jre, force java.awt.headless property
   // to be true unless the property has already been set.
   // Also allow the OS environment variable JAVA_AWT_HEADLESS to set headless state.
@@ -3278,29 +3303,6 @@
   }
 }
 
-// Disable options not supported in this release, with a warning if they
-// were explicitly requested on the command-line
-#define UNSUPPORTED_OPTION(opt, description)                    \
-do {                                                            \
-  if (opt) {                                                    \
-    if (FLAG_IS_CMDLINE(opt)) {                                 \
-      warning(description " is disabled in this release.");     \
-    }                                                           \
-    FLAG_SET_DEFAULT(opt, false);                               \
-  }                                                             \
-} while(0)
-
-
-#define UNSUPPORTED_GC_OPTION(gc)                                     \
-do {                                                                  \
-  if (gc) {                                                           \
-    if (FLAG_IS_CMDLINE(gc)) {                                        \
-      warning(#gc " is not supported in this VM.  Using Serial GC."); \
-    }                                                                 \
-    FLAG_SET_DEFAULT(gc, false);                                      \
-  }                                                                   \
-} while(0)
-
 #if !INCLUDE_ALL_GCS
 static void force_serial_gc() {
   FLAG_SET_DEFAULT(UseSerialGC, true);
--- a/hotspot/src/share/vm/services/gcNotifier.cpp	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/src/share/vm/services/gcNotifier.cpp	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -211,9 +211,9 @@
     NotificationMark nm(request);
     Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD);
 
-    Handle objName = java_lang_String::create_from_platform_dependent_str(request->gcManager->name(), CHECK);
-    Handle objAction = java_lang_String::create_from_platform_dependent_str(request->gcAction, CHECK);
-    Handle objCause = java_lang_String::create_from_platform_dependent_str(request->gcCause, CHECK);
+    Handle objName = java_lang_String::create_from_str(request->gcManager->name(), CHECK);
+    Handle objAction = java_lang_String::create_from_str(request->gcAction, CHECK);
+    Handle objCause = java_lang_String::create_from_str(request->gcCause, CHECK);
 
     Klass* k = Management::sun_management_GarbageCollectorImpl_klass(CHECK);
     instanceKlassHandle gc_mbean_klass(THREAD, k);
--- a/hotspot/src/share/vm/services/management.cpp	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/src/share/vm/services/management.cpp	Wed Jul 05 19:07:11 2017 +0200
@@ -1831,13 +1831,13 @@
  private:
   objArrayHandle _names_strings;
   char **_names_chars;
-  typeArrayOop _times;
+  typeArrayHandle _times;
   int _names_len;
   int _times_len;
   int _count;
 
  public:
-  ThreadTimesClosure(objArrayHandle names, typeArrayOop times);
+  ThreadTimesClosure(objArrayHandle names, typeArrayHandle times);
   ~ThreadTimesClosure();
   virtual void do_thread(Thread* thread);
   void do_unlocked();
@@ -1845,9 +1845,9 @@
 };
 
 ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,
-                                       typeArrayOop times) {
+                                       typeArrayHandle times) {
   assert(names() != NULL, "names was NULL");
-  assert(times != NULL, "times was NULL");
+  assert(times() != NULL, "times was NULL");
   _names_strings = names;
   _names_len = names->length();
   _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);
@@ -1925,7 +1925,7 @@
   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times));
   typeArrayHandle times_ah(THREAD, ta);
 
-  ThreadTimesClosure ttc(names_ah, times_ah());
+  ThreadTimesClosure ttc(names_ah, times_ah);
   {
     MutexLockerEx ml(Threads_lock);
     Threads::threads_do(&ttc);
--- a/hotspot/src/share/vm/utilities/exceptions.cpp	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp	Wed Jul 05 19:07:11 2017 +0200
@@ -125,13 +125,13 @@
 }
 
 void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) {
+  ResourceMark rm;
   assert(h_exception() != NULL, "exception should not be NULL");
 
   // tracing (do this up front - so it works during boot strapping)
   if (TraceExceptions) {
     ttyLocker ttyl;
-    ResourceMark rm;
-    tty->print_cr("Exception <%s>%s%s (" INTPTR_FORMAT " ) \n"
+    tty->print_cr("Exception <%s%s%s> (" INTPTR_FORMAT ") \n"
                   "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
                   h_exception->print_value_string(),
                   message ? ": " : "", message ? message : "",
@@ -141,7 +141,9 @@
   NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message));
 
   // Check for special boot-strapping/vm-thread handling
-  if (special_exception(thread, file, line, h_exception)) return;
+  if (special_exception(thread, file, line, h_exception)) {
+    return;
+  }
 
   assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable");
 
@@ -149,7 +151,9 @@
   thread->set_pending_exception(h_exception(), file, line);
 
   // vm log
-  Events::log_exception(thread, "Threw " INTPTR_FORMAT " at %s:%d", (address)h_exception(), file, line);
+  Events::log_exception(thread, "Exception <%s%s%s> (" INTPTR_FORMAT ") thrown at [%s, line %d]",
+                        h_exception->print_value_string(), message ? ": " : "", message ? message : "",
+                        (address)h_exception(), file, line);
 }
 
 
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp	Wed Jul 05 19:07:11 2017 +0200
@@ -395,7 +395,13 @@
 template<class E, MEMFLAGS F, unsigned int N>
 bool GenericTaskQueue<E, F, N>::pop_global(E& t) {
   Age oldAge = _age.get();
-  uint localBot = _bottom;
+  // Architectures with weak memory model require a barrier here
+  // to guarantee that bottom is not older than age,
+  // which is crucial for the correctness of the algorithm.
+#if !(defined SPARC || defined IA32 || defined AMD64)
+  OrderAccess::fence();
+#endif
+  uint localBot = OrderAccess::load_acquire((volatile juint*)&_bottom);
   uint n_elems = size(localBot, oldAge.top());
   if (n_elems == 0) {
     return false;
@@ -644,7 +650,7 @@
 template<class E, MEMFLAGS F, unsigned int N> inline bool
 GenericTaskQueue<E, F, N>::push(E t) {
   uint localBot = _bottom;
-  assert((localBot >= 0) && (localBot < N), "_bottom out of range.");
+  assert(localBot < N, "_bottom out of range.");
   idx_t top = _age.top();
   uint dirty_n_elems = dirty_size(localBot, top);
   assert(dirty_n_elems < N, "n_elems out of range.");
--- a/hotspot/test/compiler/codecache/CheckUpperLimit.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/test/compiler/codecache/CheckUpperLimit.java	Wed Jul 05 19:07:11 2017 +0200
@@ -35,10 +35,6 @@
     ProcessBuilder pb;
     OutputAnalyzer out;
 
-    pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2048m", "-version");
-    out = new OutputAnalyzer(pb.start());
-    out.shouldHaveExitValue(0);
-
     pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2049m", "-version");
     out = new OutputAnalyzer(pb.start());
     out.shouldContain("Invalid ReservedCodeCacheSize=");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/unsafe/GetUnsafeObjectG1PreBarrier.java	Wed Jul 05 19:07:11 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8016474
+ * @summary The bug only happens with C1 and G1 using a different ObjectAlignmentInBytes than KlassAlignmentInBytes (which is 8)
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32 GetUnsafeObjectG1PreBarrier
+ */
+
+import java.lang.reflect.Field;
+
+import sun.misc.Unsafe;
+
+public class GetUnsafeObjectG1PreBarrier {
+    private static final Unsafe unsafe;
+    private static final int N = 100_000;
+
+    static {
+        try {
+            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafe.setAccessible(true);
+            unsafe = (Unsafe) theUnsafe.get(null);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    public Object a;
+
+    public static void main(String[] args) throws Throwable {
+        new GetUnsafeObjectG1PreBarrier();
+    }
+
+    public GetUnsafeObjectG1PreBarrier() throws Throwable {
+        doit();
+    }
+
+    private void doit() throws Throwable {
+        Field field = GetUnsafeObjectG1PreBarrier.class.getField("a");
+        long fieldOffset = unsafe.objectFieldOffset(field);
+
+        for (int i = 0; i < N; i++) {
+            readField(this, fieldOffset);
+        }
+    }
+
+    private void readField(Object o, long fieldOffset) {
+        unsafe.getObject(o, fieldOffset);
+    }
+}
--- a/hotspot/test/runtime/7196045/Test7196045.java	Tue Aug 13 10:34:38 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-/*
- * @test
- * @bug 7196045
- * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API.
- * @run main/othervm -XX:+UsePerfData Test7196045
- */
-
-import java.lang.management.ManagementFactory;
-import javax.management.JMException;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-public class Test7196045 {
-
-    public static long duration = 1000 * 60 * 2;
-    private static final String HOTSPOT_INTERNAL = "sun.management:type=HotspotInternal";
-
-    public static void main(String[] args) {
-
-        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-        ObjectName objName= null;
-        try {
-            ObjectName hotspotInternal = new ObjectName(HOTSPOT_INTERNAL);
-            try {
-                server.registerMBean(new sun.management.HotspotInternal(), hotspotInternal);
-            } catch (JMException e) {
-                throw new RuntimeException("HotSpotWatcher: Failed to register the HotspotInternal MBean" + e);
-            }
-            objName= new ObjectName("sun.management:type=HotspotThreading");
-
-        } catch (MalformedObjectNameException e1) {
-            throw new RuntimeException("Bad object name" + e1);
-        }
-
-        long endTime = System.currentTimeMillis() + duration;
-        long i = 0;
-        while (true) {
-            try {
-                server.getAttribute(objName, "InternalThreadCpuTimes");
-            } catch (Exception ex) {
-                System.err.println("Exception while getting attribute: " + ex);
-            }
-            i++;
-            if (i % 10000 == 0) {
-                System.out.println("Successful iterations: " + i);
-            }
-            if (System.currentTimeMillis() > endTime) {
-                break;
-            }
-        }
-        System.out.println("PASSED.");
-    }
-}
--- a/hotspot/test/runtime/8000968/Test8000968.sh	Tue Aug 13 10:34:38 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-#
-#  Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-#  This code is free software; you can redistribute it and/or modify it
-#  under the terms of the GNU General Public License version 2 only, as
-#  published by the Free Software Foundation.
-#
-#  This code is distributed in the hope that it will be useful, but WITHOUT
-#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-#  version 2 for more details (a copy is included in the LICENSE file that
-#  accompanied this code).
-#
-#  You should have received a copy of the GNU General Public License version
-#  2 along with this work; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-#  or visit www.oracle.com if you need additional information or have any
-#  questions.
-#
-
-
-# @test Test8000968.sh
-# @bug 8000968
-# @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
-# @run shell Test8000968.sh
-#
-
-if [ "${TESTJAVA}" = "" ]
-then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  printf "TESTJAVA not set, selecting " ${TESTJAVA}
-  printf "  If this is incorrect, try setting the variable manually.\n"
-fi
-
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  Windows_* )
-    FS="\\"
-    NULL=NUL
-    ;;
-  * )
-    FS="/"
-    NULL=/dev/null
-    ;;
-esac
-
-JAVA=${TESTJAVA}${FS}bin${FS}java
-
-#
-# See if platform has 64 bit java.
-#
-${JAVA} ${TESTVMOPTS} -d64 -version 2>&1 | grep -i "does not support" > ${NULL}
-if [ "$?" != "1" ]
-then
-  printf "Platform is 32 bit, does not support -XX:ObjectAlignmentInBytes= option.\n"
-  printf "Passed.\n"
-  exit 0
-fi
-
-#
-# Test -XX:ObjectAlignmentInBytes with -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops.
-#
-${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=16 -version 2>&1 > ${NULL}
-if [ "$?" != "0" ]
-then
-  printf "FAILED: -XX:ObjectAlignmentInBytes=16 option did not work.\n"
-  exit 1
-fi
-
-${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=32 -version 2>&1 > ${NULL}
-if [ "$?" != "0" ]
-then
-  printf "FAILED: -XX:ObjectAlignmentInBytes=32 option did not work.\n"
-  exit 1
-fi
-
-${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=64 -version 2>&1 > ${NULL}
-if [ "$?" != "0" ]
-then
-  printf "FAILED: -XX:ObjectAlignmentInBytes=64 option did not work.\n"
-  exit 1
-fi
-
-${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=128 -version 2>&1 > ${NULL}
-if [ "$?" != "0" ]
-then
-  printf "FAILED: -XX:ObjectAlignmentInBytes=128 option did not work.\n"
-  exit 1
-fi
-
-
-printf "Passed.\n"
-exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java	Wed Jul 05 19:07:11 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8000968
+ * @key regression
+ * @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CompressedKlassPointerAndOops {
+
+    public static void main(String[] args) throws Exception {
+
+        if (!Platform.is64bit()) {
+            // Can't test this on 32 bit, just pass
+            System.out.println("Skipping test on 32bit");
+            return;
+        }
+
+        runWithAlignment(16);
+        runWithAlignment(32);
+        runWithAlignment(64);
+        runWithAlignment(128);
+    }
+
+    private static void runWithAlignment(int alignment) throws Exception {
+        ProcessBuilder pb;
+        OutputAnalyzer output;
+
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+UseCompressedKlassPointers",
+            "-XX:+UseCompressedOops",
+            "-XX:ObjectAlignmentInBytes=" + alignment,
+            "-version");
+
+        output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/InternalApi/ThreadCpuTimesDeadlock.java	Wed Jul 05 19:07:11 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 7196045
+ * @bug 8014294
+ * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API.
+ * @run main/othervm -XX:+UsePerfData -Xmx32m ThreadCpuTimesDeadlock
+ */
+
+import java.lang.management.ManagementFactory;
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+public class ThreadCpuTimesDeadlock {
+
+    public static byte[] dummy;
+    public static long duration = 10 * 1000;
+    private static final String HOTSPOT_INTERNAL = "sun.management:type=HotspotInternal";
+
+    public static void main(String[] args) {
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        ObjectName objName= null;
+        try {
+            ObjectName hotspotInternal = new ObjectName(HOTSPOT_INTERNAL);
+            try {
+                server.registerMBean(new sun.management.HotspotInternal(), hotspotInternal);
+            } catch (JMException e) {
+                throw new RuntimeException("HotSpotWatcher: Failed to register the HotspotInternal MBean" + e);
+            }
+            objName= new ObjectName("sun.management:type=HotspotThreading");
+
+        } catch (MalformedObjectNameException e1) {
+            throw new RuntimeException("Bad object name" + e1);
+        }
+
+        // Thread that allocs memory to generate GC's
+        Thread allocThread = new Thread() {
+          public void run() {
+            while (true) {
+              dummy = new byte[4096];
+            }
+          }
+        };
+
+        allocThread.setDaemon(true);
+        allocThread.start();
+
+        long endTime = System.currentTimeMillis() + duration;
+        long i = 0;
+        while (true) {
+            try {
+                server.getAttribute(objName, "InternalThreadCpuTimes");
+            } catch (Exception ex) {
+                System.err.println("Exception while getting attribute: " + ex);
+            }
+            i++;
+            if (i % 10000 == 0) {
+                System.out.println("Successful iterations: " + i);
+            }
+            if (System.currentTimeMillis() > endTime) {
+                break;
+            }
+        }
+        System.out.println("PASSED.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/OutputAnalyzerReportingTest.java	Wed Jul 05 19:07:11 2017 +0200
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @summary Test the OutputAnalyzer reporting functionality,
+ *     such as printing additional diagnostic info
+ *     (exit code, stdout, stderr, command line, etc.)
+ * @library /testlibrary
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class OutputAnalyzerReportingTest {
+
+    public static void main(String[] args) throws Exception {
+        // Create the output analyzer under test
+        String stdout = "aaaaaa";
+        String stderr = "bbbbbb";
+        OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
+
+        // Expected summary values should be the same for all cases,
+        // since the outputAnalyzer object is the same
+        String expectedExitValue = "-1";
+        String expectedSummary =
+                " stdout: [" + stdout + "];\n" +
+                " stderr: [" + stderr + "]\n" +
+                " exitValue = " + expectedExitValue + "\n";
+
+
+        DiagnosticSummaryTestRunner testRunner =
+                new DiagnosticSummaryTestRunner();
+
+        // should have exit value
+        testRunner.init(expectedSummary);
+        int unexpectedExitValue = 2;
+        try {
+            output.shouldHaveExitValue(unexpectedExitValue);
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should not contain
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldNotContain(stdout);
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should contain
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldContain("unexpected-stuff");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should not match
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldNotMatch("[a]");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should match
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldMatch("[qwerty]");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+    }
+
+    private static class DiagnosticSummaryTestRunner {
+        private ByteArrayOutputStream byteStream =
+                new ByteArrayOutputStream(10000);
+
+        private String expectedSummary = "";
+        private PrintStream errStream;
+
+
+        public void init(String expectedSummary) {
+            this.expectedSummary = expectedSummary;
+            byteStream.reset();
+            errStream = new PrintStream(byteStream);
+            System.setErr(errStream);
+        }
+
+        public void closeAndCheckResults() {
+            // check results
+            errStream.close();
+            String stdErrStr = byteStream.toString();
+            if (!stdErrStr.contains(expectedSummary)) {
+                throw new RuntimeException("The output does not contain "
+                    + "the diagnostic message, or the message is incorrect");
+            }
+        }
+    }
+
+}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Wed Jul 05 19:07:11 2017 +0200
@@ -76,7 +76,8 @@
    */
   public void shouldContain(String expectedString) {
     if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) {
-      throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr: [" + stdout + stderr + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n");
     }
   }
 
@@ -88,7 +89,8 @@
    */
   public void stdoutShouldContain(String expectedString) {
     if (!stdout.contains(expectedString)) {
-      throw new RuntimeException("'" + expectedString + "' missing from stdout: [" + stdout + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + expectedString + "' missing from stdout \n");
     }
   }
 
@@ -100,7 +102,8 @@
    */
   public void stderrShouldContain(String expectedString) {
     if (!stderr.contains(expectedString)) {
-      throw new RuntimeException("'" + expectedString + "' missing from stderr: [" + stderr + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + expectedString + "' missing from stderr \n");
     }
   }
 
@@ -112,10 +115,12 @@
    */
   public void shouldNotContain(String notExpectedString) {
     if (stdout.contains(notExpectedString)) {
-      throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
     }
     if (stderr.contains(notExpectedString)) {
-      throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
     }
   }
 
@@ -127,7 +132,8 @@
    */
   public void stdoutShouldNotContain(String notExpectedString) {
     if (stdout.contains(notExpectedString)) {
-      throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
     }
   }
 
@@ -139,7 +145,8 @@
    */
   public void stderrShouldNotContain(String notExpectedString) {
     if (stderr.contains(notExpectedString)) {
-      throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
     }
   }
 
@@ -154,9 +161,9 @@
       Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (!stdoutMatcher.find() && !stderrMatcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' missing from stdout/stderr: [" + stdout + stderr
-                  + "]\n");
+                + "' missing from stdout/stderr \n");
       }
   }
 
@@ -170,8 +177,9 @@
   public void stdoutShouldMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       if (!matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' missing from stdout: [" + stdout + "]\n");
+                + "' missing from stdout \n");
       }
   }
 
@@ -185,8 +193,9 @@
   public void stderrShouldMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (!matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' missing from stderr: [" + stderr + "]\n");
+                + "' missing from stderr \n");
       }
   }
 
@@ -200,13 +209,15 @@
   public void shouldNotMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       if (matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' found in stdout: [" + stdout + "]\n");
+                  + "' found in stdout \n");
       }
       matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' found in stderr: [" + stderr + "]\n");
+                  + "' found in stderr \n");
       }
   }
 
@@ -220,8 +231,9 @@
   public void stdoutShouldNotMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       if (matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' found in stdout: [" + stdout + "]\n");
+                  + "' found in stdout \n");
       }
   }
 
@@ -235,23 +247,45 @@
   public void stderrShouldNotMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' found in stderr: [" + stderr + "]\n");
+                  + "' found in stderr \n");
       }
   }
 
   /**
-   * Verifiy the exit value of the process
+   * Verify the exit value of the process
    *
    * @param expectedExitValue Expected exit value from process
    * @throws RuntimeException If the exit value from the process did not match the expected value
    */
   public void shouldHaveExitValue(int expectedExitValue) {
       if (getExitValue() != expectedExitValue) {
-          throw new RuntimeException("Exit value " + getExitValue() + " , expected to get " + expectedExitValue);
+          reportDiagnosticSummary();
+          throw new RuntimeException("Expected to get exit value of ["
+                  + expectedExitValue + "]\n");
       }
   }
 
+
+  /**
+   * Report summary that will help to diagnose the problem
+   * Currently includes:
+   *  - standard input produced by the process under test
+   *  - standard output
+   *  - exit code
+   *  Note: the command line is printed by the ProcessTools
+   */
+    private void reportDiagnosticSummary() {
+        String msg =
+            " stdout: [" + stdout + "];\n" +
+            " stderr: [" + stderr + "]\n" +
+            " exitValue = " + getExitValue() + "\n";
+
+        System.err.println(msg);
+    }
+
+
   /**
    * Get the contents of the output buffer (stdout and stderr)
    *
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Wed Jul 05 19:07:11 2017 +0200
@@ -27,6 +27,7 @@
   private static final String osName = System.getProperty("os.name");
   private static final String dataModel = System.getProperty("sun.arch.data.model");
   private static final String vmVersion = System.getProperty("java.vm.version");
+  private static final String osArch = System.getProperty("os.arch");
 
   public static boolean is64bit() {
     return dataModel.equals("64");
@@ -59,4 +60,14 @@
   public static String getVMVersion() {
     return vmVersion;
   }
+
+  // Returns true for sparc and sparcv9.
+  public static boolean isSparc() {
+    return osArch.toLowerCase().startsWith("sparc");
+  }
+
+  public static String getOsArch() {
+    return osArch;
+  }
+
 }
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java	Wed Jul 05 19:07:11 2017 +0200
@@ -31,6 +31,7 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 
 import sun.management.VMManagement;
 
@@ -107,6 +108,22 @@
   }
 
   /**
+   * Get the string containing input arguments passed to the VM
+   *
+   * @return arguments
+   */
+  public static String getVmInputArguments() {
+    RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+
+    List<String> args = runtime.getInputArguments();
+    StringBuilder result = new StringBuilder();
+    for (String arg : args)
+        result.append(arg).append(' ');
+
+    return result.toString();
+  }
+
+  /**
    * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
    *
    * @return String[] with platform specific arguments, empty if there are none
@@ -132,8 +149,13 @@
     Collections.addAll(args, getPlatformSpecificVMArgs());
     Collections.addAll(args, command);
 
+    // Reporting
+    StringBuilder cmdLine = new StringBuilder();
+    for (String cmd : args)
+        cmdLine.append(cmd).append(' ');
+    System.out.println("Command line: [" + cmdLine.toString() + "]");
+
     return new ProcessBuilder(args.toArray(new String[args.size()]));
-
   }
 
 }
--- a/jdk/.hgtags	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/.hgtags	Wed Jul 05 19:07:11 2017 +0200
@@ -223,3 +223,4 @@
 6a099a36589bd933957272ba63e5263bede29971 jdk8-b99
 5be9c5bfcfe9b2a40412b4fb364377d49de014eb jdk8-b100
 6901612328239fbd471d20823113c1cf3fdaebee jdk8-b101
+8ed8e2b4b90e0ac9aa5b3efef51cd576a9db96a9 jdk8-b102
--- a/jdk/makefiles/CompileNativeLibraries.gmk	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/makefiles/CompileNativeLibraries.gmk	Wed Jul 05 19:07:11 2017 +0200
@@ -798,6 +798,16 @@
 	LIBAWT_XAWT_CFLAGS += -DFUNCPROTO=15
 endif
 
+ifeq ($(OPENJDK_TARGET_OS),linux)
+ifndef OPENJDK
+include $(JDK_TOPDIR)/make/closed/xawt.gmk
+endif
+
+ifeq ($(DISABLE_XRENDER),true)
+	LIBAWT_XAWT_CFLAGS += -DDISABLE_XRENDER_BY_DEFAULT=true
+endif
+endif
+
 ifeq ($(MILESTONE),internal)
 	LIBAWT_XAWT_CFLAGS += -DINTERNAL_BUILD
 endif
--- a/jdk/src/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1856,7 +1856,10 @@
         // If we're not valid that means we will shortly be validated and
         // painted, which means we don't have to do anything here.
         if (!isRunsDirty && index >= 0 && index < tabPane.getTabCount()) {
-            tabPane.repaint(getTabBounds(tabPane, index));
+            Rectangle rect = getTabBounds(tabPane, index);
+            if (rect != null) {
+                tabPane.repaint(rect);
+            }
         }
     }
 
--- a/jdk/src/macosx/classes/com/apple/laf/AquaTabbedPaneUI.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaTabbedPaneUI.java	Wed Jul 05 19:07:11 2017 +0200
@@ -702,6 +702,20 @@
     }
 
     /**
+     * Returns the bounds of the specified tab index.  The bounds are
+     * with respect to the JTabbedPane's coordinate space.  If the tab at this
+     * index is not currently visible in the UI, then returns null.
+     */
+    @Override
+    public Rectangle getTabBounds(final JTabbedPane pane, final int i) {
+        if (visibleTabState.needsScrollTabs()
+                && (visibleTabState.isBefore(i) || visibleTabState.isAfter(i))) {
+            return null;
+        }
+        return super.getTabBounds(pane, i);
+    }
+
+    /**
      * Returns the tab index which intersects the specified point
      * in the JTabbedPane's coordinate space.
      */
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Jul 05 19:07:11 2017 +0200
@@ -830,18 +830,19 @@
     //                          UTILITY METHODS
     // ----------------------------------------------------------------------
 
-    /*
-     * Find image to install into Title or into Application icon.
-     * First try icons installed for toplevel. If there is no icon
-     * use default Duke image.
-     * This method shouldn't return null.
+    /**
+     * Find image to install into Title or into Application icon. First try
+     * icons installed for toplevel. Null is returned, if there is no icon and
+     * default Duke image should be used.
      */
     private CImage getImageForTarget() {
-        List<Image> icons = target.getIconImages();
-        if (icons == null || icons.size() == 0) {
-            return null;
+        CImage icon = null;
+        try {
+            icon = CImage.getCreator().createFromImages(target.getIconImages());
+        } catch (Exception ignored) {
+            // Perhaps the icon passed into Java is broken. Skipping this icon.
         }
-        return CImage.getCreator().createFromImages(icons);
+        return icon;
     }
 
     /*
--- a/jdk/src/macosx/native/java/util/SCDynamicStoreConfig.m	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/macosx/native/java/util/SCDynamicStoreConfig.m	Wed Jul 05 19:07:11 2017 +0200
@@ -103,7 +103,6 @@
         CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]);
 
         if (CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
-            NSLog(@"Unexpected CFType for realm Info: %lu", CFGetTypeID(realmInfo));
             return nil;
         }
 
@@ -140,7 +139,6 @@
 
     SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java"), _SCDynamicStoreCallBack, NULL);
     if (store == NULL) {
-        NSLog(@"Unable to load SCDynamicStore to install NotificationCallback");
         return;
     }
 
@@ -171,19 +169,11 @@
 
     SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java-kerberos"), NULL, NULL);
     if (store == NULL) {
-        NSLog(@"Unable to load SCDynamicStore");
-        return NULL;
-    }
-
-    // Create the store if it is NULL and set it.
-    if (store == NULL) {
-        NSLog(@"Invalid value for SCDynamicStore");
         return NULL;
     }
 
     CFTypeRef realms = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALMS);
     if (realms == NULL || CFGetTypeID(realms) != CFArrayGetTypeID()) {
-        NSLog(@"Unable to load realm info from SCDynamicStore");
         if (realms) CFRelease(realms);
         CFRelease(store);
         return NULL;
@@ -192,7 +182,6 @@
     CFTypeRef realmMappings = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALM_MAPPINGS);
 
     if (realmMappings == NULL || CFGetTypeID(realmMappings) != CFArrayGetTypeID()) {
-        NSLog(@"Unable to load realm mapping info from SCDynamicStore");
         if (realmMappings) CFRelease(realmMappings);
         CFRelease(realms);
         CFRelease(store);
--- a/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, 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
@@ -47,6 +47,10 @@
 
 import sun.security.util.PropertyExpander;
 
+import sun.security.provider.PolicyParser.PrincipalEntry;
+import sun.security.provider.PolicyParser.GrantEntry;
+import sun.security.provider.PolicyParser.PermissionEntry;
+
 /**
  * This class represents a default implementation for
  * <code>javax.security.auth.Policy</code>.
@@ -469,7 +473,8 @@
      * @param policyFile the policy Reader object.
      */
     private void init(URL policy) {
-        PolicyParser pp = new PolicyParser(expandProperties);
+        sun.security.provider.PolicyParser pp =
+                new sun.security.provider.PolicyParser(expandProperties);
         try {
             InputStreamReader isr
                 = new InputStreamReader(getInputStream(policy));
@@ -477,12 +482,12 @@
             isr.close();
             KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(),
                                              pp.getKeyStoreType());
-            Enumeration<PolicyParser.GrantEntry> enum_ = pp.grantElements();
+            Enumeration<GrantEntry> enum_ = pp.grantElements();
             while (enum_.hasMoreElements()) {
-                PolicyParser.GrantEntry ge = enum_.nextElement();
+                GrantEntry ge = enum_.nextElement();
                 addGrantEntry(ge, keyStore);
             }
-        } catch (PolicyParser.ParsingException pe) {
+        } catch (sun.security.provider.PolicyParser.ParsingException pe) {
             System.err.println(AUTH_POLICY +
                                 rb.getString(".error.parsing.") + policy);
             System.err.println(AUTH_POLICY +
@@ -521,8 +526,8 @@
      *
      * @return null if signedBy alias is not recognized
      */
-    CodeSource getCodeSource(PolicyParser.GrantEntry ge, KeyStore keyStore)
-        throws java.net.MalformedURLException
+    CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore)
+            throws java.net.MalformedURLException
     {
         Certificate[] certs = null;
         if (ge.signedBy != null) {
@@ -559,20 +564,18 @@
     /**
      * Add one policy entry to the vector.
      */
-    private void addGrantEntry(PolicyParser.GrantEntry ge,
-                               KeyStore keyStore) {
+    private void addGrantEntry(GrantEntry ge, KeyStore keyStore) {
 
         if (debug != null) {
             debug.println("Adding policy entry: ");
             debug.println("  signedBy " + ge.signedBy);
             debug.println("  codeBase " + ge.codeBase);
             if (ge.principals != null && ge.principals.size() > 0) {
-                ListIterator<PolicyParser.PrincipalEntry> li =
-                                                ge.principals.listIterator();
+                ListIterator<PrincipalEntry> li = ge.principals.listIterator();
                 while (li.hasNext()) {
-                    PolicyParser.PrincipalEntry pppe = li.next();
-                    debug.println("  " + pppe.principalClass +
-                                        " " + pppe.principalName);
+                    PrincipalEntry pppe = li.next();
+                    debug.println("  " + pppe.getPrincipalClass() +
+                                        " " + pppe.getPrincipalName());
                 }
             }
             debug.println();
@@ -584,10 +587,9 @@
             if (codesource == null) return;
 
             PolicyEntry entry = new PolicyEntry(codesource);
-            Enumeration<PolicyParser.PermissionEntry> enum_ =
-                                                ge.permissionElements();
+            Enumeration<PermissionEntry> enum_ = ge.permissionElements();
             while (enum_.hasMoreElements()) {
-                PolicyParser.PermissionEntry pe = enum_.nextElement();
+                PermissionEntry pe = enum_.nextElement();
                 try {
                     // XXX special case PrivateCredentialPermission-SELF
                     Permission perm;
@@ -998,11 +1000,11 @@
                 return true;
             }
 
-            ListIterator<PolicyParser.PrincipalEntry> pli =
-                                        scs.getPrincipals().listIterator();
+            ListIterator<PrincipalEntry> pli =
+                    scs.getPrincipals().listIterator();
             while (pli.hasNext()) {
 
-                PolicyParser.PrincipalEntry principal = pli.next();
+                PrincipalEntry principal = pli.next();
 
                 // XXX
                 //      if the Policy entry's Principal does not contain a
@@ -1050,30 +1052,29 @@
      *                  if (y == 1), it's the principal name.
      */
     private String[][] getPrincipalInfo
-                (PolicyParser.PrincipalEntry principal,
-                final CodeSource accCs) {
+                (PrincipalEntry principal, final CodeSource accCs) {
 
         // there are 3 possibilities:
         // 1) the entry's Principal class and name are not wildcarded
         // 2) the entry's Principal name is wildcarded only
         // 3) the entry's Principal class and name are wildcarded
 
-        if (!principal.principalClass.equals
-                (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
-            !principal.principalName.equals
-                (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
+        if (!principal.getPrincipalClass().equals
+                (PrincipalEntry.WILDCARD_CLASS) &&
+            !principal.getPrincipalName().equals
+                (PrincipalEntry.WILDCARD_NAME)) {
 
             // build a PrivateCredentialPermission for the principal
             // from the Policy entry
             String[][] info = new String[1][2];
-            info[0][0] = principal.principalClass;
-            info[0][1] = principal.principalName;
+            info[0][0] = principal.getPrincipalClass();
+            info[0][1] = principal.getPrincipalName();
             return info;
 
-        } else if (!principal.principalClass.equals
-                (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
-            principal.principalName.equals
-                (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
+        } else if (!principal.getPrincipalClass().equals
+                (PrincipalEntry.WILDCARD_CLASS) &&
+            principal.getPrincipalName().equals
+                (PrincipalEntry.WILDCARD_NAME)) {
 
             // build a PrivateCredentialPermission for all
             // the Subject's principals that are instances of principalClass
@@ -1088,7 +1089,7 @@
                 // If it doesn't, we should stop here with a ClassCastException.
                 @SuppressWarnings("unchecked")
                 Class<? extends Principal> pClass = (Class<? extends Principal>)
-                        Class.forName(principal.principalClass, false,
+                        Class.forName(principal.getPrincipalClass(), false,
                                       ClassLoader.getSystemClassLoader());
                 principalSet = scs.getSubject().getPrincipals(pClass);
             } catch (Exception e) {
@@ -1387,6 +1388,7 @@
     }
 }
 
+@SuppressWarnings("deprecation")
 class PolicyPermissions extends PermissionCollection {
 
     private static final long serialVersionUID = -1954188373270545523L;
--- a/jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java	Wed Jul 05 19:07:11 2017 +0200
@@ -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
@@ -33,6 +33,7 @@
 import java.lang.reflect.Constructor;
 
 import javax.security.auth.Subject;
+import sun.security.provider.PolicyParser.PrincipalEntry;
 
 /**
  * <p> This <code>SubjectCodeSource</code> class contains
@@ -57,7 +58,7 @@
         });
 
     private Subject subject;
-    private LinkedList<PolicyParser.PrincipalEntry> principals;
+    private LinkedList<PrincipalEntry> principals;
     private static final Class[] PARAMS = { String.class };
     private static final sun.security.util.Debug debug =
         sun.security.util.Debug.getInstance("auth", "\t[Auth Access]");
@@ -87,14 +88,14 @@
      *                  <code>SubjectCodeSource</code> <p>
      */
     SubjectCodeSource(Subject subject,
-        LinkedList<PolicyParser.PrincipalEntry> principals,
+        LinkedList<PrincipalEntry> principals,
         URL url, Certificate[] certs) {
 
         super(url, certs);
         this.subject = subject;
         this.principals = (principals == null ?
-                new LinkedList<PolicyParser.PrincipalEntry>() :
-                new LinkedList<PolicyParser.PrincipalEntry>(principals));
+                new LinkedList<PrincipalEntry>() :
+                new LinkedList<PrincipalEntry>(principals));
         sysClassLoader = java.security.AccessController.doPrivileged
         (new java.security.PrivilegedAction<ClassLoader>() {
             public ClassLoader run() {
@@ -114,7 +115,7 @@
      *          <code>SubjectCodeSource</code> as a <code>LinkedList</code>
      *          of <code>PolicyParser.PrincipalEntry</code> objects.
      */
-    LinkedList<PolicyParser.PrincipalEntry> getPrincipals() {
+    LinkedList<PrincipalEntry> getPrincipals() {
         return principals;
     }
 
@@ -167,7 +168,7 @@
      */
     public boolean implies(CodeSource codesource) {
 
-        LinkedList<PolicyParser.PrincipalEntry> subjectList = null;
+        LinkedList<PrincipalEntry> subjectList = null;
 
         if (codesource == null ||
             !(codesource instanceof SubjectCodeSource) ||
@@ -197,20 +198,19 @@
             return false;
         }
 
-        ListIterator<PolicyParser.PrincipalEntry> li =
-                this.principals.listIterator(0);
+        ListIterator<PrincipalEntry> li = this.principals.listIterator(0);
         while (li.hasNext()) {
-            PolicyParser.PrincipalEntry pppe = li.next();
+            PrincipalEntry pppe = li.next();
             try {
 
                 // handle PrincipalComparators
 
                 Class<?> principalComparator = Class.forName(
-                        pppe.principalClass, true, sysClassLoader);
+                        pppe.getPrincipalClass(), true, sysClassLoader);
                 Constructor<?> c = principalComparator.getConstructor(PARAMS);
                 PrincipalComparator pc =
                         (PrincipalComparator)c.newInstance
-                        (new Object[] { pppe.principalName });
+                        (new Object[] { pppe.getPrincipalName() });
 
                 if (!pc.implies(that.getSubject())) {
                     if (debug != null)
@@ -236,11 +236,10 @@
                     Iterator<Principal> i =
                                 that.getSubject().getPrincipals().iterator();
 
-                    subjectList = new LinkedList<PolicyParser.PrincipalEntry>();
+                    subjectList = new LinkedList<PrincipalEntry>();
                     while (i.hasNext()) {
                         Principal p = i.next();
-                        PolicyParser.PrincipalEntry spppe =
-                                new PolicyParser.PrincipalEntry
+                        PrincipalEntry spppe = new PrincipalEntry
                                 (p.getClass().getName(), p.getName());
                         subjectList.add(spppe);
                     }
@@ -281,23 +280,19 @@
      *          <i>pppe</i> argument.
      */
     private boolean subjectListImpliesPrincipalEntry(
-                LinkedList<PolicyParser.PrincipalEntry> subjectList,
-                PolicyParser.PrincipalEntry pppe) {
+                LinkedList<PrincipalEntry> subjectList, PrincipalEntry pppe) {
 
-        ListIterator<PolicyParser.PrincipalEntry> li =
-                                        subjectList.listIterator(0);
+        ListIterator<PrincipalEntry> li = subjectList.listIterator(0);
         while (li.hasNext()) {
-            PolicyParser.PrincipalEntry listPppe = li.next();
+            PrincipalEntry listPppe = li.next();
 
-            if (pppe.principalClass.equals
-                        (PolicyParser.PrincipalEntry.WILDCARD_CLASS) ||
-                pppe.principalClass.equals
-                        (listPppe.principalClass)) {
-
-                if (pppe.principalName.equals
-                        (PolicyParser.PrincipalEntry.WILDCARD_NAME) ||
-                    pppe.principalName.equals
-                        (listPppe.principalName))
+            if (pppe.getPrincipalClass().equals
+                        (PrincipalEntry.WILDCARD_CLASS) ||
+                pppe.getPrincipalClass().equals(listPppe.getPrincipalClass()))
+            {
+                if (pppe.getPrincipalName().equals
+                        (PrincipalEntry.WILDCARD_NAME) ||
+                    pppe.getPrincipalName().equals(listPppe.getPrincipalName()))
                     return true;
             }
         }
@@ -390,13 +385,12 @@
             }
         }
         if (principals != null) {
-            ListIterator<PolicyParser.PrincipalEntry> li =
-                                        principals.listIterator();
+            ListIterator<PrincipalEntry> li = principals.listIterator();
             while (li.hasNext()) {
-                PolicyParser.PrincipalEntry pppe = li.next();
+                PrincipalEntry pppe = li.next();
                 returnMe = returnMe + rb.getString("NEWLINE") +
-                        pppe.principalClass + " " +
-                        pppe.principalName;
+                        pppe.getPrincipalClass() + " " +
+                        pppe.getPrincipalName();
             }
         }
         return returnMe;
--- a/jdk/src/share/classes/com/sun/tools/hat/resources/hat.js	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/com/sun/tools/hat/resources/hat.js	Wed Jul 05 19:07:11 2017 +0200
@@ -151,7 +151,7 @@
         while (tmp != null) {
             res[res.length] = tmp;
             tmp = tmp.superclass;
-        } 
+        }
         return res;
     }
 
@@ -263,16 +263,19 @@
     
                     if (name == 'class') {
                         return wrapJavaValue(instance.clazz);
-                    } else if (name == 'toString') {
-                        return function() { 
-                            return instance.toString();
-                        }
                     } else if (name == 'wrapped-object') {
                         return instance;
                     } 
     
                     return undefined;
-            }
+            },
+            __call__: function(name) {
+                if (name == 'toString') {
+                    return instance.toString();
+                } else {
+                    return undefined;
+                }
+            } 
         }				
     }
 
@@ -297,7 +300,7 @@
                         return true;
                     }					
                 }
-                return theJavaClassProto[name] != undefined;
+                return false;
             },
             __get__ : function(name) {
                 for (var i in fields) {
@@ -305,7 +308,7 @@
                         return wrapJavaValue(fields[i].value);	
                     }					
                 }
-                return theJavaClassProto[name];
+                return undefined;
             }
         }
     		
@@ -322,7 +325,12 @@
         this.name = jclass.name; 
         this.fields = jclass.fields;
         this['wrapped-object'] = jclass;
-        this.__proto__ = this.statics;
+    }
+
+    for (var i in theJavaClassProto) {
+        if (typeof theJavaClassProto[i] == 'function') {
+           JavaClassWrapper.prototype[i] = theJavaClassProto[i];
+        }
     }
     
     // returns wrapper for Java object arrays
@@ -334,32 +342,35 @@
             __getIds__ : function() {
                 var res = new Array(elements.length);
                 for (var i = 0; i < elements.length; i++) {
-                    res[i] = i;
+                    res[i] = String(i);
                 }
                 return res;
             },
             __has__: function(name) {
-                return (typeof(name) == 'number' &&
-                        name >= 0 && name < elements.length)  ||
+                return (name >= 0 && name < elements.length)  ||
                         name == 'length' || name == 'class' ||
                         name == 'toString' || name == 'wrapped-object';
             },
             __get__ : function(name) {
-                if (typeof(name) == 'number' &&
-                    name >= 0 && name < elements.length) {
+                if (name >= 0 && name < elements.length) {
                     return wrapJavaValue(elements[name]);
                 } else if (name == 'length') {
                     return elements.length;
                 } else if (name == 'class') {
                     return wrapJavaValue(array.clazz);
-                } else if (name == 'toString') {
-                    return function() { return array.toString(); }          
                 } else if (name == 'wrapped-object') {
                     return array;
                 } else {
                     return undefined;
                 }				
-            }
+            },
+            __call__: function(name) {
+                if (name == 'toString') {
+                    return array.toString();
+                } else {
+                    return undefined;
+                }
+            } 
         }			
     }
     
@@ -373,26 +384,22 @@
             __getIds__ : function() {
                 var r = new Array(array.length);
                 for (var i = 0; i < array.length; i++) {
-                    r[i] = i;
+                    r[i] = String(i);
                 }
                 return r;
             },
             __has__: function(name) {
-                return (typeof(name) == 'number' &&
-                        name >= 0 && name < array.length) ||
+                return (name >= 0 && name < array.length) ||
                         name == 'length' || name == 'class' ||
                         name == 'toString' || name == 'wrapped-object';
             },
             __get__: function(name) {
-                if (typeof(name) == 'number' &&
-                    name >= 0 && name < array.length) {
+                if (name >= 0 && name < array.length) {
                     return elements[name];
                 }
     
                 if (name == 'length') {
                     return array.length;
-                } else if (name == 'toString') {
-                    return function() { return array.valueString(true); } 
                 } else if (name == 'wrapped-object') {
                     return array;
                 } else if (name == 'class') {
@@ -400,7 +407,14 @@
                 } else {
                     return undefined;
                 }
-            }
+            },
+            __call__: function(name) {
+                if (name == 'toString') {
+                    return array.valueString(true);
+                } else {
+                    return undefined;
+                }
+            } 
         }
     }
     return javaObject(thing);
@@ -673,34 +687,33 @@
                     __getIds__ : function() {
                         var res = new Array(path.length);
                         for (var i = 0; i < path.length; i++) {
-                            res[i] = i;
+                            res[i] = String(i);
                         }
                         return res;
                     },
                     __has__ : function (name) {
-                        return (typeof(name) == 'number' &&
-                            name >= 0 && name < path.length) ||
+                        return (name >= 0 && name < path.length) ||
                             name == 'length' || name == 'toHtml' ||
                             name == 'toString';
                     },
                     __get__ : function(name) {
-                        if (typeof(name) == 'number' &&
-                            name >= 0 && name < path.length) {
+                        if (name >= 0 && name < path.length) {
                             return path[name];
                         } else if (name == 'length') {
                             return path.length;
-                        } else if (name == 'toHtml') {
-                            return function() { 
-                               return computeDescription(true);
-                            }
-                        } else if (name == 'toString') {
-                            return function() {
-                               return computeDescription(false);
-                            }
                         } else {
                             return undefined;
                         }
                     },
+                    __call__: function(name) {
+                        if (name == 'toHtml') {
+                            return computeDescription(true);
+                        } else if (name == 'toString') {
+                            return computeDescription(false);
+                        } else {
+                            return undefined;
+                        }
+                    }
                 };
             }
 
@@ -1005,22 +1018,8 @@
             return "<a href='/object/" + id + "'>" +
                    name + "@" + id + "</a>";
         }
-    } else if ((typeof(obj) == 'object') || (obj instanceof JSAdapter)) {
-        if (obj instanceof java.lang.Object) {
-            // script wrapped Java object
-            obj = wrapIterator(obj);
-            // special case for enumeration
-            if (obj instanceof java.util.Enumeration) {
-                var res = "[ ";
-                while (obj.hasMoreElements()) {
-                    res += toHtml(obj.nextElement()) + ", ";
-                }
-                res += "]";
-                return res; 
-            } else {
-                return obj;
-            }
-        } else if (obj instanceof Array) {
+    } else if (obj instanceof Object) {
+        if (Array.isArray(obj)) {
             // script array
             var res = "[ ";
             for (var i in obj) {
@@ -1047,8 +1046,19 @@
             }
         }
     } else {
-        // JavaScript primitive value
-        return obj;
+        // a Java object
+        obj = wrapIterator(obj);
+        // special case for enumeration
+        if (obj instanceof java.util.Enumeration) {
+            var res = "[ ";
+            while (obj.hasMoreElements()) {
+                res += toHtml(obj.nextElement()) + ", ";
+            }
+            res += "]";
+            return res; 
+        } else {
+            return obj;
+        }
     }
 }
 
--- a/jdk/src/share/classes/com/sun/tools/hat/resources/oqlhelp.html	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/com/sun/tools/hat/resources/oqlhelp.html	Wed Jul 05 19:07:11 2017 +0200
@@ -79,7 +79,7 @@
 <li>select all Strings of length 100 or more
 <pre>
 <code>
-    select s from java.lang.String s where s.count >= 100
+    select s from java.lang.String s where s.value.length >= 100
 </code>
 </pre>
 <li>select all int arrays of length 256 or more
@@ -92,7 +92,7 @@
 <pre>
 <code>
     select s.value.toString() from java.lang.String s 
-    where /java/(s.value.toString())
+    where /java/.test(s.value.toString())
 </code>
 </pre>
 <li>show path value of all File objects
@@ -219,7 +219,6 @@
 <pre>
 <code>
     select heap.findClass("java.lang.System").statics.props
-    select heap.findClass("java.lang.System").props
 </code>
 </pre>
 <li>get number of fields of java.lang.String class 
@@ -237,7 +236,7 @@
 <li>select all classes that have name pattern java.net.*
 <pre>
 <code>
-    select <a href="#filter">filter</a>(heap.classes(), "/java.net./(it.name)")
+    select <a href="#filter">filter</a>(heap.classes(), "/java.net./.test(it.name)")
 </code>
 </pre>
 </ul>
@@ -536,7 +535,7 @@
 Example: print number of classes that have specific name pattern
 <pre>
 <code>
-    select count(<a href="#classes">heap.classes()</a>, "/java.io./(it.name)")
+    select count(<a href="#classes">heap.classes()</a>, "/java.io./.test(it.name)")
 </code>
 </pre>
 
@@ -559,14 +558,14 @@
 <li>show all classes that have java.io.* name pattern
 <pre>
 <code>
-    select filter(<a href="#classes">heap.classes</a>(), "/java.io./(it.name)")
+    select filter(<a href="#classes">heap.classes</a>(), "/java.io./.test(it.name)")
 </code>
 </pre>
 <li> show all referrers of URL object where the referrer is not from
 java.net package
 <pre>
 <code>
-    select filter(<a href="#referrers">referrers</a>(u), "! /java.net./(<a href="#classof">classof</a>(it).name)")
+    select filter(<a href="#referrers">referrers</a>(u), "! /java.net./.test(<a href="#classof">classof</a>(it).name)")
     from java.net.URL u
 </code>
 </pre>
@@ -619,13 +618,13 @@
 <li>find the maximum length of any String instance
 <pre>
 <code>
-    select max(map(heap.objects('java.lang.String', false), 'it.count'))
+    select max(map(heap.objects('java.lang.String', false), 'it.value.length'))
 </code>
 </pre>
 <li>find string instance that has the maximum length
 <pre>
 <code>
-    select max(heap.objects('java.lang.String'), 'lhs.count > rhs.count')
+    select max(heap.objects('java.lang.String'), 'lhs.value.length > rhs.value.length')
 </code>
 </pre>
 </ul>
@@ -775,7 +774,7 @@
 
 <pre>
 <code>
-   select <a href="#map">map</a>(<a href="#filter">filter(<a href="#findClass">heap.findClass</a>('java.lang.System').props.table, 'it != null'), 
+   select <a href="#map">map</a>(<a href="#filter">filter(<a href="#findClass">heap.findClass</a>('java.lang.System').statics.props.table, 'it != null'), 
             function (it) {
                 var res = "";
                 while (it != null) {
--- a/jdk/src/share/classes/java/applet/AppletContext.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/applet/AppletContext.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -56,7 +56,7 @@
 
     /**
      * Returns an <code>Image</code> object that can then be painted on
-     * the screen. The <code>url</code> argument<code> </code>that is
+     * the screen. The <code>url</code> argument that is
      * passed as an argument must specify an absolute URL.
      * <p>
      * This method always returns immediately, whether or not the image
@@ -157,7 +157,7 @@
      * @param stream stream to be associated with the specified key. If this
      *               parameter is <code>null</code>, the specified key is removed
      *               in this applet context.
-     * @throws <code>IOException</code> if the stream size exceeds a certain
+     * @throws IOException if the stream size exceeds a certain
      *         size limit. Size limit is decided by the implementor of this
      *         interface.
      * @since 1.4
--- a/jdk/src/share/classes/java/awt/event/ContainerListener.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/event/ContainerListener.java	Wed Jul 05 19:07:11 2017 +0200
@@ -42,7 +42,7 @@
  * Container events are provided for notification purposes ONLY;
  * The AWT will automatically handle add and remove operations
  * internally so the program works properly regardless of
- * whether the program registers a <code>ComponentListener</code> or not.
+ * whether the program registers a {@code ContainerListener} or not.
  *
  * @see ContainerAdapter
  * @see ContainerEvent
--- a/jdk/src/share/classes/java/awt/image/BufferStrategy.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/BufferStrategy.java	Wed Jul 05 19:07:11 2017 +0200
@@ -55,7 +55,7 @@
  * Alternatively, the contents of the back buffer can be copied, or
  * <i>blitted</i> forward in a chain instead of moving the video pointer.
  * <p>
- * <pre>
+ * <pre>{@code
  * Double buffering:
  *
  *                    ***********         ***********
@@ -72,7 +72,7 @@
  *          *         * <------ *         * <----- *         *
  *          ***********         ***********        ***********
  *
- * </pre>
+ * }</pre>
  * <p>
  * Here is an example of how buffer strategies can be created and used:
  * <pre><code>
--- a/jdk/src/share/classes/java/awt/image/BufferedImage.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/BufferedImage.java	Wed Jul 05 19:07:11 2017 +0200
@@ -602,12 +602,12 @@
      *                  the raster has been premultiplied with alpha.
      * @param properties <code>Hashtable</code> of
      *                  <code>String</code>/<code>Object</code> pairs.
-     * @exception <code>RasterFormatException</code> if the number and
+     * @exception RasterFormatException if the number and
      * types of bands in the <code>SampleModel</code> of the
      * <code>Raster</code> do not match the number and types required by
      * the <code>ColorModel</code> to represent its color and alpha
      * components.
-     * @exception <code>IllegalArgumentException</code> if
+     * @exception IllegalArgumentException if
      *          <code>raster</code> is incompatible with <code>cm</code>
      * @see ColorModel
      * @see Raster
@@ -927,7 +927,7 @@
      * each color component in the returned data when
      * using this method.  With a specified coordinate (x,&nbsp;y) in the
      * image, the ARGB pixel can be accessed in this way:
-     * </p>
+     * <p>
      *
      * <pre>
      *    pixel   = rgbArray[offset + (y-startY)*scansize + (x-startX)]; </pre>
@@ -1131,7 +1131,7 @@
      * @return an {@link Object} that is the property referred to by the
      *          specified <code>name</code> or <code>null</code> if the
      *          properties of this image are not yet known.
-     * @throws <code>NullPointerException</code> if the property name is null.
+     * @throws NullPointerException if the property name is null.
      * @see ImageObserver
      * @see java.awt.Image#UndefinedProperty
      */
@@ -1144,7 +1144,7 @@
      * @param name the property name
      * @return an <code>Object</code> that is the property referred to by
      *          the specified <code>name</code>.
-     * @throws <code>NullPointerException</code> if the property name is null.
+     * @throws NullPointerException if the property name is null.
      */
     public Object getProperty(String name) {
         if (name == null) {
@@ -1196,7 +1196,7 @@
      * @param h the height of the specified rectangular region
      * @return a <code>BufferedImage</code> that is the subimage of this
      *          <code>BufferedImage</code>.
-     * @exception <code>RasterFormatException</code> if the specified
+     * @exception RasterFormatException if the specified
      * area is not contained within this <code>BufferedImage</code>.
      */
     public BufferedImage getSubimage (int x, int y, int w, int h) {
@@ -1388,7 +1388,7 @@
      * @param tileY the y index of the requested tile in the tile array
      * @return a <code>Raster</code> that is the tile defined by the
      *          arguments <code>tileX</code> and <code>tileY</code>.
-     * @exception <code>ArrayIndexOutOfBoundsException</code> if both
+     * @exception ArrayIndexOutOfBoundsException if both
      *          <code>tileX</code> and <code>tileY</code> are not
      *          equal to 0
      */
@@ -1558,7 +1558,7 @@
      * @return <code>true</code> if the tile specified by the specified
      *          indices is checked out for writing; <code>false</code>
      *          otherwise.
-     * @exception <code>ArrayIndexOutOfBoundsException</code> if both
+     * @exception ArrayIndexOutOfBoundsException if both
      *          <code>tileX</code> and <code>tileY</code> are not equal
      *          to 0
      */
--- a/jdk/src/share/classes/java/awt/image/ByteLookupTable.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/ByteLookupTable.java	Wed Jul 05 19:07:11 2017 +0200
@@ -171,7 +171,7 @@
      * @exception ArrayIndexOutOfBoundsException if <code>src</code> is
      *            longer than <code>dst</code> or if for any element
      *            <code>i</code> of <code>src</code>,
-     *            <code>(src[i]&0xff)-offset</code> is either less than
+     *            {@code (src[i]&0xff)-offset} is either less than
      *            zero or greater than or equal to the length of the
      *            lookup table for any band.
      */
--- a/jdk/src/share/classes/java/awt/image/ColorModel.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/ColorModel.java	Wed Jul 05 19:07:11 2017 +0200
@@ -692,12 +692,12 @@
      * <code>DataBuffer.TYPE_INT</code>.
      * @param inData an array of pixel values
      * @return the value of the green component of the specified pixel.
-     * @throws <code>ClassCastException</code> if <code>inData</code>
+     * @throws ClassCastException if <code>inData</code>
      *  is not a primitive array of type <code>transferType</code>
-     * @throws <code>ArrayIndexOutOfBoundsException</code> if
+     * @throws ArrayIndexOutOfBoundsException if
      *  <code>inData</code> is not large enough to hold a pixel value
      *  for this <code>ColorModel</code>
-     * @throws <code>UnsupportedOperationException</code> if this
+     * @throws UnsupportedOperationException if this
      *  <code>tranferType</code> is not supported by this
      *  <code>ColorModel</code>
      */
--- a/jdk/src/share/classes/java/awt/image/DirectColorModel.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/DirectColorModel.java	Wed Jul 05 19:07:11 2017 +0200
@@ -642,12 +642,12 @@
      * @param inData the specified pixel
      * @return the alpha component of the specified pixel, scaled from
      *         0 to 255.
-     * @exception <code>ClassCastException</code> if <code>inData</code>
+     * @exception ClassCastException if <code>inData</code>
      *  is not a primitive array of type <code>transferType</code>
-     * @exception <code>ArrayIndexOutOfBoundsException</code> if
+     * @exception ArrayIndexOutOfBoundsException if
      *  <code>inData</code> is not large enough to hold a pixel value
      *  for this <code>ColorModel</code>
-     * @exception <code>UnsupportedOperationException</code> if this
+     * @exception UnsupportedOperationException if this
      *  <code>tranferType</code> is not supported by this
      *  <code>ColorModel</code>
      */
@@ -1055,7 +1055,7 @@
      * begin retrieving the color and alpha components
      * @return an <code>int</code> pixel value in this
      * <code>ColorModel</code> corresponding to the specified components.
-     * @exception <code>ArrayIndexOutOfBoundsException</code> if
+     * @exception ArrayIndexOutOfBoundsException if
      *  the <code>components</code> array is not large enough to
      *  hold all of the color and alpha components starting at
      *  <code>offset</code>
@@ -1097,9 +1097,9 @@
      * and alpha components
      * @return an <code>Object</code> representing an array of color and
      * alpha components.
-     * @exception <code>ClassCastException</code> if <code>obj</code>
+     * @exception ClassCastException if <code>obj</code>
      *  is not a primitive array of type <code>transferType</code>
-     * @exception <code>ArrayIndexOutOfBoundsException</code> if
+     * @exception ArrayIndexOutOfBoundsException if
      *  <code>obj</code> is not large enough to hold a pixel value
      *  for this <code>ColorModel</code> or the <code>components</code>
      *  array is not large enough to hold all of the color and alpha
--- a/jdk/src/share/classes/java/awt/image/ImageProducer.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/ImageProducer.java	Wed Jul 05 19:07:11 2017 +0200
@@ -100,11 +100,11 @@
      * <code>ImageProducer</code> should respond by executing
      * the following minimum set of <code>ImageConsumer</code>
      * method calls:
-     * <pre>
+     * <pre>{@code
      *  ic.setHints(TOPDOWNLEFTRIGHT | < otherhints >);
      *  ic.setPixels(...);      // As many times as needed
      *  ic.imageComplete();
-     * </pre>
+     * }</pre>
      * @param ic the specified <code>ImageConsumer</code>
      * @see ImageConsumer#setHints
      */
--- a/jdk/src/share/classes/java/awt/image/IndexColorModel.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/IndexColorModel.java	Wed Jul 05 19:07:11 2017 +0200
@@ -98,6 +98,7 @@
  * Index values greater than or equal to the map size, but less than
  * 2<sup><em>n</em></sup>, are undefined and return 0 for all color and
  * alpha components.
+ * </a>
  * <p>
  * For those methods that use a primitive array pixel representation of
  * type <code>transferType</code>, the array length is always one.
--- a/jdk/src/share/classes/java/awt/image/MemoryImageSource.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/MemoryImageSource.java	Wed Jul 05 19:07:11 2017 +0200
@@ -37,7 +37,7 @@
  * uses an array to produce pixel values for an Image.  Here is an example
  * which calculates a 100x100 image representing a fade from black to blue
  * along the X axis and a fade from black to red along the Y axis:
- * <pre>
+ * <pre>{@code
  *
  *      int w = 100;
  *      int h = 100;
@@ -52,12 +52,12 @@
  *      }
  *      Image img = createImage(new MemoryImageSource(w, h, pix, 0, w));
  *
- * </pre>
+ * }</pre>
  * The MemoryImageSource is also capable of managing a memory image which
  * varies over time to allow animation or custom rendering.  Here is an
  * example showing how to set up the animation source and signal changes
  * in the data (adapted from the MemoryAnimationSourceDemo by Garth Dickie):
- * <pre>
+ * <pre>{@code
  *
  *      int pixels[];
  *      MemoryImageSource source;
@@ -96,7 +96,7 @@
  *          }
  *      }
  *
- * </pre>
+ * }</pre>
  *
  * @see ImageProducer
  *
--- a/jdk/src/share/classes/java/awt/image/MultiPixelPackedSampleModel.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/MultiPixelPackedSampleModel.java	Wed Jul 05 19:07:11 2017 +0200
@@ -52,14 +52,14 @@
  * <code>x,&nbsp;y</code> from <code>DataBuffer</code> <code>data</code>
  * and storing the pixel data in data elements of type
  * <code>dataType</code>:
- * <pre>
+ * <pre>{@code
  *      int dataElementSize = DataBuffer.getDataTypeSize(dataType);
  *      int bitnum = dataBitOffset + x*pixelBitStride;
  *      int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
  *      int shift = dataElementSize - (bitnum & (dataElementSize-1))
  *                  - pixelBitStride;
  *      int pixel = (element >> shift) & ((1 << pixelBitStride) - 1);
- * </pre>
+ * }</pre>
  */
 
 public class MultiPixelPackedSampleModel extends SampleModel
--- a/jdk/src/share/classes/java/awt/image/PixelGrabber.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/PixelGrabber.java	Wed Jul 05 19:07:11 2017 +0200
@@ -35,7 +35,7 @@
  * The PixelGrabber class implements an ImageConsumer which can be attached
  * to an Image or ImageProducer object to retrieve a subset of the pixels
  * in that image.  Here is an example:
- * <pre>
+ * <pre>{@code
  *
  * public void handlesinglepixel(int x, int y, int pixel) {
  *      int alpha = (pixel >> 24) & 0xff;
@@ -65,7 +65,7 @@
  *      }
  * }
  *
- * </pre>
+ * }</pre>
  *
  * @see ColorModel#getRGBdefault
  *
@@ -165,8 +165,8 @@
      * accumulated in the default RGB ColorModel.  If the forceRGB
      * parameter is true, then the pixels will be accumulated in the
      * default RGB ColorModel anyway.  A buffer is allocated by the
-     * PixelGrabber to hold the pixels in either case.  If (w < 0) or
-     * (h < 0), then they will default to the remaining width and
+     * PixelGrabber to hold the pixels in either case.  If {@code (w < 0)} or
+     * {@code (h < 0)}, then they will default to the remaining width and
      * height of the source data when that information is delivered.
      * @param img the image to retrieve the image data from
      * @param x the x coordinate of the upper left corner of the rectangle
@@ -233,10 +233,10 @@
      * behaves in the following ways, depending on the value of
      * <code>ms</code>:
      * <ul>
-     * <li> If <code>ms</code> == 0, waits until all pixels are delivered
-     * <li> If <code>ms</code> > 0, waits until all pixels are delivered
+     * <li> If {@code ms == 0}, waits until all pixels are delivered
+     * <li> If {@code ms > 0}, waits until all pixels are delivered
      * as timeout expires.
-     * <li> If <code>ms</code> < 0, returns <code>true</code> if all pixels
+     * <li> If {@code ms < 0}, returns <code>true</code> if all pixels
      * are grabbed, <code>false</code> otherwise and does not wait.
      * </ul>
      * @param ms the number of milliseconds to wait for the image pixels
--- a/jdk/src/share/classes/java/awt/image/RGBImageFilter.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/RGBImageFilter.java	Wed Jul 05 19:07:11 2017 +0200
@@ -39,7 +39,7 @@
  * The only method which needs to be defined to create a useable image
  * filter is the filterRGB method.  Here is an example of a definition
  * of a filter which swaps the red and blue components of an image:
- * <pre>
+ * <pre>{@code
  *
  *      class RedBlueSwapFilter extends RGBImageFilter {
  *          public RedBlueSwapFilter() {
@@ -56,7 +56,7 @@
  *          }
  *      }
  *
- * </pre>
+ * }</pre>
  *
  * @see FilteredImageSource
  * @see ImageFilter
--- a/jdk/src/share/classes/java/awt/image/ShortLookupTable.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/ShortLookupTable.java	Wed Jul 05 19:07:11 2017 +0200
@@ -114,7 +114,7 @@
      * @exception ArrayIndexOutOfBoundsException if <code>src</code> is
      *            longer than <code>dst</code> or if for any element
      *            <code>i</code> of <code>src</code>,
-     *            <code>(src[i]&0xffff)-offset</code> is either less than
+     *            {@code (src[i]&0xffff)-offset} is either less than
      *            zero or greater than or equal to the length of the
      *            lookup table for any band.
      */
@@ -165,7 +165,7 @@
      * @exception ArrayIndexOutOfBoundsException if <code>src</code> is
      *            longer than <code>dst</code> or if for any element
      *            <code>i</code> of <code>src</code>,
-     *            <code>(src[i]&0xffff)-offset</code> is either less than
+     *            {@code (src[i]&0xffff)-offset} is either less than
      *            zero or greater than or equal to the length of the
      *            lookup table for any band.
      */
--- a/jdk/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java	Wed Jul 05 19:07:11 2017 +0200
@@ -57,10 +57,10 @@
  * The following code illustrates extracting the bits of the sample
  * representing band <code>b</code> for pixel <code>x,y</code>
  * from DataBuffer <code>data</code>:
- * <pre>
+ * <pre>{@code
  *      int sample = data.getElem(y * scanlineStride + x);
  *      sample = (sample & bitMasks[b]) >>> bitOffsets[b];
- * </pre>
+ * }</pre>
  */
 
 public class SinglePixelPackedSampleModel extends SampleModel
--- a/jdk/src/share/classes/java/awt/image/WritableRaster.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/awt/image/WritableRaster.java	Wed Jul 05 19:07:11 2017 +0200
@@ -372,13 +372,13 @@
      * integral type and less than or equal to 32 bits in size, then calling
      * this method is equivalent to executing the following code for all
      * <code>x,y</code> addresses valid in both Rasters.
-     * <pre>
+     * <pre>{@code
      *       Raster srcRaster;
      *       WritableRaster dstRaster;
      *       for (int b = 0; b < srcRaster.getNumBands(); b++) {
      *           dstRaster.setSample(x, y, b, srcRaster.getSample(x, y, b));
      *       }
-     * </pre>
+     * }</pre>
      * Thus, when copying an integral type source to an integral type
      * destination, if the source sample size is greater than the destination
      * sample size for a particular band, the high order bits of the source
--- a/jdk/src/share/classes/java/beans/AppletInitializer.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/AppletInitializer.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2000, 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
@@ -68,7 +68,6 @@
      * the Applet with its Container during the subsequent invocation of its
      * addChildren() method.
      * </ol>
-     * </p>
      *
      * @param newAppletBean  The newly instantiated JavaBean
      * @param bCtxt          The BeanContext intended for this Applet, or
--- a/jdk/src/share/classes/java/beans/Beans.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/Beans.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -62,7 +62,7 @@
      * <p>
      * Instantiate a JavaBean.
      * </p>
-     *
+     * @return a JavaBean
      * @param     cls         the class-loader from which we should create
      *                        the bean.  If this is null, then the system
      *                        class-loader is used.
@@ -82,6 +82,7 @@
      * <p>
      * Instantiate a JavaBean.
      * </p>
+     * @return a JavaBean
      *
      * @param     cls         the class-loader from which we should create
      *                        the bean.  If this is null, then the system
@@ -137,6 +138,7 @@
      * the JDK appletviewer (for a reference browser environment) and the
      * BDK BeanBox (for a reference bean container).
      *
+     * @return a JavaBean
      * @param     cls         the class-loader from which we should create
      *                        the bean.  If this is null, then the system
      *                        class-loader is used.
@@ -361,6 +363,8 @@
      * This method is provided in Beans 1.0 as a hook to allow the
      * addition of more flexible bean behaviour in the future.
      *
+     * @return an object representing a specified type view of the
+     * source object
      * @param bean        Object from which we want to obtain a view.
      * @param targetType  The type of view we'd like to get.
      *
@@ -384,7 +388,6 @@
         return Introspector.isSubclass(bean.getClass(), targetType);
     }
 
-
     /**
      * Test if we are in design-mode.
      *
--- a/jdk/src/share/classes/java/beans/ConstructorProperties.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/ConstructorProperties.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -61,7 +61,7 @@
    the {@code getY()} method.  Since parameter names are not in
    general available at runtime, without the annotation there would be
    no way to know whether the parameters correspond to {@code getX()}
-   and {@code getY()} or the other way around.</p>
+   and {@code getY()} or the other way around.
 
    @since 1.6
 */
--- a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -382,6 +382,7 @@
      * a class such that no property value depends on the value of
      * a subsequent property.
      *
+     * @param type the type of the instances
      * @param oldInstance The instance to be copied.
      * @param newInstance The instance that is to be modified.
      * @param out The stream to which any initialization statements should be written.
--- a/jdk/src/share/classes/java/beans/EventHandler.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/EventHandler.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -515,6 +515,7 @@
      *</pre>
      *</blockquote>
      *
+     * @param <T> the type to create
      * @param listenerInterface the listener interface to create a proxy for
      * @param target the object that will perform the action
      * @param action the name of a (possibly qualified) property or method on
@@ -570,6 +571,7 @@
      *</pre>
      *</blockquote>
      *
+     * @param <T> the type to create
      * @param listenerInterface the listener interface to create a proxy for
      * @param target the object that will perform the action
      * @param action the name of a (possibly qualified) property or method on
@@ -659,6 +661,7 @@
      * </pre>
      *</blockquote>
      *
+     * @param <T> the type to create
      * @param listenerInterface the listener interface to create a proxy for
      * @param target the object that will perform the action
      * @param action the name of a (possibly qualified) property or method on
--- a/jdk/src/share/classes/java/beans/Expression.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/Expression.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -139,7 +139,7 @@
      * replaces this default value in the same way that any other value
      * would, ensuring that expressions are never evaluated more than once.
      * <p>
-     * See the <code>excecute</code> method for details on how
+     * See the <code>execute</code> method for details on how
      * methods are chosen using the dynamic types of the target
      * and arguments.
      *
@@ -147,6 +147,8 @@
      * @see #setValue
      *
      * @return The result of applying this method to these arguments.
+     * @throws Exception if the method with the specified methodName
+     * throws an exception
      */
     public Object getValue() throws Exception {
         if (value == unbound) {
--- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Wed Jul 05 19:07:11 2017 +0200
@@ -207,6 +207,8 @@
      * Sets the method that should be used to read an indexed property value.
      *
      * @param readMethod The new indexed read method.
+     * @throws IntrospectionException if an exception occurs during
+     * introspection.
      */
     public synchronized void setIndexedReadMethod(Method readMethod)
         throws IntrospectionException {
@@ -285,6 +287,8 @@
      * Sets the method that should be used to write an indexed property value.
      *
      * @param writeMethod The new indexed write method.
+     * @throws IntrospectionException if an exception occurs during
+     * introspection.
      */
     public synchronized void setIndexedWriteMethod(Method writeMethod)
         throws IntrospectionException {
--- a/jdk/src/share/classes/java/beans/Introspector.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/Introspector.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -93,8 +93,17 @@
 public class Introspector {
 
     // Flags that can be used to control getBeanInfo:
+    /**
+     * Flag to indicate to use of all beaninfo.
+     */
     public final static int USE_ALL_BEANINFO           = 1;
+    /**
+     * Flag to indicate to ignore immediate beaninfo.
+     */
     public final static int IGNORE_IMMEDIATE_BEANINFO  = 2;
+    /**
+     * Flag to indicate to ignore all beaninfo.
+     */
     public final static int IGNORE_ALL_BEANINFO        = 3;
 
     // Static Caches to speed up introspection.
@@ -202,7 +211,7 @@
      * If the BeanInfo class for a Java Bean has been previously Introspected
      * based on the same arguments, then the BeanInfo class is retrieved
      * from the BeanInfo cache.
-     *
+     * @return the BeanInfo for the bean
      * @param beanClass The bean class to be analyzed.
      * @param stopClass The baseclass at which to stop the analysis.  Any
      *    methods/properties/events in the stopClass or in its baseclasses
--- a/jdk/src/share/classes/java/beans/PersistenceDelegate.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/PersistenceDelegate.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -197,6 +197,7 @@
      * The default implementation, calls the <code>initialize</code>
      * method of the type's superclass.
      *
+     * @param type the type of the instances
      * @param oldInstance The instance to be copied.
      * @param newInstance The instance that is to be modified.
      * @param out The stream to which any initialization statements should be written.
--- a/jdk/src/share/classes/java/beans/PropertyChangeSupport.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/PropertyChangeSupport.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -156,7 +156,7 @@
      * <code>PropertyChangeListenerProxy</code>, perform the cast, and examine
      * the parameter.
      *
-     * <pre>
+     * <pre>{@code
      * PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
      * for (int i = 0; i < listeners.length; i++) {
      *   if (listeners[i] instanceof PropertyChangeListenerProxy) {
@@ -168,7 +168,7 @@
      *     }
      *   }
      * }
-     *</pre>
+     * }</pre>
      *
      * @see PropertyChangeListenerProxy
      * @return all of the <code>PropertyChangeListeners</code> added or an
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Wed Jul 05 19:07:11 2017 +0200
@@ -243,6 +243,7 @@
      * Sets the method that should be used to read the property value.
      *
      * @param readMethod The new read method.
+     * @throws IntrospectionException if the read method is invalid
      */
     public synchronized void setReadMethod(Method readMethod)
                                 throws IntrospectionException {
@@ -313,6 +314,7 @@
      * Sets the method that should be used to write the property value.
      *
      * @param writeMethod The new write method.
+     * @throws IntrospectionException if the write method is invalid
      */
     public synchronized void setWriteMethod(Method writeMethod)
                                 throws IntrospectionException {
--- a/jdk/src/share/classes/java/beans/Transient.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/Transient.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
  * A {@code true} value for the "transient" attribute
  * indicates to encoders derived from {@link Encoder}
  * that this feature should be ignored.
- * <p/>
+ * <p>
  * The {@code Transient} annotation may be be used
  * in any of the methods that are involved
  * in a {@link FeatureDescriptor} subclass
@@ -49,7 +49,7 @@
  * to put the annotation and it is this declaration
  * that takes precedence in the case of multiple annotations
  * being defined for the same feature.
- * <p/>
+ * <p>
  * To declare a feature non-transient in a class
  * whose superclass declares it transient,
  * use {@code @Transient(false)}.
@@ -64,5 +64,11 @@
 @Target({METHOD})
 @Retention(RUNTIME)
 public @interface Transient {
+    /**
+     * Returns whether or not the {@code Introspector} should
+     * construct artifacts for the annotated method.
+     * @return whether or not the {@code Introspector} should
+     * construct artifacts for the annotated method
+     */
     boolean value() default true;
 }
--- a/jdk/src/share/classes/java/beans/VetoableChangeSupport.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/VetoableChangeSupport.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -42,7 +42,7 @@
  * <p>
  * Here is an example of {@code VetoableChangeSupport} usage that follows
  * the rules and recommendations laid out in the JavaBeans&trade; specification:
- * <pre>
+ * <pre>{@code
  * public class MyBean {
  *     private final VetoableChangeSupport vcs = new VetoableChangeSupport(this);
  *
@@ -68,7 +68,7 @@
  *
  *     [...]
  * }
- * </pre>
+ * }</pre>
  * <p>
  * A {@code VetoableChangeSupport} instance is thread-safe.
  * <p>
@@ -156,7 +156,7 @@
      * <code>VetoableChangeListenerProxy</code>, perform the cast, and examine
      * the parameter.
      *
-     * <pre>
+     * <pre>{@code
      * VetoableChangeListener[] listeners = bean.getVetoableChangeListeners();
      * for (int i = 0; i < listeners.length; i++) {
      *        if (listeners[i] instanceof VetoableChangeListenerProxy) {
@@ -168,7 +168,7 @@
      *     }
      *   }
      * }
-     *</pre>
+     * }</pre>
      *
      * @see VetoableChangeListenerProxy
      * @return all of the <code>VetoableChangeListeners</code> added or an
--- a/jdk/src/share/classes/java/beans/beancontext/BeanContext.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/beancontext/BeanContext.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, 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
@@ -64,10 +64,12 @@
      * and is defined by the
      * <code>java.beans.Beans.instantiate()</code> method.
      *
+     * @return a javaBean named as a child of this
+     * <code>BeanContext</code>
      * @param beanName The name of the JavaBean to instantiate
      * as a child of this <code>BeanContext</code>
-     * @throws <code>IOException</code>
-     * @throws <code>ClassNotFoundException</code> if the class identified
+     * @throws IOException if an IO problem occurs
+     * @throws ClassNotFoundException if the class identified
      * by the beanName parameter is not found
      */
     Object instantiateChild(String beanName) throws IOException, ClassNotFoundException;
@@ -83,7 +85,7 @@
      * @return an <code>InputStream</code> for reading the resource,
      * or <code>null</code> if the resource could not
      * be found.
-     * @throws <code>IllegalArgumentException</code> if
+     * @throws IllegalArgumentException if
      * the resource is not valid
      */
     InputStream getResourceAsStream(String name, BeanContextChild bcc) throws IllegalArgumentException;
@@ -98,7 +100,7 @@
      * @param bcc the specified child
      * @return a <code>URL</code> for the named
      * resource for the specified child
-     * @throws <code>IllegalArgumentException</code>
+     * @throws IllegalArgumentException
      * if the resource is not valid
      */
     URL getResource(String name, BeanContextChild bcc) throws IllegalArgumentException;
@@ -109,7 +111,7 @@
       * this <code>BeanContext</code> whenever it adds
       * or removes a child <code>Component</code>(s).
       *
-      * @param bcml the <code>BeanContextMembershipListener</code> to be added
+      * @param bcml the BeanContextMembershipListener to be added
       */
     void addBeanContextMembershipListener(BeanContextMembershipListener bcml);
 
--- a/jdk/src/share/classes/java/beans/beancontext/BeanContextChild.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextChild.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, 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
@@ -82,7 +82,7 @@
      * </p>
      * @param bc The <code>BeanContext</code> with which
      * to associate this <code>BeanContextChild</code>.
-     * @throws <code>PropertyVetoException</code> if the
+     * @throws PropertyVetoException if the
      * addition of the specified <code>BeanContext</code> is refused.
      */
     void setBeanContext(BeanContext bc) throws PropertyVetoException;
--- a/jdk/src/share/classes/java/beans/beancontext/BeanContextChildSupport.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextChildSupport.java	Wed Jul 05 19:07:11 2017 +0200
@@ -78,6 +78,7 @@
      * construct a BeanContextChildSupport where the JavaBean component
      * itself implements BeanContextChild, and encapsulates this, delegating
      * that interface to this implementation
+     * @param bcc the underlying bean context child
      */
 
     public BeanContextChildSupport(BeanContextChild bcc) {
@@ -94,7 +95,7 @@
      * this <code>BeanContextChildSupport</code>.
      * @param bc the new value to be assigned to the <code>BeanContext</code>
      * property
-     * @throws <code>PropertyVetoException</code> if the change is rejected
+     * @throws PropertyVetoException if the change is rejected
      */
     public synchronized void setBeanContext(BeanContext bc) throws PropertyVetoException {
         if (bc == beanContext) return;
@@ -361,6 +362,9 @@
     */
     protected VetoableChangeSupport vcSupport;
 
+    /**
+     * The bean context.
+     */
     protected transient BeanContext           beanContext;
 
    /**
--- a/jdk/src/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, 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
@@ -103,6 +103,7 @@
      * Is the child specified affected by the event?
      * @return <code>true</code> if affected, <code>false</code>
      * if not
+     * @param child the object to check for being affected
      */
     public boolean contains(Object child) {
         return children.contains(child);
--- a/jdk/src/share/classes/java/beans/beancontext/BeanContextServices.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextServices.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2004, 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
@@ -60,6 +60,7 @@
      * @param serviceClass     the service to add
      * @param serviceProvider  the <code>BeanContextServiceProvider</code>
      * associated with the service
+     * @return true if the service was successful added, false otherwise
      */
     boolean addService(Class serviceClass, BeanContextServiceProvider serviceProvider);
 
@@ -108,7 +109,7 @@
      * @param bcsrl the
      * <code>BeanContextServiceRevokedListener</code> to notify
      * if the service should later become revoked
-     * @throws TooManyListenersException
+     * @throws TooManyListenersException if there are too many listeners
      * @return a reference to this context's named
      * Service as requested or <code>null</code>
      */
--- a/jdk/src/share/classes/java/beans/beancontext/BeanContextServicesSupport.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextServicesSupport.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2009, 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
@@ -603,12 +603,16 @@
                 serviceProvider = bcsp;
             }
 
+            /**
+             * Returns the service provider.
+             * @return the service provider
+             */
             protected BeanContextServiceProvider getServiceProvider() {
                 return serviceProvider;
             }
 
-            /*
-             * fields
+            /**
+             * The service provider.
              */
 
             protected BeanContextServiceProvider serviceProvider;
@@ -618,6 +622,9 @@
          * subclasses can override this method to create new subclasses of
          * BCSSServiceProvider without having to overrride addService() in
          * order to instantiate.
+         * @param sc the class
+         * @param bcsp the service provider
+         * @return a service provider without overriding addService()
          */
 
         protected BCSSServiceProvider createBCSSServiceProvider(Class sc, BeanContextServiceProvider bcsp) {
@@ -629,7 +636,7 @@
     /**
      * add a BeanContextServicesListener
      *
-     * @throws NullPointerException
+     * @throws NullPointerException if the argument is null
      */
 
     public void addBeanContextServicesListener(BeanContextServicesListener bcsl) {
@@ -660,6 +667,8 @@
 
     /**
      * add a service
+     * @param serviceClass the service class
+     * @param bcsp the service provider
      */
 
     public boolean addService(Class serviceClass, BeanContextServiceProvider bcsp) {
@@ -668,6 +677,10 @@
 
     /**
      * add a service
+     * @param serviceClass the service class
+     * @param bcsp the service provider
+     * @param fireEvent whether or not an event should be fired
+     * @return true if the service was successfully added
      */
 
     protected boolean addService(Class serviceClass, BeanContextServiceProvider bcsp, boolean fireEvent) {
@@ -709,6 +722,9 @@
 
     /**
      * remove a service
+     * @param serviceClass the service class
+     * @param bcsp the service provider
+     * @param revokeCurrentServicesNow whether or not to revoke the service
      */
 
     public void revokeService(Class serviceClass, BeanContextServiceProvider bcsp, boolean revokeCurrentServicesNow) {
@@ -1067,6 +1083,7 @@
 
     /**
      * Fires a <tt>BeanContextServiceEvent</tt> notifying of a new service.
+     * @param serviceClass the service class
      */
     protected final void fireServiceAdded(Class serviceClass) {
         BeanContextServiceAvailableEvent bcssae = new BeanContextServiceAvailableEvent(getBeanContextServicesPeer(), serviceClass);
@@ -1109,6 +1126,8 @@
      * Fires a <tt>BeanContextServiceRevokedEvent</tt>
      * indicating that a particular service is
      * no longer available.
+     * @param serviceClass the service class
+     * @param revokeNow whether or not the event should be revoked now
      */
     protected final void fireServiceRevoked(Class serviceClass, boolean revokeNow) {
         Object[]                       copy;
--- a/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/beans/beancontext/BeanContextSupport.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2004, 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
@@ -62,7 +62,6 @@
 /**
  * This helper class provides a utility implementation of the
  * java.beans.beancontext.BeanContext interface.
- * </p>
  * <p>
  * Since this class directly implements the BeanContext interface, the class
  * can, and is intended to be used either by subclassing this implementation,
@@ -351,9 +350,8 @@
      * of Child without having to override add() or the other Collection
      * methods that add children to the set.
      * </p>
-     *
      * @param targetChild the child to create the Child on behalf of
-     * @param peer        the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy
+     * @param peer        the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy     * @return Subtype-specific subclass of Child without overriding collection methods
      */
 
     protected BCSChild createBCSChild(Object targetChild, Object peer) {
@@ -492,6 +490,7 @@
      * @param callChildSetBC used to indicate that
      * the child should be notified that it is no
      * longer nested in this <tt>BeanContext</tt>.
+     * @return whether or not was present before being removed
      */
     protected boolean remove(Object targetChild, boolean callChildSetBC) {
 
@@ -580,7 +579,8 @@
     /**
      * add Collection to set of Children (Unsupported)
      * implementations must synchronized on the hierarchy lock and "children" protected field
-     * @throws UnsupportedOperationException
+     * @throws UnsupportedOperationException thrown unconditionally by this implementation
+     * @return this implementation unconditionally throws {@code UnsupportedOperationException}
      */
     public boolean addAll(Collection c) {
         throw new UnsupportedOperationException();
@@ -589,7 +589,9 @@
     /**
      * remove all specified children (Unsupported)
      * implementations must synchronized on the hierarchy lock and "children" protected field
-     * @throws UnsupportedOperationException
+     * @throws UnsupportedOperationException thrown unconditionally by this implementation
+     * @return this implementation unconditionally throws {@code UnsupportedOperationException}
+
      */
     public boolean removeAll(Collection c) {
         throw new UnsupportedOperationException();
@@ -599,7 +601,8 @@
     /**
      * retain only specified children (Unsupported)
      * implementations must synchronized on the hierarchy lock and "children" protected field
-     * @throws UnsupportedOperationException
+     * @throws UnsupportedOperationException thrown unconditionally by this implementation
+     * @return this implementation unconditionally throws {@code UnsupportedOperationException}
      */
     public boolean retainAll(Collection c) {
         throw new UnsupportedOperationException();
@@ -608,7 +611,7 @@
     /**
      * clear the children (Unsupported)
      * implementations must synchronized on the hierarchy lock and "children" protected field
-     * @throws UnsupportedOperationException
+     * @throws UnsupportedOperationException thrown unconditionally by this implementation
      */
     public void clear() {
         throw new UnsupportedOperationException();
@@ -618,7 +621,7 @@
      * Adds a BeanContextMembershipListener
      *
      * @param  bcml the BeanContextMembershipListener to add
-     * @throws NullPointerException
+     * @throws NullPointerException if the argument is null
      */
 
     public void addBeanContextMembershipListener(BeanContextMembershipListener bcml) {
@@ -636,7 +639,7 @@
      * Removes a BeanContextMembershipListener
      *
      * @param  bcml the BeanContextMembershipListener to remove
-     * @throws NullPointerException
+     * @throws NullPointerException if the argument is null
      */
 
     public void removeBeanContextMembershipListener(BeanContextMembershipListener bcml) {
@@ -655,7 +658,7 @@
      * @param bcc  the child object making the request.
      *
      * @return  the requested resource as an InputStream
-     * @throws  NullPointerException
+     * @throws  NullPointerException if the argument is null
      */
 
     public InputStream getResourceAsStream(String name, BeanContextChild bcc) {
@@ -849,6 +852,8 @@
      *
      * This method should not however be used by subclasses to replace their
      * own implementation (if any) of writeObject().
+     * @param oos the {@code ObjectOutputStream} to use during serialization
+     * @throws IOException if serialization failed
      */
 
     protected void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException {
@@ -864,6 +869,9 @@
      *
      * This method should not however be used by subclasses to replace their
      * own implementation (if any) of readObject().
+     * @param ois the {@code ObjectInputStream} to use during deserialization
+     * @throws IOException if deserialization failed
+     * @throws ClassNotFoundException if needed classes are not found
      */
 
     protected void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException {
@@ -914,6 +922,8 @@
      * used by readObject to deserialize a collection.
      * @param ois the ObjectInputStream to use
      * @param coll the Collection
+     * @throws IOException if deserialization failed
+     * @throws ClassNotFoundException if needed classes are not found
      */
     protected final void deserialize(ObjectInputStream ois, Collection coll) throws IOException, ClassNotFoundException {
         int count = 0;
@@ -1005,6 +1015,9 @@
      * When an instance of this class is used as a delegate for the
      * implementation of the BeanContext protocols (and its subprotocols)
      * there exists a 'chicken and egg' problem during deserialization
+     * @param ois the ObjectInputStream to use
+     * @throws IOException if deserialization failed
+     * @throws ClassNotFoundException if needed classes are not found
      */
 
     public final void readChildren(ObjectInputStream ois) throws IOException, ClassNotFoundException {
@@ -1122,6 +1135,7 @@
      * immediately prior to their being added to the BeanContext.
      * </p>
      *
+     * @param targetChild the child to create the Child on behalf of
      * @return true iff the child may be added to this BeanContext, otherwise false.
      */
 
@@ -1136,6 +1150,7 @@
      * immediately prior to their being removed from the BeanContext.
      * </p>
      *
+     * @param targetChild the child to create the Child on behalf of
      * @return true iff the child may be removed from this BeanContext, otherwise false.
      */
 
@@ -1147,6 +1162,8 @@
      * subclasses may override this method to simply extend add() semantics
      * after the child has been added and before the event notification has
      * occurred. The method is called with the child synchronized.
+     * @param child the child
+     * @param bcsc the BCSChild
      */
 
     protected void childJustAddedHook(Object child, BCSChild bcsc) {
@@ -1156,6 +1173,8 @@
      * subclasses may override this method to simply extend remove() semantics
      * after the child has been removed and before the event notification has
      * occurred. The method is called with the child synchronized.
+     * @param child the child
+     * @param bcsc the BCSChild
      */
 
     protected void childJustRemovedHook(Object child, BCSChild bcsc) {
@@ -1254,6 +1273,7 @@
 
     /**
      * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
+     * @param bcme the event to fire
      */
 
     protected final void fireChildrenAdded(BeanContextMembershipEvent bcme) {
@@ -1267,6 +1287,7 @@
 
     /**
      * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
+     * @param bcme the event to fire
      */
 
     protected final void fireChildrenRemoved(BeanContextMembershipEvent bcme) {
--- a/jdk/src/share/classes/java/net/SocketAddress.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/net/SocketAddress.java	Wed Jul 05 19:07:11 2017 +0200
@@ -39,4 +39,7 @@
  * @since 1.4
  */
 public abstract class SocketAddress implements java.io.Serializable {
+
+    static final long serialVersionUID = 5215720748342549866L;
+
 }
--- a/jdk/src/share/classes/java/nio/file/Files.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/nio/file/Files.java	Wed Jul 05 19:07:11 2017 +0200
@@ -25,10 +25,10 @@
 
 package java.nio.file;
 
-import java.nio.ByteBuffer;
 import java.nio.file.attribute.*;
 import java.nio.file.spi.FileSystemProvider;
 import java.nio.file.spi.FileTypeDetector;
+import java.nio.channels.Channels;
 import java.nio.channels.FileChannel;
 import java.nio.channels.SeekableByteChannel;
 import java.io.Closeable;
@@ -2965,7 +2965,63 @@
     }
 
     /**
-     * Read all the bytes from a file. The method ensures that the file is
+     * The maximum size of array to allocate.
+     * Some VMs reserve some header words in an array.
+     * Attempts to allocate larger arrays may result in
+     * OutOfMemoryError: Requested array size exceeds VM limit
+     */
+    private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
+
+    /**
+     * Reads all the bytes from an input stream. Uses {@code initialSize} as a hint
+     * about how many bytes the stream will have.
+     *
+     * @param   source
+     *          the input stream to read from
+     * @param   initialSize
+     *          the initial size of the byte array to allocate
+     *
+     * @return  a byte array containing the bytes read from the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs reading from the stream
+     * @throws  OutOfMemoryError
+     *          if an array of the required size cannot be allocated
+     */
+    private static byte[] read(InputStream source, int initialSize)
+            throws IOException
+    {
+        int capacity = initialSize;
+        byte[] buf = new byte[capacity];
+        int nread = 0;
+        int n;
+        for (;;) {
+            // read to EOF which may read more or less than initialSize (eg: file
+            // is truncated while we are reading)
+            while ((n = source.read(buf, nread, capacity - nread)) > 0)
+                nread += n;
+
+            // if last call to source.read() returned -1, we are done
+            // otherwise, try to read one more byte; if that failed we're done too
+            if (n < 0 || (n = source.read()) < 0)
+                break;
+
+            // one more byte was read; need to allocate a larger buffer
+            if (capacity <= MAX_BUFFER_SIZE - capacity) {
+                capacity = Math.max(capacity << 1, BUFFER_SIZE);
+            } else {
+                if (capacity == MAX_BUFFER_SIZE)
+                    throw new OutOfMemoryError("Required array size too large");
+                capacity = MAX_BUFFER_SIZE;
+            }
+            buf = Arrays.copyOf(buf, capacity);
+            buf[nread++] = (byte)n;
+        }
+        return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
+    }
+
+    /**
+     * Reads all the bytes from a file. The method ensures that the file is
      * closed when all bytes have been read or an I/O error, or other runtime
      * exception, is thrown.
      *
@@ -2989,22 +3045,13 @@
      *          method is invoked to check read access to the file.
      */
     public static byte[] readAllBytes(Path path) throws IOException {
-        try (FileChannel fc = FileChannel.open(path)) {
+        try (FileChannel fc = FileChannel.open(path);
+             InputStream is = Channels.newInputStream(fc)) {
             long size = fc.size();
-            if (size > (long)Integer.MAX_VALUE)
+            if (size > (long)MAX_BUFFER_SIZE)
                 throw new OutOfMemoryError("Required array size too large");
 
-            byte[] arr = new byte[(int)size];
-            ByteBuffer bb = ByteBuffer.wrap(arr);
-            while (bb.hasRemaining()) {
-                if (fc.read(bb) < 0) {
-                    // truncated
-                    break;
-                }
-            }
-
-            int nread = bb.position();
-            return (nread == size) ? arr : Arrays.copyOf(arr, nread);
+            return read(is, (int)size);
         }
     }
 
--- a/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -33,15 +33,47 @@
  * in order to obtain client and server sockets for RMI calls.  An
  * application may use the <code>setSocketFactory</code> method to
  * request that the RMI runtime use its socket factory instance
- * instead of the default implementation.<p>
+ * instead of the default implementation.
  *
- * The default socket factory implementation used goes through a
+ * <p>The default socket factory implementation performs a
  * three-tiered approach to creating client sockets. First, a direct
  * socket connection to the remote VM is attempted.  If that fails
  * (due to a firewall), the runtime uses HTTP with the explicit port
  * number of the server.  If the firewall does not allow this type of
  * communication, then HTTP to a cgi-bin script on the server is used
- * to POST the RMI call.<p>
+ * to POST the RMI call.
+ *
+ * <p>The default socket factory implementation creates server sockets that
+ * are bound to the wildcard address, which accepts requests from all network
+ * interfaces.
+ *
+ * @implNote
+ * <p>You can use the {@code RMISocketFactory} class to create a server socket that
+ * is bound to a specific address, restricting the origin of requests. For example,
+ * the following code implements a socket factory that binds server sockets to the
+ * loopback address. This restricts RMI to processing requests only from the local host.
+ *
+ * <pre>{@code
+ *     class LoopbackSocketFactory extends RMISocketFactory {
+ *         public ServerSocket createServerSocket(int port) throws IOException {
+ *             return new ServerSocket(port, 5, InetAddress.getLoopbackAddress());
+ *         }
+ *
+ *         public Socket createSocket(String host, int port) throws IOException {
+ *             // just call the default client socket factory
+ *             return RMISocketFactory.getDefaultSocketFactory()
+ *                                    .createSocket(host, port);
+ *         }
+ *     }
+ *
+ *     // ...
+ *
+ *     RMISocketFactory.setSocketFactory(new LoopbackSocketFactory());
+ * }</pre>
+ *
+ * Set the {@code java.rmi.server.hostname} system property
+ * to a host name (typically {@code localhost}) that resolves to the loopback
+ * interface to ensure that the generated stubs use the right network interface.
  *
  * @author  Ann Wollrath
  * @author  Peter Jones
--- a/jdk/src/share/classes/java/rmi/server/UnicastRemoteObject.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/rmi/server/UnicastRemoteObject.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -100,6 +100,26 @@
  * </ul>
  * </ul>
  *
+ * <p>If an object is exported with the
+ * {@link #exportObject(Remote) exportObject(Remote)}
+ * or
+ * {@link #exportObject(Remote, int) exportObject(Remote, port)}
+ * methods, or if a subclass constructor invokes one of the
+ * {@link #UnicastRemoteObject()}
+ * or
+ * {@link #UnicastRemoteObject(int) UnicastRemoteObject(port)}
+ * constructors, the object is exported with a server socket created using the
+ * {@link RMISocketFactory}
+ * class.
+ *
+ * @implNote
+ * <p>By default, server sockets created by the {@link RMISocketFactory} class
+ * listen on all network interfaces. See the
+ * {@link RMISocketFactory} class and the section
+ * <a href="{@docRoot}/../platform/rmi/spec/rmi-server29.html">RMI Socket Factories</a>
+ * in the
+ * <a href="{@docRoot}/../platform/rmi/spec/rmiTOC.html">Java RMI Specification</a>.
+ *
  * @author  Ann Wollrath
  * @author  Peter Jones
  * @since   JDK1.1
--- a/jdk/src/share/classes/java/security/Security.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/security/Security.java	Wed Jul 05 19:07:11 2017 +0200
@@ -326,17 +326,13 @@
      *
      * <p>A provider cannot be added if it is already installed.
      *
-     * <p>First, if there is a security manager, its
-     * {@code checkSecurityAccess}
-     * method is called with the string
-     * {@code "insertProvider."+provider.getName()}
-     * to see if it's ok to add a new provider.
-     * If the default implementation of {@code checkSecurityAccess}
-     * is used (i.e., that method is not overriden), then this will result in
-     * a call to the security manager's {@code checkPermission} method
-     * with a
-     * {@code SecurityPermission("insertProvider."+provider.getName())}
-     * permission.
+     * <p>If there is a security manager, the
+     * {@link java.lang.SecurityManager#checkSecurityAccess} method is called
+     * with the {@code "insertProvider"} permission target name to see if
+     * it's ok to add a new provider. If this permission check is denied,
+     * {@code checkSecurityAccess} is called again with the
+     * {@code "insertProvider."+provider.getName()} permission target name. If
+     * both checks are denied, a {@code SecurityException} is thrown.
      *
      * @param provider the provider to be added.
      *
@@ -360,7 +356,7 @@
     public static synchronized int insertProviderAt(Provider provider,
             int position) {
         String providerName = provider.getName();
-        check("insertProvider." + providerName);
+        checkInsertProvider(providerName);
         ProviderList list = Providers.getFullProviderList();
         ProviderList newList = ProviderList.insertAt(list, provider, position - 1);
         if (list == newList) {
@@ -373,17 +369,13 @@
     /**
      * Adds a provider to the next position available.
      *
-     * <p>First, if there is a security manager, its
-     * {@code checkSecurityAccess}
-     * method is called with the string
-     * {@code "insertProvider."+provider.getName()}
-     * to see if it's ok to add a new provider.
-     * If the default implementation of {@code checkSecurityAccess}
-     * is used (i.e., that method is not overriden), then this will result in
-     * a call to the security manager's {@code checkPermission} method
-     * with a
-     * {@code SecurityPermission("insertProvider."+provider.getName())}
-     * permission.
+     * <p>If there is a security manager, the
+     * {@link java.lang.SecurityManager#checkSecurityAccess} method is called
+     * with the {@code "insertProvider"} permission target name to see if
+     * it's ok to add a new provider. If this permission check is denied,
+     * {@code checkSecurityAccess} is called again with the
+     * {@code "insertProvider."+provider.getName()} permission target name. If
+     * both checks are denied, a {@code SecurityException} is thrown.
      *
      * @param provider the provider to be added.
      *
@@ -863,6 +855,23 @@
         }
     }
 
+    private static void checkInsertProvider(String name) {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            try {
+                security.checkSecurityAccess("insertProvider");
+            } catch (SecurityException se1) {
+                try {
+                    security.checkSecurityAccess("insertProvider." + name);
+                } catch (SecurityException se2) {
+                    // throw first exception, but add second to suppressed
+                    se1.addSuppressed(se2);
+                    throw se1;
+                }
+            }
+        }
+    }
+
     /*
     * Returns all providers who satisfy the specified
     * criterion.
--- a/jdk/src/share/classes/java/security/SecurityPermission.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/security/SecurityPermission.java	Wed Jul 05 19:07:11 2017 +0200
@@ -130,14 +130,17 @@
  * </tr>
  *
  * <tr>
- *   <td>insertProvider.{provider name}</td>
- *   <td>Addition of a new provider, with the specified name</td>
+ *   <td>insertProvider</td>
+ *   <td>Addition of a new provider</td>
  *   <td>This would allow somebody to introduce a possibly
  * malicious provider (e.g., one that discloses the private keys passed
  * to it) as the highest-priority provider. This would be possible
  * because the Security object (which manages the installed providers)
  * currently does not check the integrity or authenticity of a provider
- * before attaching it.</td>
+ * before attaching it. The "insertProvider" permission subsumes the
+ * "insertProvider.{provider name}" permission (see the section below for
+ * more information).
+ * </td>
  * </tr>
  *
  * <tr>
@@ -186,9 +189,10 @@
  * </table>
  *
  * <P>
- * The following permissions are associated with classes that have been
- * deprecated: {@link Identity}, {@link IdentityScope}, {@link Signer}. Use of
- * them is discouraged. See the applicable classes for more information.
+ * The following permissions have been superseded by newer permissions or are
+ * associated with classes that have been deprecated: {@link Identity},
+ * {@link IdentityScope}, {@link Signer}. Use of them is discouraged. See the
+ * applicable classes for more information.
  * <P>
  *
  * <table border=1 cellpadding=5 summary="target name,what the permission allows, and associated risks">
@@ -199,6 +203,23 @@
  * </tr>
  *
  * <tr>
+ *   <td>insertProvider.{provider name}</td>
+ *   <td>Addition of a new provider, with the specified name</td>
+ *   <td>Use of this permission is discouraged from further use because it is
+ * possible to circumvent the name restrictions by overriding the
+ * {@link java.security.Provider#getName} method. Also, there is an equivalent
+ * level of risk associated with granting code permission to insert a provider
+ * with a specific name, or any name it chooses. Users should use the
+ * "insertProvider" permission instead.
+ * <p>This would allow somebody to introduce a possibly
+ * malicious provider (e.g., one that discloses the private keys passed
+ * to it) as the highest-priority provider. This would be possible
+ * because the Security object (which manages the installed providers)
+ * currently does not check the integrity or authenticity of a provider
+ * before attaching it.</td>
+ * </tr>
+ *
+ * <tr>
  *   <td>setSystemScope</td>
  *   <td>Setting of the system identity scope</td>
  *   <td>This would allow an attacker to configure the system identity scope with
@@ -306,7 +327,6 @@
      * @throws NullPointerException if {@code name} is {@code null}.
      * @throws IllegalArgumentException if {@code name} is empty.
      */
-
     public SecurityPermission(String name)
     {
         super(name);
@@ -323,7 +343,6 @@
      * @throws NullPointerException if {@code name} is {@code null}.
      * @throws IllegalArgumentException if {@code name} is empty.
      */
-
     public SecurityPermission(String name, String actions)
     {
         super(name, actions);
--- a/jdk/src/share/classes/java/util/ArrayPrefixHelpers.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/ArrayPrefixHelpers.java	Wed Jul 05 19:07:11 2017 +0200
@@ -128,6 +128,7 @@
             this.lo = lo; this.hi = hi;
         }
 
+        @SuppressWarnings("unchecked")
         public final void compute() {
             final BinaryOperator<T> fn;
             final T[] a;
@@ -692,6 +693,4 @@
             }
         }
     }
-
-
-}
\ No newline at end of file
+}
--- a/jdk/src/share/classes/java/util/Collections.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/Collections.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1143,6 +1143,7 @@
         public boolean removeIf(Predicate<? super E> filter) {
             throw new UnsupportedOperationException();
         }
+        @SuppressWarnings("unchecked")
         @Override
         public Spliterator<E> spliterator() {
             return (Spliterator<E>)c.spliterator();
@@ -1900,7 +1901,7 @@
 
             private static final long serialVersionUID = -2239321462712562324L;
 
-            EmptyNavigableMap()                       { super(new TreeMap()); }
+            EmptyNavigableMap()                       { super(new TreeMap<K,V>()); }
 
             @Override
             public NavigableSet<K> navigableKeySet()
@@ -1928,46 +1929,52 @@
         public K ceilingKey(K key)               { return nm.ceilingKey(key); }
         public K higherKey(K key)                 { return nm.higherKey(key); }
 
+        @SuppressWarnings("unchecked")
         public Entry<K, V> lowerEntry(K key) {
             Entry<K,V> lower = (Entry<K, V>) nm.lowerEntry(key);
             return (null != lower)
-                ? new UnmodifiableEntrySet.UnmodifiableEntry(lower)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(lower)
                 : null;
         }
 
+        @SuppressWarnings("unchecked")
         public Entry<K, V> floorEntry(K key) {
             Entry<K,V> floor = (Entry<K, V>) nm.floorEntry(key);
             return (null != floor)
-                ? new UnmodifiableEntrySet.UnmodifiableEntry(floor)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(floor)
                 : null;
         }
 
+        @SuppressWarnings("unchecked")
         public Entry<K, V> ceilingEntry(K key) {
             Entry<K,V> ceiling = (Entry<K, V>) nm.ceilingEntry(key);
             return (null != ceiling)
-                ? new UnmodifiableEntrySet.UnmodifiableEntry(ceiling)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(ceiling)
                 : null;
         }
 
 
+        @SuppressWarnings("unchecked")
         public Entry<K, V> higherEntry(K key) {
             Entry<K,V> higher = (Entry<K, V>) nm.higherEntry(key);
             return (null != higher)
-                ? new UnmodifiableEntrySet.UnmodifiableEntry(higher)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(higher)
                 : null;
         }
 
+        @SuppressWarnings("unchecked")
         public Entry<K, V> firstEntry() {
             Entry<K,V> first = (Entry<K, V>) nm.firstEntry();
             return (null != first)
-                ? new UnmodifiableEntrySet.UnmodifiableEntry(first)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(first)
                 : null;
         }
 
+        @SuppressWarnings("unchecked")
         public Entry<K, V> lastEntry() {
             Entry<K,V> last = (Entry<K, V>) nm.lastEntry();
             return (null != last)
-                ? new UnmodifiableEntrySet.UnmodifiableEntry(last)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(last)
                 : null;
         }
 
@@ -2360,7 +2367,7 @@
         }
         public NavigableSet<E> tailSet(E fromElement) {
             synchronized (mutex) {
-                return new SynchronizedNavigableSet(ns.tailSet(fromElement, true), mutex);
+                return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, true), mutex);
             }
         }
 
@@ -2925,7 +2932,7 @@
         public NavigableMap<K, V> descendingMap() {
             synchronized (mutex) {
                 return
-                    new SynchronizedNavigableMap(nm.descendingMap(), mutex);
+                    new SynchronizedNavigableMap<>(nm.descendingMap(), mutex);
             }
         }
 
@@ -2935,13 +2942,13 @@
 
         public NavigableSet<K> navigableKeySet() {
             synchronized (mutex) {
-                return new SynchronizedNavigableSet(nm.navigableKeySet(), mutex);
+                return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex);
             }
         }
 
         public NavigableSet<K> descendingKeySet() {
             synchronized (mutex) {
-                return new SynchronizedNavigableSet(nm.descendingKeySet(), mutex);
+                return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex);
             }
         }
 
@@ -2959,27 +2966,27 @@
         }
         public SortedMap<K,V> tailMap(K fromKey) {
             synchronized (mutex) {
-               return new SynchronizedNavigableMap<>(nm.tailMap(fromKey, true),mutex);
+        return new SynchronizedNavigableMap<>(nm.tailMap(fromKey, true),mutex);
             }
         }
 
         public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
             synchronized (mutex) {
-                return new SynchronizedNavigableMap(
+                return new SynchronizedNavigableMap<>(
                     nm.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex);
             }
         }
 
         public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
             synchronized (mutex) {
-                return new SynchronizedNavigableMap(
+                return new SynchronizedNavigableMap<>(
                         nm.headMap(toKey, inclusive), mutex);
             }
         }
 
         public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
             synchronized (mutex) {
-                return new SynchronizedNavigableMap(
+                return new SynchronizedNavigableMap<>(
                     nm.tailMap(fromKey, inclusive), mutex);
             }
         }
@@ -4081,7 +4088,7 @@
         public Entry<K, V> lowerEntry(K key) {
             Entry<K,V> lower = nm.lowerEntry(key);
             return (null != lower)
-                ? new CheckedMap.CheckedEntrySet.CheckedEntry(lower, valueType)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(lower, valueType)
                 : null;
         }
 
@@ -4090,7 +4097,7 @@
         public Entry<K, V> floorEntry(K key) {
             Entry<K,V> floor = nm.floorEntry(key);
             return (null != floor)
-                ? new CheckedMap.CheckedEntrySet.CheckedEntry(floor, valueType)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(floor, valueType)
                 : null;
         }
 
@@ -4099,7 +4106,7 @@
         public Entry<K, V> ceilingEntry(K key) {
             Entry<K,V> ceiling = nm.ceilingEntry(key);
             return (null != ceiling)
-                ? new CheckedMap.CheckedEntrySet.CheckedEntry(ceiling, valueType)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(ceiling, valueType)
                 : null;
         }
 
@@ -4108,7 +4115,7 @@
         public Entry<K, V> higherEntry(K key) {
             Entry<K,V> higher = nm.higherEntry(key);
             return (null != higher)
-                ? new CheckedMap.CheckedEntrySet.CheckedEntry(higher, valueType)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(higher, valueType)
                 : null;
         }
 
@@ -4117,14 +4124,14 @@
         public Entry<K, V> firstEntry() {
             Entry<K,V> first = nm.firstEntry();
             return (null != first)
-                ? new CheckedMap.CheckedEntrySet.CheckedEntry(first, valueType)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(first, valueType)
                 : null;
         }
 
         public Entry<K, V> lastEntry() {
             Entry<K,V> last = nm.lastEntry();
             return (null != last)
-                ? new CheckedMap.CheckedEntrySet.CheckedEntry(last, valueType)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(last, valueType)
                 : null;
         }
 
@@ -4132,14 +4139,14 @@
             Entry<K,V> entry = nm.pollFirstEntry();
             return (null == entry)
                 ? null
-                : new CheckedMap.CheckedEntrySet.CheckedEntry(entry, valueType);
+                : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType);
         }
 
         public Entry<K, V> pollLastEntry() {
             Entry<K,V> entry = nm.pollLastEntry();
             return (null == entry)
                 ? null
-                : new CheckedMap.CheckedEntrySet.CheckedEntry(entry, valueType);
+                : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType);
         }
 
         public NavigableMap<K, V> descendingMap() {
--- a/jdk/src/share/classes/java/util/Comparator.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/Comparator.java	Wed Jul 05 19:07:11 2017 +0200
@@ -352,6 +352,7 @@
      * @see Comparable
      * @since 1.8
      */
+    @SuppressWarnings("unchecked")
     public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
         return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
     }
@@ -374,7 +375,7 @@
      * @since 1.8
      */
     public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
-        return new Comparators.NullComparator(true, comparator);
+        return new Comparators.NullComparator<>(true, comparator);
     }
 
     /**
@@ -395,7 +396,7 @@
      * @since 1.8
      */
     public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
-        return new Comparators.NullComparator(false, comparator);
+        return new Comparators.NullComparator<>(false, comparator);
     }
 
     /**
--- a/jdk/src/share/classes/java/util/Comparators.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/Comparators.java	Wed Jul 05 19:07:11 2017 +0200
@@ -87,12 +87,12 @@
         @Override
         public Comparator<T> thenComparing(Comparator<? super T> other) {
             Objects.requireNonNull(other);
-            return new NullComparator(nullFirst, real == null ? other : real.thenComparing(other));
+            return new NullComparator<>(nullFirst, real == null ? other : real.thenComparing(other));
         }
 
         @Override
         public Comparator<T> reversed() {
-            return new NullComparator(!nullFirst, real == null ? null : real.reversed());
+            return new NullComparator<>(!nullFirst, real == null ? null : real.reversed());
         }
     }
 }
--- a/jdk/src/share/classes/java/util/Deque.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/Deque.java	Wed Jul 05 19:07:11 2017 +0200
@@ -38,7 +38,7 @@
 /**
  * A linear collection that supports element insertion and removal at
  * both ends.  The name <i>deque</i> is short for "double ended queue"
- * and is usually pronounced "deck".  Most <tt>Deque</tt>
+ * and is usually pronounced "deck".  Most {@code Deque}
  * implementations place no fixed limits on the number of elements
  * they may contain, but this interface supports capacity-restricted
  * deques as well as those with no fixed size limit.
@@ -47,10 +47,10 @@
  * ends of the deque.  Methods are provided to insert, remove, and
  * examine the element.  Each of these methods exists in two forms:
  * one throws an exception if the operation fails, the other returns a
- * special value (either <tt>null</tt> or <tt>false</tt>, depending on
+ * special value (either {@code null} or {@code false}, depending on
  * the operation).  The latter form of the insert operation is
  * designed specifically for use with capacity-restricted
- * <tt>Deque</tt> implementations; in most implementations, insert
+ * {@code Deque} implementations; in most implementations, insert
  * operations cannot fail.
  *
  * <p>The twelve methods described above are summarized in the
@@ -58,6 +58,7 @@
  *
  * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Summary of Deque methods</caption>
  *  <tr>
  *    <td></td>
  *    <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td>
@@ -72,38 +73,39 @@
  *  </tr>
  *  <tr>
  *    <td><b>Insert</b></td>
- *    <td>{@link #addFirst addFirst(e)}</td>
- *    <td>{@link #offerFirst offerFirst(e)}</td>
- *    <td>{@link #addLast addLast(e)}</td>
- *    <td>{@link #offerLast offerLast(e)}</td>
+ *    <td>{@link Deque#addFirst addFirst(e)}</td>
+ *    <td>{@link Deque#offerFirst offerFirst(e)}</td>
+ *    <td>{@link Deque#addLast addLast(e)}</td>
+ *    <td>{@link Deque#offerLast offerLast(e)}</td>
  *  </tr>
  *  <tr>
  *    <td><b>Remove</b></td>
- *    <td>{@link #removeFirst removeFirst()}</td>
- *    <td>{@link #pollFirst pollFirst()}</td>
- *    <td>{@link #removeLast removeLast()}</td>
- *    <td>{@link #pollLast pollLast()}</td>
+ *    <td>{@link Deque#removeFirst removeFirst()}</td>
+ *    <td>{@link Deque#pollFirst pollFirst()}</td>
+ *    <td>{@link Deque#removeLast removeLast()}</td>
+ *    <td>{@link Deque#pollLast pollLast()}</td>
  *  </tr>
  *  <tr>
  *    <td><b>Examine</b></td>
- *    <td>{@link #getFirst getFirst()}</td>
- *    <td>{@link #peekFirst peekFirst()}</td>
- *    <td>{@link #getLast getLast()}</td>
- *    <td>{@link #peekLast peekLast()}</td>
+ *    <td>{@link Deque#getFirst getFirst()}</td>
+ *    <td>{@link Deque#peekFirst peekFirst()}</td>
+ *    <td>{@link Deque#getLast getLast()}</td>
+ *    <td>{@link Deque#peekLast peekLast()}</td>
  *  </tr>
  * </table>
  *
  * <p>This interface extends the {@link Queue} interface.  When a deque is
  * used as a queue, FIFO (First-In-First-Out) behavior results.  Elements are
  * added at the end of the deque and removed from the beginning.  The methods
- * inherited from the <tt>Queue</tt> interface are precisely equivalent to
- * <tt>Deque</tt> methods as indicated in the following table:
+ * inherited from the {@code Queue} interface are precisely equivalent to
+ * {@code Deque} methods as indicated in the following table:
  *
  * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Comparison of Queue and Deque methods</caption>
  *  <tr>
- *    <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td>
- *    <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
+ *    <td ALIGN=CENTER> <b>{@code Queue} Method</b></td>
+ *    <td ALIGN=CENTER> <b>Equivalent {@code Deque} Method</b></td>
  *  </tr>
  *  <tr>
  *    <td>{@link java.util.Queue#add add(e)}</td>
@@ -135,13 +137,14 @@
  * interface should be used in preference to the legacy {@link Stack} class.
  * When a deque is used as a stack, elements are pushed and popped from the
  * beginning of the deque.  Stack methods are precisely equivalent to
- * <tt>Deque</tt> methods as indicated in the table below:
+ * {@code Deque} methods as indicated in the table below:
  *
  * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Comparison of Stack and Deque methods</caption>
  *  <tr>
  *    <td ALIGN=CENTER> <b>Stack Method</b></td>
- *    <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
+ *    <td ALIGN=CENTER> <b>Equivalent {@code Deque} Method</b></td>
  *  </tr>
  *  <tr>
  *    <td>{@link #push push(e)}</td>
@@ -168,18 +171,18 @@
  * <p>Unlike the {@link List} interface, this interface does not
  * provide support for indexed access to elements.
  *
- * <p>While <tt>Deque</tt> implementations are not strictly required
+ * <p>While {@code Deque} implementations are not strictly required
  * to prohibit the insertion of null elements, they are strongly
- * encouraged to do so.  Users of any <tt>Deque</tt> implementations
+ * encouraged to do so.  Users of any {@code Deque} implementations
  * that do allow null elements are strongly encouraged <i>not</i> to
  * take advantage of the ability to insert nulls.  This is so because
- * <tt>null</tt> is used as a special return value by various methods
+ * {@code null} is used as a special return value by various methods
  * to indicated that the deque is empty.
  *
- * <p><tt>Deque</tt> implementations generally do not define
- * element-based versions of the <tt>equals</tt> and <tt>hashCode</tt>
+ * <p>{@code Deque} implementations generally do not define
+ * element-based versions of the {@code equals} and {@code hashCode}
  * methods, but instead inherit the identity-based versions from class
- * <tt>Object</tt>.
+ * {@code Object}.
  *
  * <p>This interface is a member of the <a
  * href="{@docRoot}/../technotes/guides/collections/index.html"> Java Collections
@@ -190,13 +193,13 @@
  * @since  1.6
  * @param <E> the type of elements held in this collection
  */
-
 public interface Deque<E> extends Queue<E> {
     /**
      * Inserts the specified element at the front of this deque if it is
-     * possible to do so immediately without violating capacity restrictions.
-     * When using a capacity-restricted deque, it is generally preferable to
-     * use method {@link #offerFirst}.
+     * possible to do so immediately without violating capacity restrictions,
+     * throwing an {@code IllegalStateException} if no space is currently
+     * available.  When using a capacity-restricted deque, it is generally
+     * preferable to use method {@link #offerFirst}.
      *
      * @param e the element to add
      * @throws IllegalStateException if the element cannot be added at this
@@ -212,9 +215,10 @@
 
     /**
      * Inserts the specified element at the end of this deque if it is
-     * possible to do so immediately without violating capacity restrictions.
-     * When using a capacity-restricted deque, it is generally preferable to
-     * use method {@link #offerLast}.
+     * possible to do so immediately without violating capacity restrictions,
+     * throwing an {@code IllegalStateException} if no space is currently
+     * available.  When using a capacity-restricted deque, it is generally
+     * preferable to use method {@link #offerLast}.
      *
      * <p>This method is equivalent to {@link #add}.
      *
@@ -237,8 +241,8 @@
      * 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 deque, else
-     *         <tt>false</tt>
+     * @return {@code true} if the element was added to this deque, else
+     *         {@code false}
      * @throws ClassCastException if the class of the specified element
      *         prevents it from being added to this deque
      * @throws NullPointerException if the specified element is null and this
@@ -255,8 +259,8 @@
      * 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 deque, else
-     *         <tt>false</tt>
+     * @return {@code true} if the element was added to this deque, else
+     *         {@code false}
      * @throws ClassCastException if the class of the specified element
      *         prevents it from being added to this deque
      * @throws NullPointerException if the specified element is null and this
@@ -288,17 +292,17 @@
 
     /**
      * Retrieves and removes the first element of this deque,
-     * or returns <tt>null</tt> if this deque is empty.
+     * or returns {@code null} if this deque is empty.
      *
-     * @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 pollFirst();
 
     /**
      * Retrieves and removes the last element of this deque,
-     * or returns <tt>null</tt> if this deque is empty.
+     * or returns {@code null} if this deque is empty.
      *
-     * @return the tail of this deque, or <tt>null</tt> if this deque is empty
+     * @return the tail of this deque, or {@code null} if this deque is empty
      */
     E pollLast();
 
@@ -325,31 +329,31 @@
 
     /**
      * Retrieves, but does not remove, the first element of this deque,
-     * or returns <tt>null</tt> if this deque is empty.
+     * or returns {@code null} if this deque is empty.
      *
-     * @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 peekFirst();
 
     /**
      * Retrieves, but does not remove, the last element of this deque,
-     * or returns <tt>null</tt> if this deque is empty.
+     * or returns {@code null} if this deque is empty.
      *
-     * @return the tail of this deque, or <tt>null</tt> if this deque is empty
+     * @return the tail of this deque, or {@code null} if this deque is empty
      */
     E peekLast();
 
     /**
      * 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
+     * More formally, removes the first element {@code e} such that
      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
      * (if such an element exists).
-     * Returns <tt>true</tt> if this deque contained the specified element
+     * 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>)
@@ -362,14 +366,14 @@
     /**
      * 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
+     * More formally, removes the last element {@code e} such that
      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
      * (if such an element exists).
-     * Returns <tt>true</tt> if this deque contained the specified element
+     * 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>)
@@ -385,15 +389,15 @@
      * 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}.
      *
      * <p>This method is equivalent to {@link #addLast}.
      *
      * @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
@@ -409,7 +413,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.
@@ -417,8 +421,8 @@
      * <p>This method is equivalent to {@link #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 ClassCastException if the class of the specified element
      *         prevents it from being added to this deque
      * @throws NullPointerException if the specified element is null and this
@@ -444,11 +448,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 first element of this deque, or <tt>null</tt> if
+     * @return the first element of this deque, or {@code null} if
      *         this deque is empty
      */
     E poll();
@@ -469,12 +473,12 @@
     /**
      * 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()}.
      *
      * @return the head of the queue represented by this deque, or
-     *         <tt>null</tt> if this deque is empty
+     *         {@code null} if this deque is empty
      */
     E peek();
 
@@ -484,9 +488,8 @@
     /**
      * 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, returning
-     * <tt>true</tt> upon success and throwing an
-     * <tt>IllegalStateException</tt> if no space is currently available.
+     * immediately without violating capacity restrictions, throwing an
+     * {@code IllegalStateException} if no space is currently available.
      *
      * <p>This method is equivalent to {@link #addFirst}.
      *
@@ -520,16 +523,16 @@
     /**
      * 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
+     * More formally, removes the first element {@code e} such that
      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
      * (if such an element exists).
-     * Returns <tt>true</tt> if this deque contained the specified element
+     * 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}.
+     * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
      *
      * @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>)
@@ -540,13 +543,13 @@
     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
+     * 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
      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
      *
      * @param o element whose presence in this deque is to be tested
-     * @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 type of the specified element
      *         is incompatible with this deque
      * (<a href="Collection.html#optional-restrictions">optional</a>)
--- a/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java	Wed Jul 05 19:07:11 2017 +0200
@@ -25,6 +25,7 @@
 package java.util;
 
 import java.util.function.DoubleConsumer;
+import java.util.stream.Collector;
 
 /**
  * A state object for collecting statistics such as count, min, max, sum, and
@@ -35,24 +36,24 @@
  * summary statistics on a stream of doubles with:
  * <pre> {@code
  * DoubleSummaryStatistics stats = doubleStream.collect(DoubleSummaryStatistics::new,
- *     DoubleSummaryStatistics::accept,
- *     DoubleSummaryStatistics::combine);
+ *                                                      DoubleSummaryStatistics::accept,
+ *                                                      DoubleSummaryStatistics::combine);
  * }</pre>
  *
  * <p>{@code DoubleSummaryStatistics} can be used as a
- * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction}
+ * {@linkplain java.util.stream.Stream#collect(Collector) reduction}
  * target for a {@linkplain java.util.stream.Stream stream}. For example:
  *
  * <pre> {@code
  * DoubleSummaryStatistics stats = people.stream()
- *     .collect(Collectors.toDoubleSummaryStatistics(Person::getWeight));
+ *     .collect(Collectors.summarizingDouble(Person::getWeight));
  *}</pre>
  *
  * This computes, in a single pass, the count of people, as well as the minimum,
  * maximum, sum, and average of their weights.
  *
  * @implNote This implementation is not thread safe. However, it is safe to use
- * {@link java.util.stream.Collectors#toDoubleSummaryStatistics(java.util.function.ToDoubleFunction)
+ * {@link java.util.stream.Collectors#summarizingDouble(java.util.function.ToDoubleFunction)
  * Collectors.toDoubleStatistics()} on a parallel stream, because the parallel
  * implementation of {@link java.util.stream.Stream#collect Stream.collect()}
  * provides the necessary partitioning, isolation, and merging of results for
@@ -152,7 +153,7 @@
     }
 
     /**
-     * Returns the average of values recorded, or zero if no values have been
+     * Returns the arithmetic mean of values recorded, or zero if no values have been
      * recorded. The average returned can vary depending upon the order in
      * which values are recorded. This is due to accumulated rounding error in
      * addition of values of differing magnitudes. Values sorted by increasing
@@ -160,7 +161,7 @@
      * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
      * average will be {@code NaN}.
      *
-     * @return the average of values, or zero if none
+     * @return the arithmetic mean of values, or zero if none
      */
     public final double getAverage() {
         return getCount() > 0 ? getSum() / getCount() : 0.0d;
--- a/jdk/src/share/classes/java/util/Formatter.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/Formatter.java	Wed Jul 05 19:07:11 2017 +0200
@@ -626,12 +626,11 @@
  * <p> For general argument types, the precision is the maximum number of
  * characters to be written to the output.
  *
- * <p> For the floating-point conversions {@code 'e'}, {@code 'E'}, and
- * {@code 'f'} the precision is the number of digits after the decimal
- * separator.  If the conversion is {@code 'g'} or {@code 'G'}, then the
+ * <p> For the floating-point conversions {@code 'a'}, {@code 'A'}, {@code 'e'},
+ * {@code 'E'}, and {@code 'f'} the precision is the number of digits after the
+ * radix point.  If the conversion is {@code 'g'} or {@code 'G'}, then the
  * precision is the total number of digits in the resulting magnitude after
- * rounding.  If the conversion is {@code 'a'} or {@code 'A'}, then the
- * precision must not be specified.
+ * rounding.
  *
  * <p> For character, integral, and date/time argument types and the percent
  * and line separator conversions, the precision is not applicable; if a
@@ -1297,14 +1296,21 @@
  *     of the significand as a fraction.  The exponent is represented by
  *     {@code 'p'} (<tt>'&#92;u0070'</tt>) followed by a decimal string of the
  *     unbiased exponent as if produced by invoking {@link
- *     Integer#toString(int) Integer.toString} on the exponent value.
+ *     Integer#toString(int) Integer.toString} on the exponent value.  If the
+ *     precision is specified, the value is rounded to the given number of
+ *     hexadecimal digits.
  *
  *     <li> If <i>m</i> is a {@code double} value with a subnormal
- *     representation then the significand is represented by the characters
- *     {@code '0x0.'} followed by the hexadecimal representation of the rest
- *     of the significand as a fraction.  The exponent is represented by
- *     {@code 'p-1022'}.  Note that there must be at least one nonzero digit
- *     in a subnormal significand.
+ *     representation then, unless the precision is specified to be in the range
+ *     1 through 12, inclusive, the significand is represented by the characters
+ *     {@code '0x0.'} followed by the hexadecimal representation of the rest of
+ *     the significand as a fraction, and the exponent represented by
+ *     {@code 'p-1022'}.  If the precision is in the interval
+ *     [1,&nbsp;12], the subnormal value is normalized such that it
+ *     begins with the characters {@code '0x1.'}, rounded to the number of
+ *     hexadecimal digits of precision, and the exponent adjusted
+ *     accordingly.  Note that there must be at least one nonzero digit in a
+ *     subnormal significand.
  *
  *     </ul>
  *
@@ -1367,7 +1373,7 @@
  * {@code 1}.
  *
  * <p> If the conversion is {@code 'a'} or {@code 'A'}, then the precision
- * is the number of hexadecimal digits after the decimal separator.  If the
+ * is the number of hexadecimal digits after the radix point.  If the
  * precision is not provided, then all of the digits as returned by {@link
  * Double#toHexString(double)} will be output.
  *
--- a/jdk/src/share/classes/java/util/HashMap.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/HashMap.java	Wed Jul 05 19:07:11 2017 +0200
@@ -876,13 +876,9 @@
 
     private static int roundUpToPowerOf2(int number) {
         // assert number >= 0 : "number must be non-negative";
-        int rounded = number >= MAXIMUM_CAPACITY
+        return number >= MAXIMUM_CAPACITY
                 ? MAXIMUM_CAPACITY
-                : (rounded = Integer.highestOneBit(number)) != 0
-                    ? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded
-                    : 1;
-
-        return rounded;
+                : (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1;
     }
 
     /**
--- a/jdk/src/share/classes/java/util/Hashtable.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/Hashtable.java	Wed Jul 05 19:07:11 2017 +0200
@@ -928,6 +928,7 @@
         return (null == result) ? defaultValue : result;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public synchronized void forEach(BiConsumer<? super K, ? super V> action) {
         Objects.requireNonNull(action);     // explicit check required in case
@@ -947,6 +948,7 @@
         }
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public synchronized void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
         Objects.requireNonNull(function);     // explicit check required in case
--- a/jdk/src/share/classes/java/util/IdentityHashMap.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/IdentityHashMap.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1339,6 +1339,7 @@
         tab[i + 1] = value;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public void forEach(BiConsumer<? super K, ? super V> action) {
         Objects.requireNonNull(action);
@@ -1357,6 +1358,7 @@
         }
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
         Objects.requireNonNull(function);
--- a/jdk/src/share/classes/java/util/IntSummaryStatistics.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/IntSummaryStatistics.java	Wed Jul 05 19:07:11 2017 +0200
@@ -25,6 +25,7 @@
 package java.util;
 
 import java.util.function.IntConsumer;
+import java.util.stream.Collector;
 
 /**
  * A state object for collecting statistics such as count, min, max, sum, and
@@ -35,24 +36,24 @@
  * summary statistics on a stream of ints with:
  * <pre> {@code
  * IntSummaryStatistics stats = intStream.collect(IntSummaryStatistics::new,
- *     IntSummaryStatistics::accept,
- *     IntSummaryStatistics::combine);
+ *                                                IntSummaryStatistics::accept,
+ *                                                IntSummaryStatistics::combine);
  * }</pre>
  *
  * <p>{@code IntSummaryStatistics} can be used as a
- * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction}
+ * {@linkplain java.util.stream.Stream#collect(Collector) reduction}
  * target for a {@linkplain java.util.stream.Stream stream}. For example:
  *
  * <pre> {@code
  * IntSummaryStatistics stats = people.stream()
- *     .collect(Collectors.toIntSummaryStatistics(Person::getDependents));
+ *                                    .collect(Collectors.summarizingInt(Person::getDependents));
  *}</pre>
  *
  * This computes, in a single pass, the count of people, as well as the minimum,
  * maximum, sum, and average of their number of dependents.
  *
  * @implNote This implementation is not thread safe. However, it is safe to use
- * {@link java.util.stream.Collectors#toIntSummaryStatistics(java.util.function.ToIntFunction)
+ * {@link java.util.stream.Collectors#summarizingInt(java.util.function.ToIntFunction)
  * Collectors.toIntStatistics()} on a parallel stream, because the parallel
  * implementation of {@link java.util.stream.Stream#collect Stream.collect()}
  * provides the necessary partitioning, isolation, and merging of results for
@@ -140,10 +141,10 @@
     }
 
     /**
-     * Returns the average of values recorded, or zero if no values have been
+     * Returns the arithmetic mean of values recorded, or zero if no values have been
      * recorded.
      *
-     * @return the average of values, or zero if none
+     * @return the arithmetic mean of values, or zero if none
      */
     public final double getAverage() {
         return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
--- a/jdk/src/share/classes/java/util/LongSummaryStatistics.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/LongSummaryStatistics.java	Wed Jul 05 19:07:11 2017 +0200
@@ -26,6 +26,7 @@
 
 import java.util.function.IntConsumer;
 import java.util.function.LongConsumer;
+import java.util.stream.Collector;
 
 /**
  * A state object for collecting statistics such as count, min, max, sum, and
@@ -36,24 +37,24 @@
  * summary statistics on a stream of longs with:
  * <pre> {@code
  * LongSummaryStatistics stats = longStream.collect(LongSummaryStatistics::new,
- *     LongSummaryStatistics::accept,
- *     LongSummaryStatistics::combine);
+ *                                                  LongSummaryStatistics::accept,
+ *                                                  LongSummaryStatistics::combine);
  * }</pre>
  *
  * <p>{@code LongSummaryStatistics} can be used as a
- * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction}
+ * {@linkplain java.util.stream.Stream#collect(Collector)} reduction}
  * target for a {@linkplain java.util.stream.Stream stream}. For example:
  *
  * <pre> {@code
  * LongSummaryStatistics stats = people.stream()
- *     .collect(Collectors.toLongSummaryStatistics(Person::getAge));
+ *                                     .collect(Collectors.summarizingLong(Person::getAge));
  *}</pre>
  *
  * This computes, in a single pass, the count of people, as well as the minimum,
- * maximum, sum, and average of their ages in milliseconds.
+ * maximum, sum, and average of their ages.
  *
  * @implNote This implementation is not thread safe. However, it is safe to use
- * {@link java.util.stream.Collectors#toLongSummaryStatistics(java.util.function.ToLongFunction)
+ * {@link java.util.stream.Collectors#summarizingLong(java.util.function.ToLongFunction)
  * Collectors.toLongStatistics()} on a parallel stream, because the parallel
  * implementation of {@link java.util.stream.Stream#collect Stream.collect()}
  * provides the necessary partitioning, isolation, and merging of results for
@@ -152,10 +153,10 @@
     }
 
     /**
-     * Returns the average of values recorded, or zero if no values have been
+     * Returns the arithmetic mean of values recorded, or zero if no values have been
      * recorded.
      *
-     * @return The average of values, or zero if none
+     * @return The arithmetic mean of values, or zero if none
      */
     public final double getAverage() {
         return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
--- a/jdk/src/share/classes/java/util/Optional.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/Optional.java	Wed Jul 05 19:07:11 2017 +0200
@@ -307,7 +307,7 @@
             return false;
         }
 
-        Optional other = (Optional) obj;
+        Optional<?> other = (Optional<?>) obj;
         return Objects.equals(value, other.value);
     }
 
--- a/jdk/src/share/classes/java/util/Queue.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/Queue.java	Wed Jul 05 19:07:11 2017 +0200
@@ -41,14 +41,15 @@
  * queues provide additional insertion, extraction, and inspection
  * operations.  Each of these methods exists in two forms: one throws
  * an exception if the operation fails, the other returns a special
- * value (either <tt>null</tt> or <tt>false</tt>, depending on the
+ * value (either {@code null} or {@code false}, depending on the
  * operation).  The latter form of the insert operation is designed
- * specifically for use with capacity-restricted <tt>Queue</tt>
+ * specifically for use with capacity-restricted {@code Queue}
  * implementations; in most implementations, insert operations cannot
  * fail.
  *
  * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Summary of Queue methods</caption>
  *  <tr>
  *    <td></td>
  *    <td ALIGN=CENTER><em>Throws exception</em></td>
@@ -56,18 +57,18 @@
  *  </tr>
  *  <tr>
  *    <td><b>Insert</b></td>
- *    <td>{@link #add add(e)}</td>
- *    <td>{@link #offer offer(e)}</td>
+ *    <td>{@link Queue#add add(e)}</td>
+ *    <td>{@link Queue#offer offer(e)}</td>
  *  </tr>
  *  <tr>
  *    <td><b>Remove</b></td>
- *    <td>{@link #remove remove()}</td>
- *    <td>{@link #poll poll()}</td>
+ *    <td>{@link Queue#remove remove()}</td>
+ *    <td>{@link Queue#poll poll()}</td>
  *  </tr>
  *  <tr>
  *    <td><b>Examine</b></td>
- *    <td>{@link #element element()}</td>
- *    <td>{@link #peek peek()}</td>
+ *    <td>{@link Queue#element element()}</td>
+ *    <td>{@link Queue#peek peek()}</td>
  *  </tr>
  * </table>
  *
@@ -79,15 +80,15 @@
  * Whatever the ordering used, the <em>head</em> of the queue is that
  * element which would be removed by a call to {@link #remove() } or
  * {@link #poll()}.  In a FIFO queue, all new elements are inserted at
- * the <em> tail</em> of the queue. Other kinds of queues may use
- * different placement rules.  Every <tt>Queue</tt> implementation
+ * the <em>tail</em> of the queue. Other kinds of queues may use
+ * different placement rules.  Every {@code Queue} implementation
  * must specify its ordering properties.
  *
  * <p>The {@link #offer offer} method inserts an element if possible,
- * otherwise returning <tt>false</tt>.  This differs from the {@link
+ * otherwise returning {@code false}.  This differs from the {@link
  * java.util.Collection#add Collection.add} method, which can fail to
  * add an element only by throwing an unchecked exception.  The
- * <tt>offer</tt> method is designed for use when failure is a normal,
+ * {@code offer} method is designed for use when failure is a normal,
  * rather than exceptional occurrence, for example, in fixed-capacity
  * (or &quot;bounded&quot;) queues.
  *
@@ -95,32 +96,32 @@
  * return the head of the queue.
  * Exactly which element is removed from the queue is a
  * function of the queue's ordering policy, which differs from
- * implementation to implementation. The <tt>remove()</tt> and
- * <tt>poll()</tt> methods differ only in their behavior when the
- * queue is empty: the <tt>remove()</tt> method throws an exception,
- * while the <tt>poll()</tt> method returns <tt>null</tt>.
+ * implementation to implementation. The {@code remove()} and
+ * {@code poll()} methods differ only in their behavior when the
+ * queue is empty: the {@code remove()} method throws an exception,
+ * while the {@code poll()} method returns {@code null}.
  *
  * <p>The {@link #element()} and {@link #peek()} methods return, but do
  * not remove, the head of the queue.
  *
- * <p>The <tt>Queue</tt> interface does not define the <i>blocking queue
+ * <p>The {@code Queue} interface does not define the <i>blocking queue
  * methods</i>, which are common in concurrent programming.  These methods,
  * which wait for elements to appear or for space to become available, are
  * defined in the {@link java.util.concurrent.BlockingQueue} interface, which
  * extends this interface.
  *
- * <p><tt>Queue</tt> implementations generally do not allow insertion
- * of <tt>null</tt> elements, although some implementations, such as
- * {@link LinkedList}, do not prohibit insertion of <tt>null</tt>.
- * Even in the implementations that permit it, <tt>null</tt> should
- * not be inserted into a <tt>Queue</tt>, as <tt>null</tt> is also
- * used as a special return value by the <tt>poll</tt> method to
+ * <p>{@code Queue} implementations generally do not allow insertion
+ * of {@code null} elements, although some implementations, such as
+ * {@link LinkedList}, do not prohibit insertion of {@code null}.
+ * Even in the implementations that permit it, {@code null} should
+ * not be inserted into a {@code Queue}, as {@code null} is also
+ * used as a special return value by the {@code poll} method to
  * indicate that the queue contains no elements.
  *
- * <p><tt>Queue</tt> implementations generally do not define
- * element-based versions of methods <tt>equals</tt> and
- * <tt>hashCode</tt> but instead inherit the identity based versions
- * from class <tt>Object</tt>, because element-based equality is not
+ * <p>{@code Queue} implementations generally do not define
+ * element-based versions of methods {@code equals} and
+ * {@code hashCode} but instead inherit the identity based versions
+ * from class {@code Object}, because element-based equality is not
  * always well-defined for queues with the same elements but different
  * ordering properties.
  *
@@ -145,11 +146,11 @@
     /**
      * 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>
+     * {@code true} upon success and throwing an {@code IllegalStateException}
      * if no space is currently available.
      *
      * @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
@@ -169,8 +170,8 @@
      * 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 and
@@ -192,9 +193,9 @@
 
     /**
      * Retrieves and removes the head of this queue,
-     * or returns <tt>null</tt> if this queue is empty.
+     * or returns {@code null} if this queue is empty.
      *
-     * @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
      */
     E poll();
 
@@ -210,9 +211,9 @@
 
     /**
      * Retrieves, but does not remove, the head of this queue,
-     * or returns <tt>null</tt> if this queue is empty.
+     * or returns {@code null} if this queue is empty.
      *
-     * @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
      */
     E peek();
 }
--- a/jdk/src/share/classes/java/util/StringJoiner.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/StringJoiner.java	Wed Jul 05 19:07:11 2017 +0200
@@ -49,16 +49,17 @@
  * <p>
  * A {@code StringJoiner} may be employed to create formatted output from a
  * {@link java.util.stream.Stream} using
- * {@link java.util.stream.Collectors#toStringJoiner}. For example:
+ * {@link java.util.stream.Collectors#joining(CharSequence)}. For example:
  *
  * <pre> {@code
  * List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
  * String commaSeparatedNumbers = numbers.stream()
  *     .map(i -> i.toString())
- *     .collect(Collectors.toStringJoiner(", ")).toString();
+ *     .collect(Collectors.joining(", "));
  * }</pre>
  *
- * @see java.util.stream.Collectors#toStringJoiner
+ * @see java.util.stream.Collectors#joining(CharSequence)
+ * @see java.util.stream.Collectors#joining(CharSequence, CharSequence, CharSequence)
  * @since  1.8
 */
 public final class StringJoiner {
--- a/jdk/src/share/classes/java/util/Vector.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/Vector.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1164,12 +1164,13 @@
                 if (i >= size) {
                     return;
                 }
-                final Object[] elementData = Vector.this.elementData;
+        @SuppressWarnings("unchecked")
+                final E[] elementData = (E[]) Vector.this.elementData;
                 if (i >= elementData.length) {
                     throw new ConcurrentModificationException();
                 }
                 while (i != size && modCount == expectedModCount) {
-                    action.accept((E) elementData[i++]);
+                    action.accept(elementData[i++]);
                 }
                 // update once at end of iteration to reduce heap write traffic
                 cursor = i;
@@ -1311,8 +1312,8 @@
         modCount++;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    @SuppressWarnings("unchecked")
     public synchronized void sort(Comparator<? super E> c) {
         final int expectedModCount = modCount;
         Arrays.sort((E[]) elementData, 0, elementCount, c);
--- a/jdk/src/share/classes/java/util/WeakHashMap.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/WeakHashMap.java	Wed Jul 05 19:07:11 2017 +0200
@@ -1038,6 +1038,7 @@
         }
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public void forEach(BiConsumer<? super K, ? super V> action) {
         Objects.requireNonNull(action);
@@ -1059,6 +1060,7 @@
         }
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
         Objects.requireNonNull(function);
--- a/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java	Wed Jul 05 19:07:11 2017 +0200
@@ -48,13 +48,16 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.CompletionStage;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.LockSupport;
 
 /**
  * A {@link Future} that may be explicitly completed (setting its
- * value and status), and may include dependent functions and actions
- * that trigger upon its completion.
+ * value and status), and may be used as a {@link CompletionStage},
+ * supporting dependent functions and actions that trigger upon its
+ * completion.
  *
  * <p>When two or more threads attempt to
  * {@link #complete complete},
@@ -62,64 +65,50 @@
  * {@link #cancel cancel}
  * a CompletableFuture, only one of them succeeds.
  *
- * <p>Methods are available for adding dependents based on
- * user-provided Functions, Consumers, or Runnables. The appropriate
- * form to use depends on whether actions require arguments and/or
- * produce results.  Completion of a dependent action will trigger the
- * completion of another CompletableFuture.  Actions may also be
- * triggered after either or both the current and another
- * CompletableFuture complete.  Multiple CompletableFutures may also
- * be grouped as one using {@link #anyOf(CompletableFuture...)} and
- * {@link #allOf(CompletableFuture...)}.
+ * <p>In addition to these and related methods for directly
+ * manipulating status and results, CompletableFuture implements
+ * interface {@link CompletionStage} with the following policies: <ul>
  *
- * <p>CompletableFutures themselves do not execute asynchronously.
- * However, actions supplied for dependent completions of another
- * CompletableFuture may do so, depending on whether they are provided
- * via one of the <em>async</em> methods (that is, methods with names
- * of the form <tt><var>xxx</var>Async</tt>).  The <em>async</em>
- * methods provide a way to commence asynchronous processing of an
- * action using either a given {@link Executor} or by default the
- * {@link ForkJoinPool#commonPool()}. To simplify monitoring,
+ * <li>Actions supplied for dependent completions of
+ * <em>non-async</em> methods may be performed by the thread that
+ * completes the current CompletableFuture, or by any other caller of
+ * a completion method.</li>
+ *
+ * <li>All <em>async</em> methods without an explicit Executor
+ * argument are performed using the {@link ForkJoinPool#commonPool()}
+ * (unless it does not support a parallelism level of at least two, in
+ * which case, a new Thread is used). To simplify monitoring,
  * debugging, and tracking, all generated asynchronous tasks are
- * instances of the marker interface {@link AsynchronousCompletionTask}.
+ * instances of the marker interface {@link
+ * AsynchronousCompletionTask}. </li>
  *
- * <p>Actions supplied for dependent completions of <em>non-async</em>
- * methods may be performed by the thread that completes the current
- * CompletableFuture, or by any other caller of these methods.  There
- * are no guarantees about the order of processing completions unless
- * constrained by these methods.
+ * <li>All CompletionStage methods are implemented independently of
+ * other public methods, so the behavior of one method is not impacted
+ * by overrides of others in subclasses.  </li> </ul>
  *
- * <p>Since (unlike {@link FutureTask}) this class has no direct
+ * <p>CompletableFuture also implements {@link Future} with the following
+ * policies: <ul>
+ *
+ * <li>Since (unlike {@link FutureTask}) this class has no direct
  * control over the computation that causes it to be completed,
- * cancellation is treated as just another form of exceptional completion.
- * Method {@link #cancel cancel} has the same effect as
- * {@code completeExceptionally(new CancellationException())}.
+ * cancellation is treated as just another form of exceptional
+ * completion.  Method {@link #cancel cancel} has the same effect as
+ * {@code completeExceptionally(new CancellationException())}. Method
+ * {@link #isCompletedExceptionally} can be used to determine if a
+ * CompletableFuture completed in any exceptional fashion.</li>
  *
- * <p>Upon exceptional completion (including cancellation), or when a
- * completion entails an additional computation which terminates
- * abruptly with an (unchecked) exception or error, then all of their
- * dependent completions (and their dependents in turn) generally act
- * as {@code completeExceptionally} with a {@link CompletionException}
- * holding that exception as its cause.  However, the {@link
- * #exceptionally exceptionally} and {@link #handle handle}
- * completions <em>are</em> able to handle exceptional completions of
- * the CompletableFutures they depend on.
- *
- * <p>In case of exceptional completion with a CompletionException,
+ * <li>In case of exceptional completion with a CompletionException,
  * methods {@link #get()} and {@link #get(long, TimeUnit)} throw an
  * {@link ExecutionException} with the same cause as held in the
- * corresponding CompletionException.  However, in these cases,
- * methods {@link #join()} and {@link #getNow} throw the
- * CompletionException, which simplifies usage.
- *
- * <p>Arguments used to pass a completion result (that is, for parameters
- * of type {@code T}) may be null, but passing a null value for any other
- * parameter will result in a {@link NullPointerException} being thrown.
+ * corresponding CompletionException.  To simplify usage in most
+ * contexts, this class also defines methods {@link #join()} and
+ * {@link #getNow} that instead throw the CompletionException directly
+ * in these cases.</li> </ul>
  *
  * @author Doug Lea
  * @since 1.8
  */
-public class CompletableFuture<T> implements Future<T> {
+public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
 
     /*
      * Overview:
@@ -438,6 +427,19 @@
         public final void run() { exec(); }
     }
 
+    /**
+     * Starts the given async task using the given executor, unless
+     * the executor is ForkJoinPool.commonPool and it has been
+     * disabled, in which case starts a new thread.
+     */
+    static void execAsync(Executor e, Async r) {
+        if (e == ForkJoinPool.commonPool() &&
+            ForkJoinPool.getCommonPoolParallelism() <= 1)
+            new Thread(r).start();
+        else
+            e.execute(r);
+    }
+
     static final class AsyncRun extends Async {
         final Runnable fn;
         final CompletableFuture<Void> dst;
@@ -538,13 +540,13 @@
     static final class AsyncAccept<T> extends Async {
         final T arg;
         final Consumer<? super T> fn;
-        final CompletableFuture<Void> dst;
+        final CompletableFuture<?> dst;
         AsyncAccept(T arg, Consumer<? super T> fn,
-                    CompletableFuture<Void> dst) {
+                    CompletableFuture<?> dst) {
             this.arg = arg; this.fn = fn; this.dst = dst;
         }
         public final boolean exec() {
-            CompletableFuture<Void> d; Throwable ex;
+            CompletableFuture<?> d; Throwable ex;
             if ((d = this.dst) != null && d.result == null) {
                 try {
                     fn.accept(arg);
@@ -563,14 +565,14 @@
         final T arg1;
         final U arg2;
         final BiConsumer<? super T,? super U> fn;
-        final CompletableFuture<Void> dst;
+        final CompletableFuture<?> dst;
         AsyncAcceptBoth(T arg1, U arg2,
                         BiConsumer<? super T,? super U> fn,
-                        CompletableFuture<Void> dst) {
+                        CompletableFuture<?> dst) {
             this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst;
         }
         public final boolean exec() {
-            CompletableFuture<Void> d; Throwable ex;
+            CompletableFuture<?> d; Throwable ex;
             if ((d = this.dst) != null && d.result == null) {
                 try {
                     fn.accept(arg1, arg2);
@@ -587,10 +589,10 @@
 
     static final class AsyncCompose<T,U> extends Async {
         final T arg;
-        final Function<? super T, CompletableFuture<U>> fn;
+        final Function<? super T, ? extends CompletionStage<U>> fn;
         final CompletableFuture<U> dst;
         AsyncCompose(T arg,
-                     Function<? super T, CompletableFuture<U>> fn,
+                     Function<? super T, ? extends CompletionStage<U>> fn,
                      CompletableFuture<U> dst) {
             this.arg = arg; this.fn = fn; this.dst = dst;
         }
@@ -598,7 +600,8 @@
             CompletableFuture<U> d, fr; U u; Throwable ex;
             if ((d = this.dst) != null && d.result == null) {
                 try {
-                    fr = fn.apply(arg);
+                    CompletionStage<U> cs = fn.apply(arg);
+                    fr = (cs == null) ? null : cs.toCompletableFuture();
                     ex = (fr == null) ? new NullPointerException() : null;
                 } catch (Throwable rex) {
                     ex = rex;
@@ -626,6 +629,33 @@
         private static final long serialVersionUID = 5232453952276885070L;
     }
 
+    static final class AsyncWhenComplete<T> extends Async {
+        final T arg1;
+        final Throwable arg2;
+        final BiConsumer<? super T,? super Throwable> fn;
+        final CompletableFuture<T> dst;
+        AsyncWhenComplete(T arg1, Throwable arg2,
+                          BiConsumer<? super T,? super Throwable> fn,
+                          CompletableFuture<T> dst) {
+            this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst;
+        }
+        public final boolean exec() {
+            CompletableFuture<T> d;
+            if ((d = this.dst) != null && d.result == null) {
+                Throwable ex = arg2;
+                try {
+                    fn.accept(arg1, ex);
+                } catch (Throwable rex) {
+                    if (ex == null)
+                        ex = rex;
+                }
+                d.internalComplete(arg1, ex);
+            }
+            return true;
+        }
+        private static final long serialVersionUID = 5232453952276885070L;
+    }
+
     /* ------------- Completions -------------- */
 
     /**
@@ -680,7 +710,7 @@
                 if (ex == null) {
                     try {
                         if (e != null)
-                            e.execute(new AsyncApply<T,U>(t, fn, dst));
+                            execAsync(e, new AsyncApply<T,U>(t, fn, dst));
                         else
                             u = fn.apply(t);
                     } catch (Throwable rex) {
@@ -697,11 +727,11 @@
     static final class ThenAccept<T> extends Completion {
         final CompletableFuture<? extends T> src;
         final Consumer<? super T> fn;
-        final CompletableFuture<Void> dst;
+        final CompletableFuture<?> dst;
         final Executor executor;
         ThenAccept(CompletableFuture<? extends T> src,
                    Consumer<? super T> fn,
-                   CompletableFuture<Void> dst,
+                   CompletableFuture<?> dst,
                    Executor executor) {
             this.src = src; this.fn = fn; this.dst = dst;
             this.executor = executor;
@@ -709,7 +739,7 @@
         public final void run() {
             final CompletableFuture<? extends T> a;
             final Consumer<? super T> fn;
-            final CompletableFuture<Void> dst;
+            final CompletableFuture<?> dst;
             Object r; T t; Throwable ex;
             if ((dst = this.dst) != null &&
                 (fn = this.fn) != null &&
@@ -729,7 +759,7 @@
                 if (ex == null) {
                     try {
                         if (e != null)
-                            e.execute(new AsyncAccept<T>(t, fn, dst));
+                            execAsync(e, new AsyncAccept<T>(t, fn, dst));
                         else
                             fn.accept(t);
                     } catch (Throwable rex) {
@@ -773,7 +803,7 @@
                 if (ex == null) {
                     try {
                         if (e != null)
-                            e.execute(new AsyncRun(fn, dst));
+                            execAsync(e, new AsyncRun(fn, dst));
                         else
                             fn.run();
                     } catch (Throwable rex) {
@@ -839,7 +869,7 @@
                 if (ex == null) {
                     try {
                         if (e != null)
-                            e.execute(new AsyncCombine<T,U,V>(t, u, fn, dst));
+                            execAsync(e, new AsyncCombine<T,U,V>(t, u, fn, dst));
                         else
                             v = fn.apply(t, u);
                     } catch (Throwable rex) {
@@ -904,7 +934,7 @@
                 if (ex == null) {
                     try {
                         if (e != null)
-                            e.execute(new AsyncAcceptBoth<T,U>(t, u, fn, dst));
+                            execAsync(e, new AsyncAcceptBoth<T,U>(t, u, fn, dst));
                         else
                             fn.accept(t, u);
                     } catch (Throwable rex) {
@@ -956,7 +986,7 @@
                 if (ex == null) {
                     try {
                         if (e != null)
-                            e.execute(new AsyncRun(fn, dst));
+                            execAsync(e, new AsyncRun(fn, dst));
                         else
                             fn.run();
                     } catch (Throwable rex) {
@@ -1042,7 +1072,7 @@
                 if (ex == null) {
                     try {
                         if (e != null)
-                            e.execute(new AsyncApply<T,U>(t, fn, dst));
+                            execAsync(e, new AsyncApply<T,U>(t, fn, dst));
                         else
                             u = fn.apply(t);
                     } catch (Throwable rex) {
@@ -1095,7 +1125,7 @@
                 if (ex == null) {
                     try {
                         if (e != null)
-                            e.execute(new AsyncAccept<T>(t, fn, dst));
+                            execAsync(e, new AsyncAccept<T>(t, fn, dst));
                         else
                             fn.accept(t);
                     } catch (Throwable rex) {
@@ -1143,7 +1173,7 @@
                 if (ex == null) {
                     try {
                         if (e != null)
-                            e.execute(new AsyncRun(fn, dst));
+                            execAsync(e, new AsyncRun(fn, dst));
                         else
                             fn.run();
                     } catch (Throwable rex) {
@@ -1226,6 +1256,54 @@
         private static final long serialVersionUID = 5232453952276885070L;
     }
 
+    static final class WhenCompleteCompletion<T> extends Completion {
+        final CompletableFuture<? extends T> src;
+        final BiConsumer<? super T, ? super Throwable> fn;
+        final CompletableFuture<T> dst;
+        final Executor executor;
+        WhenCompleteCompletion(CompletableFuture<? extends T> src,
+                                  BiConsumer<? super T, ? super Throwable> fn,
+                                  CompletableFuture<T> dst,
+                                  Executor executor) {
+            this.src = src; this.fn = fn; this.dst = dst;
+            this.executor = executor;
+        }
+        public final void run() {
+            final CompletableFuture<? extends T> a;
+            final BiConsumer<? super T, ? super Throwable> fn;
+            final CompletableFuture<T> dst;
+            Object r; T t; Throwable ex;
+            if ((dst = this.dst) != null &&
+                (fn = this.fn) != null &&
+                (a = this.src) != null &&
+                (r = a.result) != null &&
+                compareAndSet(0, 1)) {
+                if (r instanceof AltResult) {
+                    ex = ((AltResult)r).ex;
+                    t = null;
+                }
+                else {
+                    ex = null;
+                    @SuppressWarnings("unchecked") T tr = (T) r;
+                    t = tr;
+                }
+                Executor e = executor;
+                Throwable dx = null;
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncWhenComplete<T>(t, ex, fn, dst));
+                    else
+                        fn.accept(t, ex);
+                } catch (Throwable rex) {
+                    dx = rex;
+                }
+                if (e == null || dx != null)
+                    dst.internalComplete(t, ex != null ? ex : dx);
+            }
+        }
+        private static final long serialVersionUID = 5232453952276885070L;
+    }
+
     static final class ThenCopy<T> extends Completion {
         final CompletableFuture<?> src;
         final CompletableFuture<T> dst;
@@ -1286,10 +1364,13 @@
         final CompletableFuture<? extends T> src;
         final BiFunction<? super T, Throwable, ? extends U> fn;
         final CompletableFuture<U> dst;
+        final Executor executor;
         HandleCompletion(CompletableFuture<? extends T> src,
                          BiFunction<? super T, Throwable, ? extends U> fn,
-                         CompletableFuture<U> dst) {
+                         CompletableFuture<U> dst,
+                          Executor executor) {
             this.src = src; this.fn = fn; this.dst = dst;
+            this.executor = executor;
         }
         public final void run() {
             final CompletableFuture<? extends T> a;
@@ -1310,13 +1391,19 @@
                     @SuppressWarnings("unchecked") T tr = (T) r;
                     t = tr;
                 }
-                U u = null; Throwable dx = null;
+                Executor e = executor;
+                U u = null;
+                Throwable dx = null;
                 try {
-                    u = fn.apply(t, ex);
+                    if (e != null)
+                        execAsync(e, new AsyncCombine<T,Throwable,U>(t, ex, fn, dst));
+                    else
+                        u = fn.apply(t, ex);
                 } catch (Throwable rex) {
                     dx = rex;
                 }
-                dst.internalComplete(u, dx);
+                if (e == null || dx != null)
+                    dst.internalComplete(u, dx);
             }
         }
         private static final long serialVersionUID = 5232453952276885070L;
@@ -1324,11 +1411,11 @@
 
     static final class ThenCompose<T,U> extends Completion {
         final CompletableFuture<? extends T> src;
-        final Function<? super T, CompletableFuture<U>> fn;
+        final Function<? super T, ? extends CompletionStage<U>> fn;
         final CompletableFuture<U> dst;
         final Executor executor;
         ThenCompose(CompletableFuture<? extends T> src,
-                    Function<? super T, CompletableFuture<U>> fn,
+                    Function<? super T, ? extends CompletionStage<U>> fn,
                     CompletableFuture<U> dst,
                     Executor executor) {
             this.src = src; this.fn = fn; this.dst = dst;
@@ -1336,7 +1423,7 @@
         }
         public final void run() {
             final CompletableFuture<? extends T> a;
-            final Function<? super T, CompletableFuture<U>> fn;
+            final Function<? super T, ? extends CompletionStage<U>> fn;
             final CompletableFuture<U> dst;
             Object r; T t; Throwable ex; Executor e;
             if ((dst = this.dst) != null &&
@@ -1358,10 +1445,12 @@
                 boolean complete = false;
                 if (ex == null) {
                     if ((e = executor) != null)
-                        e.execute(new AsyncCompose<T,U>(t, fn, dst));
+                        execAsync(e, new AsyncCompose<T,U>(t, fn, dst));
                     else {
                         try {
-                            if ((c = fn.apply(t)) == null)
+                            CompletionStage<U> cs = fn.apply(t);
+                            c = (cs == null) ? null : cs.toCompletableFuture();
+                            if (c == null)
                                 ex = new NullPointerException();
                         } catch (Throwable rex) {
                             ex = rex;
@@ -1401,6 +1490,619 @@
         private static final long serialVersionUID = 5232453952276885070L;
     }
 
+    // Implementations of stage methods with (plain, async, Executor) forms
+
+    private <U> CompletableFuture<U> doThenApply
+        (Function<? super T,? extends U> fn,
+         Executor e) {
+        if (fn == null) throw new NullPointerException();
+        CompletableFuture<U> dst = new CompletableFuture<U>();
+        ThenApply<T,U> d = null;
+        Object r;
+        if ((r = result) == null) {
+            CompletionNode p = new CompletionNode
+                (d = new ThenApply<T,U>(this, fn, dst, e));
+            while ((r = result) == null) {
+                if (UNSAFE.compareAndSwapObject
+                    (this, COMPLETIONS, p.next = completions, p))
+                    break;
+            }
+        }
+        if (r != null && (d == null || d.compareAndSet(0, 1))) {
+            T t; Throwable ex;
+            if (r instanceof AltResult) {
+                ex = ((AltResult)r).ex;
+                t = null;
+            }
+            else {
+                ex = null;
+                @SuppressWarnings("unchecked") T tr = (T) r;
+                t = tr;
+            }
+            U u = null;
+            if (ex == null) {
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncApply<T,U>(t, fn, dst));
+                    else
+                        u = fn.apply(t);
+                } catch (Throwable rex) {
+                    ex = rex;
+                }
+            }
+            if (e == null || ex != null)
+                dst.internalComplete(u, ex);
+        }
+        helpPostComplete();
+        return dst;
+    }
+
+    private CompletableFuture<Void> doThenAccept(Consumer<? super T> fn,
+                                                 Executor e) {
+        if (fn == null) throw new NullPointerException();
+        CompletableFuture<Void> dst = new CompletableFuture<Void>();
+        ThenAccept<T> d = null;
+        Object r;
+        if ((r = result) == null) {
+            CompletionNode p = new CompletionNode
+                (d = new ThenAccept<T>(this, fn, dst, e));
+            while ((r = result) == null) {
+                if (UNSAFE.compareAndSwapObject
+                    (this, COMPLETIONS, p.next = completions, p))
+                    break;
+            }
+        }
+        if (r != null && (d == null || d.compareAndSet(0, 1))) {
+            T t; Throwable ex;
+            if (r instanceof AltResult) {
+                ex = ((AltResult)r).ex;
+                t = null;
+            }
+            else {
+                ex = null;
+                @SuppressWarnings("unchecked") T tr = (T) r;
+                t = tr;
+            }
+            if (ex == null) {
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncAccept<T>(t, fn, dst));
+                    else
+                        fn.accept(t);
+                } catch (Throwable rex) {
+                    ex = rex;
+                }
+            }
+            if (e == null || ex != null)
+                dst.internalComplete(null, ex);
+        }
+        helpPostComplete();
+        return dst;
+    }
+
+    private CompletableFuture<Void> doThenRun(Runnable action,
+                                              Executor e) {
+        if (action == null) throw new NullPointerException();
+        CompletableFuture<Void> dst = new CompletableFuture<Void>();
+        ThenRun d = null;
+        Object r;
+        if ((r = result) == null) {
+            CompletionNode p = new CompletionNode
+                (d = new ThenRun(this, action, dst, e));
+            while ((r = result) == null) {
+                if (UNSAFE.compareAndSwapObject
+                    (this, COMPLETIONS, p.next = completions, p))
+                    break;
+            }
+        }
+        if (r != null && (d == null || d.compareAndSet(0, 1))) {
+            Throwable ex;
+            if (r instanceof AltResult)
+                ex = ((AltResult)r).ex;
+            else
+                ex = null;
+            if (ex == null) {
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncRun(action, dst));
+                    else
+                        action.run();
+                } catch (Throwable rex) {
+                    ex = rex;
+                }
+            }
+            if (e == null || ex != null)
+                dst.internalComplete(null, ex);
+        }
+        helpPostComplete();
+        return dst;
+    }
+
+    private <U,V> CompletableFuture<V> doThenCombine
+        (CompletableFuture<? extends U> other,
+         BiFunction<? super T,? super U,? extends V> fn,
+         Executor e) {
+        if (other == null || fn == null) throw new NullPointerException();
+        CompletableFuture<V> dst = new CompletableFuture<V>();
+        ThenCombine<T,U,V> d = null;
+        Object r, s = null;
+        if ((r = result) == null || (s = other.result) == null) {
+            d = new ThenCombine<T,U,V>(this, other, fn, dst, e);
+            CompletionNode q = null, p = new CompletionNode(d);
+            while ((r == null && (r = result) == null) ||
+                   (s == null && (s = other.result) == null)) {
+                if (q != null) {
+                    if (s != null ||
+                        UNSAFE.compareAndSwapObject
+                        (other, COMPLETIONS, q.next = other.completions, q))
+                        break;
+                }
+                else if (r != null ||
+                         UNSAFE.compareAndSwapObject
+                         (this, COMPLETIONS, p.next = completions, p)) {
+                    if (s != null)
+                        break;
+                    q = new CompletionNode(d);
+                }
+            }
+        }
+        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
+            T t; U u; Throwable ex;
+            if (r instanceof AltResult) {
+                ex = ((AltResult)r).ex;
+                t = null;
+            }
+            else {
+                ex = null;
+                @SuppressWarnings("unchecked") T tr = (T) r;
+                t = tr;
+            }
+            if (ex != null)
+                u = null;
+            else if (s instanceof AltResult) {
+                ex = ((AltResult)s).ex;
+                u = null;
+            }
+            else {
+                @SuppressWarnings("unchecked") U us = (U) s;
+                u = us;
+            }
+            V v = null;
+            if (ex == null) {
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncCombine<T,U,V>(t, u, fn, dst));
+                    else
+                        v = fn.apply(t, u);
+                } catch (Throwable rex) {
+                    ex = rex;
+                }
+            }
+            if (e == null || ex != null)
+                dst.internalComplete(v, ex);
+        }
+        helpPostComplete();
+        other.helpPostComplete();
+        return dst;
+    }
+
+    private <U> CompletableFuture<Void> doThenAcceptBoth
+        (CompletableFuture<? extends U> other,
+         BiConsumer<? super T,? super U> fn,
+         Executor e) {
+        if (other == null || fn == null) throw new NullPointerException();
+        CompletableFuture<Void> dst = new CompletableFuture<Void>();
+        ThenAcceptBoth<T,U> d = null;
+        Object r, s = null;
+        if ((r = result) == null || (s = other.result) == null) {
+            d = new ThenAcceptBoth<T,U>(this, other, fn, dst, e);
+            CompletionNode q = null, p = new CompletionNode(d);
+            while ((r == null && (r = result) == null) ||
+                   (s == null && (s = other.result) == null)) {
+                if (q != null) {
+                    if (s != null ||
+                        UNSAFE.compareAndSwapObject
+                        (other, COMPLETIONS, q.next = other.completions, q))
+                        break;
+                }
+                else if (r != null ||
+                         UNSAFE.compareAndSwapObject
+                         (this, COMPLETIONS, p.next = completions, p)) {
+                    if (s != null)
+                        break;
+                    q = new CompletionNode(d);
+                }
+            }
+        }
+        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
+            T t; U u; Throwable ex;
+            if (r instanceof AltResult) {
+                ex = ((AltResult)r).ex;
+                t = null;
+            }
+            else {
+                ex = null;
+                @SuppressWarnings("unchecked") T tr = (T) r;
+                t = tr;
+            }
+            if (ex != null)
+                u = null;
+            else if (s instanceof AltResult) {
+                ex = ((AltResult)s).ex;
+                u = null;
+            }
+            else {
+                @SuppressWarnings("unchecked") U us = (U) s;
+                u = us;
+            }
+            if (ex == null) {
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncAcceptBoth<T,U>(t, u, fn, dst));
+                    else
+                        fn.accept(t, u);
+                } catch (Throwable rex) {
+                    ex = rex;
+                }
+            }
+            if (e == null || ex != null)
+                dst.internalComplete(null, ex);
+        }
+        helpPostComplete();
+        other.helpPostComplete();
+        return dst;
+    }
+
+    private CompletableFuture<Void> doRunAfterBoth(CompletableFuture<?> other,
+                                                   Runnable action,
+                                                   Executor e) {
+        if (other == null || action == null) throw new NullPointerException();
+        CompletableFuture<Void> dst = new CompletableFuture<Void>();
+        RunAfterBoth d = null;
+        Object r, s = null;
+        if ((r = result) == null || (s = other.result) == null) {
+            d = new RunAfterBoth(this, other, action, dst, e);
+            CompletionNode q = null, p = new CompletionNode(d);
+            while ((r == null && (r = result) == null) ||
+                   (s == null && (s = other.result) == null)) {
+                if (q != null) {
+                    if (s != null ||
+                        UNSAFE.compareAndSwapObject
+                        (other, COMPLETIONS, q.next = other.completions, q))
+                        break;
+                }
+                else if (r != null ||
+                         UNSAFE.compareAndSwapObject
+                         (this, COMPLETIONS, p.next = completions, p)) {
+                    if (s != null)
+                        break;
+                    q = new CompletionNode(d);
+                }
+            }
+        }
+        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
+            Throwable ex;
+            if (r instanceof AltResult)
+                ex = ((AltResult)r).ex;
+            else
+                ex = null;
+            if (ex == null && (s instanceof AltResult))
+                ex = ((AltResult)s).ex;
+            if (ex == null) {
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncRun(action, dst));
+                    else
+                        action.run();
+                } catch (Throwable rex) {
+                    ex = rex;
+                }
+            }
+            if (e == null || ex != null)
+                dst.internalComplete(null, ex);
+        }
+        helpPostComplete();
+        other.helpPostComplete();
+        return dst;
+    }
+
+    private <U> CompletableFuture<U> doApplyToEither
+        (CompletableFuture<? extends T> other,
+         Function<? super T, U> fn,
+         Executor e) {
+        if (other == null || fn == null) throw new NullPointerException();
+        CompletableFuture<U> dst = new CompletableFuture<U>();
+        ApplyToEither<T,U> d = null;
+        Object r;
+        if ((r = result) == null && (r = other.result) == null) {
+            d = new ApplyToEither<T,U>(this, other, fn, dst, e);
+            CompletionNode q = null, p = new CompletionNode(d);
+            while ((r = result) == null && (r = other.result) == null) {
+                if (q != null) {
+                    if (UNSAFE.compareAndSwapObject
+                        (other, COMPLETIONS, q.next = other.completions, q))
+                        break;
+                }
+                else if (UNSAFE.compareAndSwapObject
+                         (this, COMPLETIONS, p.next = completions, p))
+                    q = new CompletionNode(d);
+            }
+        }
+        if (r != null && (d == null || d.compareAndSet(0, 1))) {
+            T t; Throwable ex;
+            if (r instanceof AltResult) {
+                ex = ((AltResult)r).ex;
+                t = null;
+            }
+            else {
+                ex = null;
+                @SuppressWarnings("unchecked") T tr = (T) r;
+                t = tr;
+            }
+            U u = null;
+            if (ex == null) {
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncApply<T,U>(t, fn, dst));
+                    else
+                        u = fn.apply(t);
+                } catch (Throwable rex) {
+                    ex = rex;
+                }
+            }
+            if (e == null || ex != null)
+                dst.internalComplete(u, ex);
+        }
+        helpPostComplete();
+        other.helpPostComplete();
+        return dst;
+    }
+
+    private CompletableFuture<Void> doAcceptEither
+        (CompletableFuture<? extends T> other,
+         Consumer<? super T> fn,
+         Executor e) {
+        if (other == null || fn == null) throw new NullPointerException();
+        CompletableFuture<Void> dst = new CompletableFuture<Void>();
+        AcceptEither<T> d = null;
+        Object r;
+        if ((r = result) == null && (r = other.result) == null) {
+            d = new AcceptEither<T>(this, other, fn, dst, e);
+            CompletionNode q = null, p = new CompletionNode(d);
+            while ((r = result) == null && (r = other.result) == null) {
+                if (q != null) {
+                    if (UNSAFE.compareAndSwapObject
+                        (other, COMPLETIONS, q.next = other.completions, q))
+                        break;
+                }
+                else if (UNSAFE.compareAndSwapObject
+                         (this, COMPLETIONS, p.next = completions, p))
+                    q = new CompletionNode(d);
+            }
+        }
+        if (r != null && (d == null || d.compareAndSet(0, 1))) {
+            T t; Throwable ex;
+            if (r instanceof AltResult) {
+                ex = ((AltResult)r).ex;
+                t = null;
+            }
+            else {
+                ex = null;
+                @SuppressWarnings("unchecked") T tr = (T) r;
+                t = tr;
+            }
+            if (ex == null) {
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncAccept<T>(t, fn, dst));
+                    else
+                        fn.accept(t);
+                } catch (Throwable rex) {
+                    ex = rex;
+                }
+            }
+            if (e == null || ex != null)
+                dst.internalComplete(null, ex);
+        }
+        helpPostComplete();
+        other.helpPostComplete();
+        return dst;
+    }
+
+    private CompletableFuture<Void> doRunAfterEither
+        (CompletableFuture<?> other,
+         Runnable action,
+         Executor e) {
+        if (other == null || action == null) throw new NullPointerException();
+        CompletableFuture<Void> dst = new CompletableFuture<Void>();
+        RunAfterEither d = null;
+        Object r;
+        if ((r = result) == null && (r = other.result) == null) {
+            d = new RunAfterEither(this, other, action, dst, e);
+            CompletionNode q = null, p = new CompletionNode(d);
+            while ((r = result) == null && (r = other.result) == null) {
+                if (q != null) {
+                    if (UNSAFE.compareAndSwapObject
+                        (other, COMPLETIONS, q.next = other.completions, q))
+                        break;
+                }
+                else if (UNSAFE.compareAndSwapObject
+                         (this, COMPLETIONS, p.next = completions, p))
+                    q = new CompletionNode(d);
+            }
+        }
+        if (r != null && (d == null || d.compareAndSet(0, 1))) {
+            Throwable ex;
+            if (r instanceof AltResult)
+                ex = ((AltResult)r).ex;
+            else
+                ex = null;
+            if (ex == null) {
+                try {
+                    if (e != null)
+                        execAsync(e, new AsyncRun(action, dst));
+                    else
+                        action.run();
+                } catch (Throwable rex) {
+                    ex = rex;
+                }
+            }
+            if (e == null || ex != null)
+                dst.internalComplete(null, ex);
+        }
+        helpPostComplete();
+        other.helpPostComplete();
+        return dst;
+    }
+
+    private <U> CompletableFuture<U> doThenCompose
+        (Function<? super T, ? extends CompletionStage<U>> fn,
+         Executor e) {
+        if (fn == null) throw new NullPointerException();
+        CompletableFuture<U> dst = null;
+        ThenCompose<T,U> d = null;
+        Object r;
+        if ((r = result) == null) {
+            dst = new CompletableFuture<U>();
+            CompletionNode p = new CompletionNode
+                (d = new ThenCompose<T,U>(this, fn, dst, e));
+            while ((r = result) == null) {
+                if (UNSAFE.compareAndSwapObject
+                    (this, COMPLETIONS, p.next = completions, p))
+                    break;
+            }
+        }
+        if (r != null && (d == null || d.compareAndSet(0, 1))) {
+            T t; Throwable ex;
+            if (r instanceof AltResult) {
+                ex = ((AltResult)r).ex;
+                t = null;
+            }
+            else {
+                ex = null;
+                @SuppressWarnings("unchecked") T tr = (T) r;
+                t = tr;
+            }
+            if (ex == null) {
+                if (e != null) {
+                    if (dst == null)
+                        dst = new CompletableFuture<U>();
+                    execAsync(e, new AsyncCompose<T,U>(t, fn, dst));
+                }
+                else {
+                    try {
+                        CompletionStage<U> cs = fn.apply(t);
+                        if (cs == null ||
+                            (dst = cs.toCompletableFuture()) == null)
+                            ex = new NullPointerException();
+                    } catch (Throwable rex) {
+                        ex = rex;
+                    }
+                }
+            }
+            if (dst == null)
+                dst = new CompletableFuture<U>();
+            if (e == null || ex != null)
+                dst.internalComplete(null, ex);
+        }
+        helpPostComplete();
+        dst.helpPostComplete();
+        return dst;
+    }
+
+    private CompletableFuture<T> doWhenComplete
+        (BiConsumer<? super T, ? super Throwable> fn,
+         Executor e) {
+        if (fn == null) throw new NullPointerException();
+        CompletableFuture<T> dst = new CompletableFuture<T>();
+        WhenCompleteCompletion<T> d = null;
+        Object r;
+        if ((r = result) == null) {
+            CompletionNode p =
+                new CompletionNode(d = new WhenCompleteCompletion<T>
+                                   (this, fn, dst, e));
+            while ((r = result) == null) {
+                if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
+                                                p.next = completions, p))
+                    break;
+            }
+        }
+        if (r != null && (d == null || d.compareAndSet(0, 1))) {
+            T t; Throwable ex;
+            if (r instanceof AltResult) {
+                ex = ((AltResult)r).ex;
+                t = null;
+            }
+            else {
+                ex = null;
+                @SuppressWarnings("unchecked") T tr = (T) r;
+                t = tr;
+            }
+            Throwable dx = null;
+            try {
+                if (e != null)
+                    execAsync(e, new AsyncWhenComplete<T>(t, ex, fn, dst));
+                else
+                    fn.accept(t, ex);
+            } catch (Throwable rex) {
+                dx = rex;
+            }
+            if (e == null || dx != null)
+                dst.internalComplete(t, ex != null ? ex : dx);
+        }
+        helpPostComplete();
+        return dst;
+    }
+
+    private <U> CompletableFuture<U> doHandle
+        (BiFunction<? super T, Throwable, ? extends U> fn,
+         Executor e) {
+        if (fn == null) throw new NullPointerException();
+        CompletableFuture<U> dst = new CompletableFuture<U>();
+        HandleCompletion<T,U> d = null;
+        Object r;
+        if ((r = result) == null) {
+            CompletionNode p =
+                new CompletionNode(d = new HandleCompletion<T,U>
+                                   (this, fn, dst, e));
+            while ((r = result) == null) {
+                if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
+                                                p.next = completions, p))
+                    break;
+            }
+        }
+        if (r != null && (d == null || d.compareAndSet(0, 1))) {
+            T t; Throwable ex;
+            if (r instanceof AltResult) {
+                ex = ((AltResult)r).ex;
+                t = null;
+            }
+            else {
+                ex = null;
+                @SuppressWarnings("unchecked") T tr = (T) r;
+                t = tr;
+            }
+            U u = null;
+            Throwable dx = null;
+            try {
+                if (e != null)
+                    execAsync(e, new AsyncCombine<T,Throwable,U>(t, ex, fn, dst));
+                else {
+                    u = fn.apply(t, ex);
+                    dx = null;
+                }
+            } catch (Throwable rex) {
+                dx = rex;
+                u = null;
+            }
+            if (e == null || dx != null)
+                dst.internalComplete(u, dx);
+        }
+        helpPostComplete();
+        return dst;
+    }
+
+
     // public methods
 
     /**
@@ -1416,13 +2118,13 @@
      *
      * @param supplier a function returning the value to be used
      * to complete the returned CompletableFuture
+     * @param <U> the function's return type
      * @return the new CompletableFuture
      */
     public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
         if (supplier == null) throw new NullPointerException();
         CompletableFuture<U> f = new CompletableFuture<U>();
-        ForkJoinPool.commonPool().
-            execute((ForkJoinTask<?>)new AsyncSupply<U>(supplier, f));
+        execAsync(ForkJoinPool.commonPool(), new AsyncSupply<U>(supplier, f));
         return f;
     }
 
@@ -1434,6 +2136,7 @@
      * @param supplier a function returning the value to be used
      * to complete the returned CompletableFuture
      * @param executor the executor to use for asynchronous execution
+     * @param <U> the function's return type
      * @return the new CompletableFuture
      */
     public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
@@ -1441,7 +2144,7 @@
         if (executor == null || supplier == null)
             throw new NullPointerException();
         CompletableFuture<U> f = new CompletableFuture<U>();
-        executor.execute(new AsyncSupply<U>(supplier, f));
+        execAsync(executor, new AsyncSupply<U>(supplier, f));
         return f;
     }
 
@@ -1457,8 +2160,7 @@
     public static CompletableFuture<Void> runAsync(Runnable runnable) {
         if (runnable == null) throw new NullPointerException();
         CompletableFuture<Void> f = new CompletableFuture<Void>();
-        ForkJoinPool.commonPool().
-            execute((ForkJoinTask<?>)new AsyncRun(runnable, f));
+        execAsync(ForkJoinPool.commonPool(), new AsyncRun(runnable, f));
         return f;
     }
 
@@ -1477,7 +2179,7 @@
         if (executor == null || runnable == null)
             throw new NullPointerException();
         CompletableFuture<Void> f = new CompletableFuture<Void>();
-        executor.execute(new AsyncRun(runnable, f));
+        execAsync(executor, new AsyncRun(runnable, f));
         return f;
     }
 
@@ -1486,6 +2188,7 @@
      * the given value.
      *
      * @param value the value
+     * @param <U> the type of the value
      * @return the completed CompletableFuture
      */
     public static <U> CompletableFuture<U> completedFuture(U value) {
@@ -1657,60 +2360,18 @@
         return triggered;
     }
 
-    /**
-     * Returns a new CompletableFuture that is completed
-     * when this CompletableFuture completes, with the result of the
-     * given function of this CompletableFuture's result.
-     *
-     * <p>If this CompletableFuture completes exceptionally, or the
-     * supplied function throws an exception, then the returned
-     * CompletableFuture completes exceptionally with a
-     * CompletionException holding the exception as its cause.
-     *
-     * @param fn the function to use to compute the value of
-     * the returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) {
+    // CompletionStage methods
+
+    public <U> CompletableFuture<U> thenApply
+        (Function<? super T,? extends U> fn) {
         return doThenApply(fn, null);
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when this CompletableFuture completes, with the result of the
-     * given function of this CompletableFuture's result from a
-     * task running in the {@link ForkJoinPool#commonPool()}.
-     *
-     * <p>If this CompletableFuture completes exceptionally, or the
-     * supplied function throws an exception, then the returned
-     * CompletableFuture completes exceptionally with a
-     * CompletionException holding the exception as its cause.
-     *
-     * @param fn the function to use to compute the value of
-     * the returned CompletableFuture
-     * @return the new CompletableFuture
-     */
     public <U> CompletableFuture<U> thenApplyAsync
         (Function<? super T,? extends U> fn) {
         return doThenApply(fn, ForkJoinPool.commonPool());
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when this CompletableFuture completes, with the result of the
-     * given function of this CompletableFuture's result from a
-     * task running in the given executor.
-     *
-     * <p>If this CompletableFuture completes exceptionally, or the
-     * supplied function throws an exception, then the returned
-     * CompletableFuture completes exceptionally with a
-     * CompletionException holding the exception as its cause.
-     *
-     * @param fn the function to use to compute the value of
-     * the returned CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the new CompletableFuture
-     */
     public <U> CompletableFuture<U> thenApplyAsync
         (Function<? super T,? extends U> fn,
          Executor executor) {
@@ -1718,1149 +2379,228 @@
         return doThenApply(fn, executor);
     }
 
-    private <U> CompletableFuture<U> doThenApply
-        (Function<? super T,? extends U> fn,
-         Executor e) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<U> dst = new CompletableFuture<U>();
-        ThenApply<T,U> d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p = new CompletionNode
-                (d = new ThenApply<T,U>(this, fn, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (this, COMPLETIONS, p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            U u = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        e.execute(new AsyncApply<T,U>(t, fn, dst));
-                    else
-                        u = fn.apply(t);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(u, ex);
-        }
-        helpPostComplete();
-        return dst;
+    public CompletableFuture<Void> thenAccept
+        (Consumer<? super T> action) {
+        return doThenAccept(action, null);
     }
 
-    /**
-     * Returns a new CompletableFuture that is completed
-     * when this CompletableFuture completes, after performing the given
-     * action with this CompletableFuture's result.
-     *
-     * <p>If this CompletableFuture completes exceptionally, or the
-     * supplied action throws an exception, then the returned
-     * CompletableFuture completes exceptionally with a
-     * CompletionException holding the exception as its cause.
-     *
-     * @param block the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> thenAccept(Consumer<? super T> block) {
-        return doThenAccept(block, null);
+    public CompletableFuture<Void> thenAcceptAsync
+        (Consumer<? super T> action) {
+        return doThenAccept(action, ForkJoinPool.commonPool());
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when this CompletableFuture completes, after performing the given
-     * action with this CompletableFuture's result from a task running
-     * in the {@link ForkJoinPool#commonPool()}.
-     *
-     * <p>If this CompletableFuture completes exceptionally, or the
-     * supplied action throws an exception, then the returned
-     * CompletableFuture completes exceptionally with a
-     * CompletionException holding the exception as its cause.
-     *
-     * @param block the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> block) {
-        return doThenAccept(block, ForkJoinPool.commonPool());
+    public CompletableFuture<Void> thenAcceptAsync
+        (Consumer<? super T> action,
+         Executor executor) {
+        if (executor == null) throw new NullPointerException();
+        return doThenAccept(action, executor);
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when this CompletableFuture completes, after performing the given
-     * action with this CompletableFuture's result from a task running
-     * in the given executor.
-     *
-     * <p>If this CompletableFuture completes exceptionally, or the
-     * supplied action throws an exception, then the returned
-     * CompletableFuture completes exceptionally with a
-     * CompletionException holding the exception as its cause.
-     *
-     * @param block the action to perform before completing the
-     * returned CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> block,
-                                                   Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doThenAccept(block, executor);
-    }
-
-    private CompletableFuture<Void> doThenAccept(Consumer<? super T> fn,
-                                                 Executor e) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        ThenAccept<T> d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p = new CompletionNode
-                (d = new ThenAccept<T>(this, fn, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (this, COMPLETIONS, p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        e.execute(new AsyncAccept<T>(t, fn, dst));
-                    else
-                        fn.accept(t);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        return dst;
-    }
-
-    /**
-     * Returns a new CompletableFuture that is completed
-     * when this CompletableFuture completes, after performing the given
-     * action.
-     *
-     * <p>If this CompletableFuture completes exceptionally, or the
-     * supplied action throws an exception, then the returned
-     * CompletableFuture completes exceptionally with a
-     * CompletionException holding the exception as its cause.
-     *
-     * @param action the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> thenRun(Runnable action) {
+    public CompletableFuture<Void> thenRun
+        (Runnable action) {
         return doThenRun(action, null);
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when this CompletableFuture completes, after performing the given
-     * action from a task running in the {@link ForkJoinPool#commonPool()}.
-     *
-     * <p>If this CompletableFuture completes exceptionally, or the
-     * supplied action throws an exception, then the returned
-     * CompletableFuture completes exceptionally with a
-     * CompletionException holding the exception as its cause.
-     *
-     * @param action the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> thenRunAsync(Runnable action) {
+    public CompletableFuture<Void> thenRunAsync
+        (Runnable action) {
         return doThenRun(action, ForkJoinPool.commonPool());
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when this CompletableFuture completes, after performing the given
-     * action from a task running in the given executor.
-     *
-     * <p>If this CompletableFuture completes exceptionally, or the
-     * supplied action throws an exception, then the returned
-     * CompletableFuture completes exceptionally with a
-     * CompletionException holding the exception as its cause.
-     *
-     * @param action the action to perform before completing the
-     * returned CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> thenRunAsync(Runnable action,
-                                                Executor executor) {
+    public CompletableFuture<Void> thenRunAsync
+        (Runnable action,
+         Executor executor) {
         if (executor == null) throw new NullPointerException();
         return doThenRun(action, executor);
     }
 
-    private CompletableFuture<Void> doThenRun(Runnable action,
-                                              Executor e) {
-        if (action == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        ThenRun d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p = new CompletionNode
-                (d = new ThenRun(this, action, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (this, COMPLETIONS, p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            Throwable ex;
-            if (r instanceof AltResult)
-                ex = ((AltResult)r).ex;
-            else
-                ex = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        e.execute(new AsyncRun(action, dst));
-                    else
-                        action.run();
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        return dst;
+    public <U,V> CompletableFuture<V> thenCombine
+        (CompletionStage<? extends U> other,
+         BiFunction<? super T,? super U,? extends V> fn) {
+        return doThenCombine(other.toCompletableFuture(), fn, null);
     }
 
-    /**
-     * Returns a new CompletableFuture that is completed
-     * when both this and the other given CompletableFuture complete,
-     * with the result of the given function of the results of the two
-     * CompletableFutures.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, or the supplied function throws an exception,
-     * then the returned CompletableFuture completes exceptionally
-     * with a CompletionException holding the exception as its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param fn the function to use to compute the value of
-     * the returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public <U,V> CompletableFuture<V> thenCombine
-        (CompletableFuture<? extends U> other,
+    public <U,V> CompletableFuture<V> thenCombineAsync
+        (CompletionStage<? extends U> other,
          BiFunction<? super T,? super U,? extends V> fn) {
-        return doThenCombine(other, fn, null);
+        return doThenCombine(other.toCompletableFuture(), fn,
+                             ForkJoinPool.commonPool());
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when both this and the other given CompletableFuture complete,
-     * with the result of the given function of the results of the two
-     * CompletableFutures from a task running in the
-     * {@link ForkJoinPool#commonPool()}.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, or the supplied function throws an exception,
-     * then the returned CompletableFuture completes exceptionally
-     * with a CompletionException holding the exception as its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param fn the function to use to compute the value of
-     * the returned CompletableFuture
-     * @return the new CompletableFuture
-     */
     public <U,V> CompletableFuture<V> thenCombineAsync
-        (CompletableFuture<? extends U> other,
-         BiFunction<? super T,? super U,? extends V> fn) {
-        return doThenCombine(other, fn, ForkJoinPool.commonPool());
-    }
-
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when both this and the other given CompletableFuture complete,
-     * with the result of the given function of the results of the two
-     * CompletableFutures from a task running in the given executor.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, or the supplied function throws an exception,
-     * then the returned CompletableFuture completes exceptionally
-     * with a CompletionException holding the exception as its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param fn the function to use to compute the value of
-     * the returned CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the new CompletableFuture
-     */
-    public <U,V> CompletableFuture<V> thenCombineAsync
-        (CompletableFuture<? extends U> other,
+        (CompletionStage<? extends U> other,
          BiFunction<? super T,? super U,? extends V> fn,
          Executor executor) {
         if (executor == null) throw new NullPointerException();
-        return doThenCombine(other, fn, executor);
+        return doThenCombine(other.toCompletableFuture(), fn, executor);
     }
 
-    private <U,V> CompletableFuture<V> doThenCombine
-        (CompletableFuture<? extends U> other,
-         BiFunction<? super T,? super U,? extends V> fn,
-         Executor e) {
-        if (other == null || fn == null) throw new NullPointerException();
-        CompletableFuture<V> dst = new CompletableFuture<V>();
-        ThenCombine<T,U,V> d = null;
-        Object r, s = null;
-        if ((r = result) == null || (s = other.result) == null) {
-            d = new ThenCombine<T,U,V>(this, other, fn, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r == null && (r = result) == null) ||
-                   (s == null && (s = other.result) == null)) {
-                if (q != null) {
-                    if (s != null ||
-                        UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (r != null ||
-                         UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p)) {
-                    if (s != null)
-                        break;
-                    q = new CompletionNode(d);
-                }
-            }
-        }
-        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; U u; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex != null)
-                u = null;
-            else if (s instanceof AltResult) {
-                ex = ((AltResult)s).ex;
-                u = null;
-            }
-            else {
-                @SuppressWarnings("unchecked") U us = (U) s;
-                u = us;
-            }
-            V v = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        e.execute(new AsyncCombine<T,U,V>(t, u, fn, dst));
-                    else
-                        v = fn.apply(t, u);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(v, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
+    public <U> CompletableFuture<Void> thenAcceptBoth
+        (CompletionStage<? extends U> other,
+         BiConsumer<? super T, ? super U> action) {
+        return doThenAcceptBoth(other.toCompletableFuture(), action, null);
     }
 
-    /**
-     * Returns a new CompletableFuture that is completed
-     * when both this and the other given CompletableFuture complete,
-     * after performing the given action with the results of the two
-     * CompletableFutures.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, or the supplied action throws an exception,
-     * then the returned CompletableFuture completes exceptionally
-     * with a CompletionException holding the exception as its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param block the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public <U> CompletableFuture<Void> thenAcceptBoth
-        (CompletableFuture<? extends U> other,
-         BiConsumer<? super T, ? super U> block) {
-        return doThenAcceptBoth(other, block, null);
+    public <U> CompletableFuture<Void> thenAcceptBothAsync
+        (CompletionStage<? extends U> other,
+         BiConsumer<? super T, ? super U> action) {
+        return doThenAcceptBoth(other.toCompletableFuture(), action,
+                                ForkJoinPool.commonPool());
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when both this and the other given CompletableFuture complete,
-     * after performing the given action with the results of the two
-     * CompletableFutures from a task running in the {@link
-     * ForkJoinPool#commonPool()}.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, or the supplied action throws an exception,
-     * then the returned CompletableFuture completes exceptionally
-     * with a CompletionException holding the exception as its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param block the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
     public <U> CompletableFuture<Void> thenAcceptBothAsync
-        (CompletableFuture<? extends U> other,
-         BiConsumer<? super T, ? super U> block) {
-        return doThenAcceptBoth(other, block, ForkJoinPool.commonPool());
+        (CompletionStage<? extends U> other,
+         BiConsumer<? super T, ? super U> action,
+         Executor executor) {
+        if (executor == null) throw new NullPointerException();
+        return doThenAcceptBoth(other.toCompletableFuture(), action, executor);
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when both this and the other given CompletableFuture complete,
-     * after performing the given action with the results of the two
-     * CompletableFutures from a task running in the given executor.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, or the supplied action throws an exception,
-     * then the returned CompletableFuture completes exceptionally
-     * with a CompletionException holding the exception as its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param block the action to perform before completing the
-     * returned CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the new CompletableFuture
-     */
-    public <U> CompletableFuture<Void> thenAcceptBothAsync
-        (CompletableFuture<? extends U> other,
-         BiConsumer<? super T, ? super U> block,
+    public CompletableFuture<Void> runAfterBoth
+        (CompletionStage<?> other,
+         Runnable action) {
+        return doRunAfterBoth(other.toCompletableFuture(), action, null);
+    }
+
+    public CompletableFuture<Void> runAfterBothAsync
+        (CompletionStage<?> other,
+         Runnable action) {
+        return doRunAfterBoth(other.toCompletableFuture(), action,
+                              ForkJoinPool.commonPool());
+    }
+
+    public CompletableFuture<Void> runAfterBothAsync
+        (CompletionStage<?> other,
+         Runnable action,
          Executor executor) {
         if (executor == null) throw new NullPointerException();
-        return doThenAcceptBoth(other, block, executor);
+        return doRunAfterBoth(other.toCompletableFuture(), action, executor);
     }
 
-    private <U> CompletableFuture<Void> doThenAcceptBoth
-        (CompletableFuture<? extends U> other,
-         BiConsumer<? super T,? super U> fn,
-         Executor e) {
-        if (other == null || fn == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        ThenAcceptBoth<T,U> d = null;
-        Object r, s = null;
-        if ((r = result) == null || (s = other.result) == null) {
-            d = new ThenAcceptBoth<T,U>(this, other, fn, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r == null && (r = result) == null) ||
-                   (s == null && (s = other.result) == null)) {
-                if (q != null) {
-                    if (s != null ||
-                        UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (r != null ||
-                         UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p)) {
-                    if (s != null)
-                        break;
-                    q = new CompletionNode(d);
-                }
-            }
-        }
-        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; U u; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex != null)
-                u = null;
-            else if (s instanceof AltResult) {
-                ex = ((AltResult)s).ex;
-                u = null;
-            }
-            else {
-                @SuppressWarnings("unchecked") U us = (U) s;
-                u = us;
-            }
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        e.execute(new AsyncAcceptBoth<T,U>(t, u, fn, dst));
-                    else
-                        fn.accept(t, u);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
+
+    public <U> CompletableFuture<U> applyToEither
+        (CompletionStage<? extends T> other,
+         Function<? super T, U> fn) {
+        return doApplyToEither(other.toCompletableFuture(), fn, null);
     }
 
-    /**
-     * Returns a new CompletableFuture that is completed
-     * when both this and the other given CompletableFuture complete,
-     * after performing the given action.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, or the supplied action throws an exception,
-     * then the returned CompletableFuture completes exceptionally
-     * with a CompletionException holding the exception as its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param action the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> runAfterBoth(CompletableFuture<?> other,
-                                                Runnable action) {
-        return doRunAfterBoth(other, action, null);
+    public <U> CompletableFuture<U> applyToEitherAsync
+        (CompletionStage<? extends T> other,
+         Function<? super T, U> fn) {
+        return doApplyToEither(other.toCompletableFuture(), fn,
+                               ForkJoinPool.commonPool());
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when both this and the other given CompletableFuture complete,
-     * after performing the given action from a task running in the
-     * {@link ForkJoinPool#commonPool()}.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, or the supplied action throws an exception,
-     * then the returned CompletableFuture completes exceptionally
-     * with a CompletionException holding the exception as its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param action the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> runAfterBothAsync(CompletableFuture<?> other,
-                                                     Runnable action) {
-        return doRunAfterBoth(other, action, ForkJoinPool.commonPool());
-    }
-
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when both this and the other given CompletableFuture complete,
-     * after performing the given action from a task running in the
-     * given executor.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, or the supplied action throws an exception,
-     * then the returned CompletableFuture completes exceptionally
-     * with a CompletionException holding the exception as its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param action the action to perform before completing the
-     * returned CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> runAfterBothAsync(CompletableFuture<?> other,
-                                                     Runnable action,
-                                                     Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doRunAfterBoth(other, action, executor);
-    }
-
-    private CompletableFuture<Void> doRunAfterBoth(CompletableFuture<?> other,
-                                                   Runnable action,
-                                                   Executor e) {
-        if (other == null || action == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        RunAfterBoth d = null;
-        Object r, s = null;
-        if ((r = result) == null || (s = other.result) == null) {
-            d = new RunAfterBoth(this, other, action, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r == null && (r = result) == null) ||
-                   (s == null && (s = other.result) == null)) {
-                if (q != null) {
-                    if (s != null ||
-                        UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (r != null ||
-                         UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p)) {
-                    if (s != null)
-                        break;
-                    q = new CompletionNode(d);
-                }
-            }
-        }
-        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
-            Throwable ex;
-            if (r instanceof AltResult)
-                ex = ((AltResult)r).ex;
-            else
-                ex = null;
-            if (ex == null && (s instanceof AltResult))
-                ex = ((AltResult)s).ex;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        e.execute(new AsyncRun(action, dst));
-                    else
-                        action.run();
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
-    }
-
-    /**
-     * Returns a new CompletableFuture that is completed
-     * when either this or the other given CompletableFuture completes,
-     * with the result of the given function of either this or the other
-     * CompletableFuture's result.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, then the returned CompletableFuture may also do so,
-     * with a CompletionException holding one of these exceptions as its
-     * cause.  No guarantees are made about which result or exception is
-     * used in the returned CompletableFuture.  If the supplied function
-     * throws an exception, then the returned CompletableFuture completes
-     * exceptionally with a CompletionException holding the exception as
-     * its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param fn the function to use to compute the value of
-     * the returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public <U> CompletableFuture<U> applyToEither
-        (CompletableFuture<? extends T> other,
-         Function<? super T, U> fn) {
-        return doApplyToEither(other, fn, null);
-    }
-
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when either this or the other given CompletableFuture completes,
-     * with the result of the given function of either this or the other
-     * CompletableFuture's result from a task running in the
-     * {@link ForkJoinPool#commonPool()}.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, then the returned CompletableFuture may also do so,
-     * with a CompletionException holding one of these exceptions as its
-     * cause.  No guarantees are made about which result or exception is
-     * used in the returned CompletableFuture.  If the supplied function
-     * throws an exception, then the returned CompletableFuture completes
-     * exceptionally with a CompletionException holding the exception as
-     * its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param fn the function to use to compute the value of
-     * the returned CompletableFuture
-     * @return the new CompletableFuture
-     */
     public <U> CompletableFuture<U> applyToEitherAsync
-        (CompletableFuture<? extends T> other,
-         Function<? super T, U> fn) {
-        return doApplyToEither(other, fn, ForkJoinPool.commonPool());
-    }
-
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when either this or the other given CompletableFuture completes,
-     * with the result of the given function of either this or the other
-     * CompletableFuture's result from a task running in the
-     * given executor.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, then the returned CompletableFuture may also do so,
-     * with a CompletionException holding one of these exceptions as its
-     * cause.  No guarantees are made about which result or exception is
-     * used in the returned CompletableFuture.  If the supplied function
-     * throws an exception, then the returned CompletableFuture completes
-     * exceptionally with a CompletionException holding the exception as
-     * its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param fn the function to use to compute the value of
-     * the returned CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the new CompletableFuture
-     */
-    public <U> CompletableFuture<U> applyToEitherAsync
-        (CompletableFuture<? extends T> other,
+        (CompletionStage<? extends T> other,
          Function<? super T, U> fn,
          Executor executor) {
         if (executor == null) throw new NullPointerException();
-        return doApplyToEither(other, fn, executor);
+        return doApplyToEither(other.toCompletableFuture(), fn, executor);
     }
 
-    private <U> CompletableFuture<U> doApplyToEither
-        (CompletableFuture<? extends T> other,
-         Function<? super T, U> fn,
-         Executor e) {
-        if (other == null || fn == null) throw new NullPointerException();
-        CompletableFuture<U> dst = new CompletableFuture<U>();
-        ApplyToEither<T,U> d = null;
-        Object r;
-        if ((r = result) == null && (r = other.result) == null) {
-            d = new ApplyToEither<T,U>(this, other, fn, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r = result) == null && (r = other.result) == null) {
-                if (q != null) {
-                    if (UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p))
-                    q = new CompletionNode(d);
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            U u = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        e.execute(new AsyncApply<T,U>(t, fn, dst));
-                    else
-                        u = fn.apply(t);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(u, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
+    public CompletableFuture<Void> acceptEither
+        (CompletionStage<? extends T> other,
+         Consumer<? super T> action) {
+        return doAcceptEither(other.toCompletableFuture(), action, null);
     }
 
-    /**
-     * Returns a new CompletableFuture that is completed
-     * when either this or the other given CompletableFuture completes,
-     * after performing the given action with the result of either this
-     * or the other CompletableFuture's result.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, then the returned CompletableFuture may also do so,
-     * with a CompletionException holding one of these exceptions as its
-     * cause.  No guarantees are made about which result or exception is
-     * used in the returned CompletableFuture.  If the supplied action
-     * throws an exception, then the returned CompletableFuture completes
-     * exceptionally with a CompletionException holding the exception as
-     * its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param block the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> acceptEither
-        (CompletableFuture<? extends T> other,
-         Consumer<? super T> block) {
-        return doAcceptEither(other, block, null);
+    public CompletableFuture<Void> acceptEitherAsync
+        (CompletionStage<? extends T> other,
+         Consumer<? super T> action) {
+        return doAcceptEither(other.toCompletableFuture(), action,
+                              ForkJoinPool.commonPool());
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when either this or the other given CompletableFuture completes,
-     * after performing the given action with the result of either this
-     * or the other CompletableFuture's result from a task running in
-     * the {@link ForkJoinPool#commonPool()}.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, then the returned CompletableFuture may also do so,
-     * with a CompletionException holding one of these exceptions as its
-     * cause.  No guarantees are made about which result or exception is
-     * used in the returned CompletableFuture.  If the supplied action
-     * throws an exception, then the returned CompletableFuture completes
-     * exceptionally with a CompletionException holding the exception as
-     * its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param block the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
     public CompletableFuture<Void> acceptEitherAsync
-        (CompletableFuture<? extends T> other,
-         Consumer<? super T> block) {
-        return doAcceptEither(other, block, ForkJoinPool.commonPool());
+        (CompletionStage<? extends T> other,
+         Consumer<? super T> action,
+         Executor executor) {
+        if (executor == null) throw new NullPointerException();
+        return doAcceptEither(other.toCompletableFuture(), action, executor);
     }
 
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when either this or the other given CompletableFuture completes,
-     * after performing the given action with the result of either this
-     * or the other CompletableFuture's result from a task running in
-     * the given executor.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, then the returned CompletableFuture may also do so,
-     * with a CompletionException holding one of these exceptions as its
-     * cause.  No guarantees are made about which result or exception is
-     * used in the returned CompletableFuture.  If the supplied action
-     * throws an exception, then the returned CompletableFuture completes
-     * exceptionally with a CompletionException holding the exception as
-     * its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param block the action to perform before completing the
-     * returned CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> acceptEitherAsync
-        (CompletableFuture<? extends T> other,
-         Consumer<? super T> block,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doAcceptEither(other, block, executor);
+    public CompletableFuture<Void> runAfterEither(CompletionStage<?> other,
+                                                  Runnable action) {
+        return doRunAfterEither(other.toCompletableFuture(), action, null);
     }
 
-    private CompletableFuture<Void> doAcceptEither
-        (CompletableFuture<? extends T> other,
-         Consumer<? super T> fn,
-         Executor e) {
-        if (other == null || fn == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        AcceptEither<T> d = null;
-        Object r;
-        if ((r = result) == null && (r = other.result) == null) {
-            d = new AcceptEither<T>(this, other, fn, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r = result) == null && (r = other.result) == null) {
-                if (q != null) {
-                    if (UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p))
-                    q = new CompletionNode(d);
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        e.execute(new AsyncAccept<T>(t, fn, dst));
-                    else
-                        fn.accept(t);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
+    public CompletableFuture<Void> runAfterEitherAsync
+        (CompletionStage<?> other,
+         Runnable action) {
+        return doRunAfterEither(other.toCompletableFuture(), action,
+                                ForkJoinPool.commonPool());
     }
 
-    /**
-     * Returns a new CompletableFuture that is completed
-     * when either this or the other given CompletableFuture completes,
-     * after performing the given action.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, then the returned CompletableFuture may also do so,
-     * with a CompletionException holding one of these exceptions as its
-     * cause.  No guarantees are made about which result or exception is
-     * used in the returned CompletableFuture.  If the supplied action
-     * throws an exception, then the returned CompletableFuture completes
-     * exceptionally with a CompletionException holding the exception as
-     * its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param action the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> runAfterEither(CompletableFuture<?> other,
-                                                  Runnable action) {
-        return doRunAfterEither(other, action, null);
-    }
-
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when either this or the other given CompletableFuture completes,
-     * after performing the given action from a task running in the
-     * {@link ForkJoinPool#commonPool()}.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, then the returned CompletableFuture may also do so,
-     * with a CompletionException holding one of these exceptions as its
-     * cause.  No guarantees are made about which result or exception is
-     * used in the returned CompletableFuture.  If the supplied action
-     * throws an exception, then the returned CompletableFuture completes
-     * exceptionally with a CompletionException holding the exception as
-     * its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param action the action to perform before completing the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
     public CompletableFuture<Void> runAfterEitherAsync
-        (CompletableFuture<?> other,
-         Runnable action) {
-        return doRunAfterEither(other, action, ForkJoinPool.commonPool());
-    }
-
-    /**
-     * Returns a new CompletableFuture that is asynchronously completed
-     * when either this or the other given CompletableFuture completes,
-     * after performing the given action from a task running in the
-     * given executor.
-     *
-     * <p>If this and/or the other CompletableFuture complete
-     * exceptionally, then the returned CompletableFuture may also do so,
-     * with a CompletionException holding one of these exceptions as its
-     * cause.  No guarantees are made about which result or exception is
-     * used in the returned CompletableFuture.  If the supplied action
-     * throws an exception, then the returned CompletableFuture completes
-     * exceptionally with a CompletionException holding the exception as
-     * its cause.
-     *
-     * @param other the other CompletableFuture
-     * @param action the action to perform before completing the
-     * returned CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the new CompletableFuture
-     */
-    public CompletableFuture<Void> runAfterEitherAsync
-        (CompletableFuture<?> other,
+        (CompletionStage<?> other,
          Runnable action,
          Executor executor) {
         if (executor == null) throw new NullPointerException();
-        return doRunAfterEither(other, action, executor);
+        return doRunAfterEither(other.toCompletableFuture(), action, executor);
     }
 
-    private CompletableFuture<Void> doRunAfterEither
-        (CompletableFuture<?> other,
-         Runnable action,
-         Executor e) {
-        if (other == null || action == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        RunAfterEither d = null;
-        Object r;
-        if ((r = result) == null && (r = other.result) == null) {
-            d = new RunAfterEither(this, other, action, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r = result) == null && (r = other.result) == null) {
-                if (q != null) {
-                    if (UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p))
-                    q = new CompletionNode(d);
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            Throwable ex;
-            if (r instanceof AltResult)
-                ex = ((AltResult)r).ex;
-            else
-                ex = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        e.execute(new AsyncRun(action, dst));
-                    else
-                        action.run();
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
-    }
-
-    /**
-     * Returns a CompletableFuture that upon completion, has the same
-     * value as produced by the given function of the result of this
-     * CompletableFuture.
-     *
-     * <p>If this CompletableFuture completes exceptionally, then the
-     * returned CompletableFuture also does so, with a
-     * CompletionException holding this exception as its cause.
-     * Similarly, if the computed CompletableFuture completes
-     * exceptionally, then so does the returned CompletableFuture.
-     *
-     * @param fn the function returning a new CompletableFuture
-     * @return the CompletableFuture
-     */
     public <U> CompletableFuture<U> thenCompose
-        (Function<? super T, CompletableFuture<U>> fn) {
+        (Function<? super T, ? extends CompletionStage<U>> fn) {
         return doThenCompose(fn, null);
     }
 
-    /**
-     * Returns a CompletableFuture that upon completion, has the same
-     * value as that produced asynchronously using the {@link
-     * ForkJoinPool#commonPool()} by the given function of the result
-     * of this CompletableFuture.
-     *
-     * <p>If this CompletableFuture completes exceptionally, then the
-     * returned CompletableFuture also does so, with a
-     * CompletionException holding this exception as its cause.
-     * Similarly, if the computed CompletableFuture completes
-     * exceptionally, then so does the returned CompletableFuture.
-     *
-     * @param fn the function returning a new CompletableFuture
-     * @return the CompletableFuture
-     */
     public <U> CompletableFuture<U> thenComposeAsync
-        (Function<? super T, CompletableFuture<U>> fn) {
+        (Function<? super T, ? extends CompletionStage<U>> fn) {
         return doThenCompose(fn, ForkJoinPool.commonPool());
     }
 
-    /**
-     * Returns a CompletableFuture that upon completion, has the same
-     * value as that produced asynchronously using the given executor
-     * by the given function of this CompletableFuture.
-     *
-     * <p>If this CompletableFuture completes exceptionally, then the
-     * returned CompletableFuture also does so, with a
-     * CompletionException holding this exception as its cause.
-     * Similarly, if the computed CompletableFuture completes
-     * exceptionally, then so does the returned CompletableFuture.
-     *
-     * @param fn the function returning a new CompletableFuture
-     * @param executor the executor to use for asynchronous execution
-     * @return the CompletableFuture
-     */
     public <U> CompletableFuture<U> thenComposeAsync
-        (Function<? super T, CompletableFuture<U>> fn,
+        (Function<? super T, ? extends CompletionStage<U>> fn,
          Executor executor) {
         if (executor == null) throw new NullPointerException();
         return doThenCompose(fn, executor);
     }
 
-    private <U> CompletableFuture<U> doThenCompose
-        (Function<? super T, CompletableFuture<U>> fn,
-         Executor e) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<U> dst = null;
-        ThenCompose<T,U> d = null;
-        Object r;
-        if ((r = result) == null) {
-            dst = new CompletableFuture<U>();
-            CompletionNode p = new CompletionNode
-                (d = new ThenCompose<T,U>(this, fn, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (this, COMPLETIONS, p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex == null) {
-                if (e != null) {
-                    if (dst == null)
-                        dst = new CompletableFuture<U>();
-                    e.execute(new AsyncCompose<T,U>(t, fn, dst));
-                }
-                else {
-                    try {
-                        if ((dst = fn.apply(t)) == null)
-                            ex = new NullPointerException();
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-            }
-            if (dst == null)
-                dst = new CompletableFuture<U>();
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        dst.helpPostComplete();
-        return dst;
+    public CompletableFuture<T> whenComplete
+        (BiConsumer<? super T, ? super Throwable> action) {
+        return doWhenComplete(action, null);
     }
 
+    public CompletableFuture<T> whenCompleteAsync
+        (BiConsumer<? super T, ? super Throwable> action) {
+        return doWhenComplete(action, ForkJoinPool.commonPool());
+    }
+
+    public CompletableFuture<T> whenCompleteAsync
+        (BiConsumer<? super T, ? super Throwable> action,
+         Executor executor) {
+        if (executor == null) throw new NullPointerException();
+        return doWhenComplete(action, executor);
+    }
+
+    public <U> CompletableFuture<U> handle
+        (BiFunction<? super T, Throwable, ? extends U> fn) {
+        return doHandle(fn, null);
+    }
+
+    public <U> CompletableFuture<U> handleAsync
+        (BiFunction<? super T, Throwable, ? extends U> fn) {
+        return doHandle(fn, ForkJoinPool.commonPool());
+    }
+
+    public <U> CompletableFuture<U> handleAsync
+        (BiFunction<? super T, Throwable, ? extends U> fn,
+         Executor executor) {
+        if (executor == null) throw new NullPointerException();
+        return doHandle(fn, executor);
+    }
+
+    /**
+     * Returns this CompletableFuture
+     *
+     * @return this CompletableFuture
+     */
+    public CompletableFuture<T> toCompletableFuture() {
+        return this;
+    }
+
+    // not in interface CompletionStage
+
     /**
      * Returns a new CompletableFuture that is completed when this
      * CompletableFuture completes, with the result of the given
@@ -2868,6 +2608,8 @@
      * completion when it completes exceptionally; otherwise, if this
      * CompletableFuture completes normally, then the returned
      * CompletableFuture also completes normally with the same value.
+     * Note: More flexible versions of this functionality are
+     * available using methods {@code whenComplete} and {@code handle}.
      *
      * @param fn the function to use to compute the value of the
      * returned CompletableFuture if this CompletableFuture completed
@@ -2882,7 +2624,8 @@
         Object r;
         if ((r = result) == null) {
             CompletionNode p =
-                new CompletionNode(d = new ExceptionCompletion<T>(this, fn, dst));
+                new CompletionNode(d = new ExceptionCompletion<T>
+                                   (this, fn, dst));
             while ((r = result) == null) {
                 if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
                                                 p.next = completions, p))
@@ -2910,59 +2653,6 @@
         return dst;
     }
 
-    /**
-     * Returns a new CompletableFuture that is completed when this
-     * CompletableFuture completes, with the result of the given
-     * function of the result and exception of this CompletableFuture's
-     * completion.  The given function is invoked with the result (or
-     * {@code null} if none) and the exception (or {@code null} if none)
-     * of this CompletableFuture when complete.
-     *
-     * @param fn the function to use to compute the value of the
-     * returned CompletableFuture
-     * @return the new CompletableFuture
-     */
-    public <U> CompletableFuture<U> handle
-        (BiFunction<? super T, Throwable, ? extends U> fn) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<U> dst = new CompletableFuture<U>();
-        HandleCompletion<T,U> d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p =
-                new CompletionNode(d = new HandleCompletion<T,U>(this, fn, dst));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
-                                                p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            U u; Throwable dx;
-            try {
-                u = fn.apply(t, ex);
-                dx = null;
-            } catch (Throwable rex) {
-                dx = rex;
-                u = null;
-            }
-            dst.internalComplete(u, dx);
-        }
-        helpPostComplete();
-        return dst;
-    }
-
-
     /* ------------- Arbitrary-arity constructions -------------- */
 
     /*
@@ -3215,6 +2905,21 @@
     }
 
     /**
+     * Returns {@code true} if this CompletableFuture completed
+     * exceptionally, in any way. Possible causes include
+     * cancellation, explicit invocation of {@code
+     * completeExceptionally}, and abrupt termination of a
+     * CompletionStage action.
+     *
+     * @return {@code true} if this CompletableFuture completed
+     * exceptionally
+     */
+    public boolean isCompletedExceptionally() {
+        Object r;
+        return ((r = result) instanceof AltResult) && r != NIL;
+    }
+
+    /**
      * Forcibly sets or resets the value subsequently returned by
      * method {@link #get()} and related methods, whether or not
      * already completed. This method is designed for use only in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/CompletionStage.java	Wed Jul 05 19:07:11 2017 +0200
@@ -0,0 +1,760 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package java.util.concurrent;
+import java.util.function.Supplier;
+import java.util.function.Consumer;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.BiFunction;
+import java.util.concurrent.Executor;
+
+/**
+ * A stage of a possibly asynchronous computation, that performs an
+ * action or computes a value when another CompletionStage completes.
+ * A stage completes upon termination of its computation, but this may
+ * in turn trigger other dependent stages.  The functionality defined
+ * in this interface takes only a few basic forms, which expand out to
+ * a larger set of methods to capture a range of usage styles: <ul>
+ *
+ * <li>The computation performed by a stage may be expressed as a
+ * Function, Consumer, or Runnable (using methods with names including
+ * <em>apply</em>, <em>accept</em>, or <em>run</em>, respectively)
+ * depending on whether it requires arguments and/or produces results.
+ * For example, {@code stage.thenApply(x -> square(x)).thenAccept(x ->
+ * System.out.print(x)).thenRun(() -> System.out.println())}. An
+ * additional form (<em>compose</em>) applies functions of stages
+ * themselves, rather than their results. </li>
+ *
+ * <li> One stage's execution may be triggered by completion of a
+ * single stage, or both of two stages, or either of two stages.
+ * Dependencies on a single stage are arranged using methods with
+ * prefix <em>then</em>. Those triggered by completion of
+ * <em>both</em> of two stages may <em>combine</em> their results or
+ * effects, using correspondingly named methods. Those triggered by
+ * <em>either</em> of two stages make no guarantees about which of the
+ * results or effects are used for the dependent stage's
+ * computation.</li>
+ *
+ * <li> Dependencies among stages control the triggering of
+ * computations, but do not otherwise guarantee any particular
+ * ordering. Additionally, execution of a new stage's computations may
+ * be arranged in any of three ways: default execution, default
+ * asynchronous execution (using methods with suffix <em>async</em>
+ * that employ the stage's default asynchronous execution facility),
+ * or custom (via a supplied {@link Executor}).  The execution
+ * properties of default and async modes are specified by
+ * CompletionStage implementations, not this interface. Methods with
+ * explicit Executor arguments may have arbitrary execution
+ * properties, and might not even support concurrent execution, but
+ * are arranged for processing in a way that accommodates asynchrony.
+ *
+ * <li> Two method forms support processing whether the triggering
+ * stage completed normally or exceptionally: Method {@link
+ * #whenComplete whenComplete} allows injection of an action
+ * regardless of outcome, otherwise preserving the outcome in its
+ * completion. Method {@link #handle handle} additionally allows the
+ * stage to compute a replacement result that may enable further
+ * processing by other dependent stages.  In all other cases, if a
+ * stage's computation terminates abruptly with an (unchecked)
+ * exception or error, then all dependent stages requiring its
+ * completion complete exceptionally as well, with a {@link
+ * CompletionException} holding the exception as its cause.  If a
+ * stage is dependent on <em>both</em> of two stages, and both
+ * complete exceptionally, then the CompletionException may correspond
+ * to either one of these exceptions.  If a stage is dependent on
+ * <em>either</em> of two others, and only one of them completes
+ * exceptionally, no guarantees are made about whether the dependent
+ * stage completes normally or exceptionally. In the case of method
+ * {@code whenComplete}, when the supplied action itself encounters an
+ * exception, then the stage exceptionally completes with this
+ * exception if not already completed exceptionally.</li>
+ *
+ * </ul>
+ *
+ * <p>All methods adhere to the above triggering, execution, and
+ * exceptional completion specifications (which are not repeated in
+ * individual method specifications). Additionally, while arguments
+ * used to pass a completion result (that is, for parameters of type
+ * {@code T}) for methods accepting them may be null, passing a null
+ * value for any other parameter will result in a {@link
+ * NullPointerException} being thrown.
+ *
+ * <p>This interface does not define methods for initially creating,
+ * forcibly completing normally or exceptionally, probing completion
+ * status or results, or awaiting completion of a stage.
+ * Implementations of CompletionStage may provide means of achieving
+ * such effects, as appropriate.  Method {@link #toCompletableFuture}
+ * enables interoperability among different implementations of this
+ * interface by providing a common conversion type.
+ *
+ * @author Doug Lea
+ * @since 1.8
+ */
+public interface CompletionStage<T> {
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, is executed with this stage's result as the argument
+     * to the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param fn the function to use to compute the value of
+     * the returned CompletionStage
+     * @param <U> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, is executed using this stage's default asynchronous
+     * execution facility, with this stage's result as the argument to
+     * the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param fn the function to use to compute the value of
+     * the returned CompletionStage
+     * @param <U> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> thenApplyAsync
+        (Function<? super T,? extends U> fn);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, is executed using the supplied Executor, with this
+     * stage's result as the argument to the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param fn the function to use to compute the value of
+     * the returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @param <U> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> thenApplyAsync
+        (Function<? super T,? extends U> fn,
+         Executor executor);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, is executed with this stage's result as the argument
+     * to the supplied action.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> thenAccept(Consumer<? super T> action);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, is executed using this stage's default asynchronous
+     * execution facility, with this stage's result as the argument to
+     * the supplied action.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, is executed using the supplied Executor, with this
+     * stage's result as the argument to the supplied action.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action,
+                                                 Executor executor);
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, executes the given action.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> thenRun(Runnable action);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, executes the given action using this stage's default
+     * asynchronous execution facility.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> thenRunAsync(Runnable action);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, executes the given action using the supplied Executor.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> thenRunAsync(Runnable action,
+                                              Executor executor);
+
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage both complete normally, is executed with the two
+     * results as arguments to the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param fn the function to use to compute the value of
+     * the returned CompletionStage
+     * @param <U> the type of the other CompletionStage's result
+     * @param <V> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U,V> CompletionStage<V> thenCombine
+        (CompletionStage<? extends U> other,
+         BiFunction<? super T,? super U,? extends V> fn);
+
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage complete normally, is executed using this stage's
+     * default asynchronous execution facility, with the two results
+     * as arguments to the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param fn the function to use to compute the value of
+     * the returned CompletionStage
+     * @param <U> the type of the other CompletionStage's result
+     * @param <V> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U,V> CompletionStage<V> thenCombineAsync
+        (CompletionStage<? extends U> other,
+         BiFunction<? super T,? super U,? extends V> fn);
+
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage complete normally, is executed using the supplied
+     * executor, with the two results as arguments to the supplied
+     * function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param fn the function to use to compute the value of
+     * the returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @param <U> the type of the other CompletionStage's result
+     * @param <V> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U,V> CompletionStage<V> thenCombineAsync
+        (CompletionStage<? extends U> other,
+         BiFunction<? super T,? super U,? extends V> fn,
+         Executor executor);
+
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage both complete normally, is executed with the two
+     * results as arguments to the supplied action.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @param <U> the type of the other CompletionStage's result
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<Void> thenAcceptBoth
+        (CompletionStage<? extends U> other,
+         BiConsumer<? super T, ? super U> action);
+
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage complete normally, is executed using this stage's
+     * default asynchronous execution facility, with the two results
+     * as arguments to the supplied action.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @param <U> the type of the other CompletionStage's result
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<Void> thenAcceptBothAsync
+        (CompletionStage<? extends U> other,
+         BiConsumer<? super T, ? super U> action);
+
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage complete normally, is executed using the supplied
+     * executor, with the two results as arguments to the supplied
+     * function.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @param <U> the type of the other CompletionStage's result
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<Void> thenAcceptBothAsync
+        (CompletionStage<? extends U> other,
+         BiConsumer<? super T, ? super U> action,
+         Executor executor);
+
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage both complete normally, executes the given action.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> runAfterBoth(CompletionStage<?> other,
+                                              Runnable action);
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage complete normally, executes the given action using
+     * this stage's default asynchronous execution facility.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other,
+                                                   Runnable action);
+
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage complete normally, executes the given action using
+     * the supplied executor
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other,
+                                                   Runnable action,
+                                                   Executor executor);
+    /**
+     * Returns a new CompletionStage that, when either this or the
+     * other given stage complete normally, is executed with the
+     * corresponding result as argument to the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param fn the function to use to compute the value of
+     * the returned CompletionStage
+     * @param <U> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> applyToEither
+        (CompletionStage<? extends T> other,
+         Function<? super T, U> fn);
+
+    /**
+     * Returns a new CompletionStage that, when either this or the
+     * other given stage complete normally, is executed using this
+     * stage's default asynchronous execution facility, with the
+     * corresponding result as argument to the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param fn the function to use to compute the value of
+     * the returned CompletionStage
+     * @param <U> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> applyToEitherAsync
+        (CompletionStage<? extends T> other,
+         Function<? super T, U> fn);
+
+    /**
+     * Returns a new CompletionStage that, when either this or the
+     * other given stage complete normally, is executed using the
+     * supplied executor, with the corresponding result as argument to
+     * the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param fn the function to use to compute the value of
+     * the returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @param <U> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> applyToEitherAsync
+        (CompletionStage<? extends T> other,
+         Function<? super T, U> fn,
+         Executor executor);
+
+    /**
+     * Returns a new CompletionStage that, when either this or the
+     * other given stage complete normally, is executed with the
+     * corresponding result as argument to the supplied action.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> acceptEither
+        (CompletionStage<? extends T> other,
+         Consumer<? super T> action);
+
+    /**
+     * Returns a new CompletionStage that, when either this or the
+     * other given stage complete normally, is executed using this
+     * stage's default asynchronous execution facility, with the
+     * corresponding result as argument to the supplied action.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> acceptEitherAsync
+        (CompletionStage<? extends T> other,
+         Consumer<? super T> action);
+
+    /**
+     * Returns a new CompletionStage that, when either this or the
+     * other given stage complete normally, is executed using the
+     * supplied executor, with the corresponding result as argument to
+     * the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> acceptEitherAsync
+        (CompletionStage<? extends T> other,
+         Consumer<? super T> action,
+         Executor executor);
+
+    /**
+     * Returns a new CompletionStage that, when either this or the
+     * other given stage complete normally, executes the given action.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> runAfterEither(CompletionStage<?> other,
+                                                Runnable action);
+
+    /**
+     * Returns a new CompletionStage that, when either this or the
+     * other given stage complete normally, executes the given action
+     * using this stage's default asynchronous execution facility.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> runAfterEitherAsync
+        (CompletionStage<?> other,
+         Runnable action);
+
+    /**
+     * Returns a new CompletionStage that, when either this or the
+     * other given stage complete normally, executes the given action
+     * using supplied executor.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param other the other CompletionStage
+     * @param action the action to perform before completing the
+     * returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @return the new CompletionStage
+     */
+    public CompletionStage<Void> runAfterEitherAsync
+        (CompletionStage<?> other,
+         Runnable action,
+         Executor executor);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, is executed with this stage as the argument
+     * to the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param fn the function returning a new CompletionStage
+     * @param <U> the type of the returned CompletionStage's result
+     * @return the CompletionStage
+     */
+    public <U> CompletionStage<U> thenCompose
+        (Function<? super T, ? extends CompletionStage<U>> fn);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, is executed using this stage's default asynchronous
+     * execution facility, with this stage as the argument to the
+     * supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param fn the function returning a new CompletionStage
+     * @param <U> the type of the returned CompletionStage's result
+     * @return the CompletionStage
+     */
+    public <U> CompletionStage<U> thenComposeAsync
+        (Function<? super T, ? extends CompletionStage<U>> fn);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * normally, is executed using the supplied Executor, with this
+     * stage's result as the argument to the supplied function.
+     *
+     * See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param fn the function returning a new CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @param <U> the type of the returned CompletionStage's result
+     * @return the CompletionStage
+     */
+    public <U> CompletionStage<U> thenComposeAsync
+        (Function<? super T, ? extends CompletionStage<U>> fn,
+         Executor executor);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * exceptionally, is executed with this stage's exception as the
+     * argument to the supplied function.  Otherwise, if this stage
+     * completes normally, then the returned stage also completes
+     * normally with the same value.
+     *
+     * @param fn the function to use to compute the value of the
+     * returned CompletionStage if this CompletionStage completed
+     * exceptionally
+     * @return the new CompletionStage
+     */
+    public CompletionStage<T> exceptionally
+        (Function<Throwable, ? extends T> fn);
+
+    /**
+     * Returns a new CompletionStage with the same result or exception
+     * as this stage, and when this stage completes, executes the
+     * given action with the result (or {@code null} if none) and the
+     * exception (or {@code null} if none) of this stage.
+     *
+     * @param action the action to perform
+     * @return the new CompletionStage
+     */
+    public CompletionStage<T> whenComplete
+        (BiConsumer<? super T, ? super Throwable> action);
+
+    /**
+     * Returns a new CompletionStage with the same result or exception
+     * as this stage, and when this stage completes, executes the
+     * given action executes the given action using this stage's
+     * default asynchronous execution facility, with the result (or
+     * {@code null} if none) and the exception (or {@code null} if
+     * none) of this stage as arguments.
+     *
+     * @param action the action to perform
+     * @return the new CompletionStage
+     */
+    public CompletionStage<T> whenCompleteAsync
+        (BiConsumer<? super T, ? super Throwable> action);
+
+    /**
+     * Returns a new CompletionStage with the same result or exception
+     * as this stage, and when this stage completes, executes using
+     * the supplied Executor, the given action with the result (or
+     * {@code null} if none) and the exception (or {@code null} if
+     * none) of this stage as arguments.
+     *
+     * @param action the action to perform
+     * @param executor the executor to use for asynchronous execution
+     * @return the new CompletionStage
+     */
+    public CompletionStage<T> whenCompleteAsync
+        (BiConsumer<? super T, ? super Throwable> action,
+         Executor executor);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * either normally or exceptionally, is executed with this stage's
+     * result and exception as arguments to the supplied function.
+     * The given function is invoked with the result (or {@code null}
+     * if none) and the exception (or {@code null} if none) of this
+     * stage when complete as arguments.
+     *
+     * @param fn the function to use to compute the value of the
+     * returned CompletionStage
+     * @param <U> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> handle
+        (BiFunction<? super T, Throwable, ? extends U> fn);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * either normally or exceptionally, is executed using this stage's
+     * default asynchronous execution facility, with this stage's
+     * result and exception as arguments to the supplied function.
+     * The given function is invoked with the result (or {@code null}
+     * if none) and the exception (or {@code null} if none) of this
+     * stage when complete as arguments.
+     *
+     * @param fn the function to use to compute the value of the
+     * returned CompletionStage
+     * @param <U> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> handleAsync
+        (BiFunction<? super T, Throwable, ? extends U> fn);
+
+    /**
+     * Returns a new CompletionStage that, when this stage completes
+     * either normally or exceptionally, is executed using the
+     * supplied executor, with this stage's result and exception as
+     * arguments to the supplied function.  The given function is
+     * invoked with the result (or {@code null} if none) and the
+     * exception (or {@code null} if none) of this stage when complete
+     * as arguments.
+     *
+     * @param fn the function to use to compute the value of the
+     * returned CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @param <U> the function's return type
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> handleAsync
+        (BiFunction<? super T, Throwable, ? extends U> fn,
+         Executor executor);
+
+    /**
+     * Returns a {@link CompletableFuture} maintaining the same
+     * completion properties as this stage. If this stage is already a
+     * CompletableFuture, this method may return this stage itself.
+     * Otherwise, invocation of this method may be equivalent in
+     * effect to {@code thenApply(x -> x)}, but returning an instance
+     * of type {@code CompletableFuture}. A CompletionStage
+     * implementation that does not choose to interoperate with others
+     * may throw {@code UnsupportedOperationException}.
+     *
+     * @return the CompletableFuture
+     * @throws UnsupportedOperationException if this implementation
+     * does not interoperate with CompletableFuture
+     */
+    public CompletableFuture<T> toCompletableFuture();
+
+}
--- a/jdk/src/share/classes/java/util/logging/XMLFormatter.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/logging/XMLFormatter.java	Wed Jul 05 19:07:11 2017 +0200
@@ -47,7 +47,7 @@
     private LogManager manager = LogManager.getLogManager();
 
     // Append a two digit number.
-    private void a2(StringBuffer sb, int x) {
+    private void a2(StringBuilder sb, int x) {
         if (x < 10) {
             sb.append('0');
         }
@@ -55,25 +55,26 @@
     }
 
     // Append the time and date in ISO 8601 format
-    private void appendISO8601(StringBuffer sb, long millis) {
-        Date date = new Date(millis);
-        sb.append(date.getYear() + 1900);
+    private void appendISO8601(StringBuilder sb, long millis) {
+        GregorianCalendar cal = new GregorianCalendar();
+        cal.setTimeInMillis(millis);
+        sb.append(cal.get(Calendar.YEAR) + 1900);
         sb.append('-');
-        a2(sb, date.getMonth() + 1);
+        a2(sb, cal.get(Calendar.MONTH) + 1);
         sb.append('-');
-        a2(sb, date.getDate());
+        a2(sb, cal.get(Calendar.DAY_OF_MONTH));
         sb.append('T');
-        a2(sb, date.getHours());
+        a2(sb, cal.get(Calendar.HOUR_OF_DAY));
         sb.append(':');
-        a2(sb, date.getMinutes());
+        a2(sb, cal.get(Calendar.MINUTE));
         sb.append(':');
-        a2(sb, date.getSeconds());
+        a2(sb, cal.get(Calendar.SECOND));
     }
 
-    // Append to the given StringBuffer an escaped version of the
+    // Append to the given StringBuilder an escaped version of the
     // given text string where XML special characters have been escaped.
     // For a null string we append "<null>"
-    private void escape(StringBuffer sb, String text) {
+    private void escape(StringBuilder sb, String text) {
         if (text == null) {
             text = "<null>";
         }
@@ -102,7 +103,7 @@
      * @return a formatted log record
      */
     public String format(LogRecord record) {
-        StringBuffer sb = new StringBuffer(500);
+        StringBuilder sb = new StringBuilder(500);
         sb.append("<record>\n");
 
         sb.append("  <date>");
@@ -224,7 +225,7 @@
      * @return  a valid XML string
      */
     public String getHead(Handler h) {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         String encoding;
         sb.append("<?xml version=\"1.0\"");
 
--- a/jdk/src/share/classes/java/util/stream/AbstractPipeline.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/AbstractPipeline.java	Wed Jul 05 19:07:11 2017 +0200
@@ -75,11 +75,13 @@
      * Backlink to the head of the pipeline chain (self if this is the source
      * stage).
      */
+    @SuppressWarnings("rawtypes")
     private final AbstractPipeline sourceStage;
 
     /**
      * The "upstream" pipeline, or null if this is the source stage.
      */
+    @SuppressWarnings("rawtypes")
     private final AbstractPipeline previousStage;
 
     /**
@@ -92,6 +94,7 @@
      * The next stage in the pipeline, or null if this is the last stage.
      * Effectively final at the point of linking to the next pipeline.
      */
+    @SuppressWarnings("rawtypes")
     private AbstractPipeline nextStage;
 
     /**
@@ -222,8 +225,8 @@
         linkedOrConsumed = true;
 
         return isParallel()
-               ? (R) terminalOp.evaluateParallel(this, sourceSpliterator(terminalOp.getOpFlags()))
-               : (R) terminalOp.evaluateSequential(this, sourceSpliterator(terminalOp.getOpFlags()));
+               ? terminalOp.evaluateParallel(this, sourceSpliterator(terminalOp.getOpFlags()))
+               : terminalOp.evaluateSequential(this, sourceSpliterator(terminalOp.getOpFlags()));
     }
 
     /**
@@ -232,6 +235,7 @@
      * @param generator the array generator to be used to create array instances
      * @return a flat array-backed Node that holds the collected output elements
      */
+    @SuppressWarnings("unchecked")
     final Node<E_OUT> evaluateToArrayNode(IntFunction<E_OUT[]> generator) {
         if (linkedOrConsumed)
             throw new IllegalStateException("stream has already been operated upon");
@@ -256,6 +260,7 @@
      * @throws IllegalStateException if this pipeline stage is not the source
      *         stage.
      */
+    @SuppressWarnings("unchecked")
     final Spliterator<E_OUT> sourceStageSpliterator() {
         if (this != sourceStage)
             throw new IllegalStateException();
@@ -265,11 +270,13 @@
         linkedOrConsumed = true;
 
         if (sourceStage.sourceSpliterator != null) {
+            @SuppressWarnings("unchecked")
             Spliterator<E_OUT> s = sourceStage.sourceSpliterator;
             sourceStage.sourceSpliterator = null;
             return s;
         }
         else if (sourceStage.sourceSupplier != null) {
+            @SuppressWarnings("unchecked")
             Spliterator<E_OUT> s = (Spliterator<E_OUT>) sourceStage.sourceSupplier.get();
             sourceStage.sourceSupplier = null;
             return s;
@@ -282,12 +289,14 @@
     // BaseStream
 
     @Override
+    @SuppressWarnings("unchecked")
     public final S sequential() {
         sourceStage.parallel = false;
         return (S) this;
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public final S parallel() {
         sourceStage.parallel = true;
         return (S) this;
@@ -295,6 +304,7 @@
 
     // Primitive specialization use co-variant overrides, hence is not final
     @Override
+    @SuppressWarnings("unchecked")
     public Spliterator<E_OUT> spliterator() {
         if (linkedOrConsumed)
             throw new IllegalStateException("stream has already been operated upon");
@@ -302,12 +312,14 @@
 
         if (this == sourceStage) {
             if (sourceStage.sourceSpliterator != null) {
-                Spliterator<E_OUT> s = sourceStage.sourceSpliterator;
+                @SuppressWarnings("unchecked")
+                Spliterator<E_OUT> s = (Spliterator<E_OUT>) sourceStage.sourceSpliterator;
                 sourceStage.sourceSpliterator = null;
                 return s;
             }
             else if (sourceStage.sourceSupplier != null) {
-                Supplier<Spliterator<E_OUT>> s = sourceStage.sourceSupplier;
+                @SuppressWarnings("unchecked")
+                Supplier<Spliterator<E_OUT>> s = (Supplier<Spliterator<E_OUT>>) sourceStage.sourceSupplier;
                 sourceStage.sourceSupplier = null;
                 return lazySpliterator(s);
             }
@@ -349,10 +361,11 @@
      * @param terminalFlags Operation flags for the terminal operation
      */
     private void parallelPrepare(int terminalFlags) {
+        @SuppressWarnings("rawtypes")
         AbstractPipeline backPropagationHead = sourceStage;
         if (sourceStage.sourceAnyStateful) {
             int depth = 1;
-            for (AbstractPipeline u = sourceStage, p = sourceStage.nextStage;
+            for (  @SuppressWarnings("rawtypes") AbstractPipeline u = sourceStage, p = sourceStage.nextStage;
                  p != null;
                  u = p, p = p.nextStage) {
                 int thisOpFlags = p.sourceOrOpFlags;
@@ -383,7 +396,7 @@
         // Apply the upstream terminal flags
         if (terminalFlags != 0) {
             int upstreamTerminalFlags = terminalFlags & StreamOpFlag.UPSTREAM_TERMINAL_OP_MASK;
-            for (AbstractPipeline p = backPropagationHead; p.nextStage != null; p = p.nextStage) {
+            for ( @SuppressWarnings("rawtypes") AbstractPipeline p = backPropagationHead; p.nextStage != null; p = p.nextStage) {
                 p.combinedFlags = StreamOpFlag.combineOpFlags(upstreamTerminalFlags, p.combinedFlags);
             }
 
@@ -398,6 +411,7 @@
      * of all computations up to and including the most recent stateful
      * operation.
      */
+    @SuppressWarnings("unchecked")
     private Spliterator<?> sourceSpliterator(int terminalFlags) {
         // Get the source spliterator of the pipeline
         Spliterator<?> spliterator = null;
@@ -421,7 +435,7 @@
 
             // Adapt the source spliterator, evaluating each stateful op
             // in the pipeline up to and including this pipeline stage
-            for (AbstractPipeline u = sourceStage, p = sourceStage.nextStage, e = this;
+            for ( @SuppressWarnings("rawtypes") AbstractPipeline u = sourceStage, p = sourceStage.nextStage, e = this;
                  u != e;
                  u = p, p = p.nextStage) {
 
@@ -442,6 +456,7 @@
 
     @Override
     final StreamShape getSourceShape() {
+        @SuppressWarnings("rawtypes")
         AbstractPipeline p = AbstractPipeline.this;
         while (p.depth > 0) {
             p = p.previousStage;
@@ -475,7 +490,9 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     final <P_IN> void copyIntoWithCancel(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator) {
+        @SuppressWarnings({"rawtypes","unchecked"})
         AbstractPipeline p = AbstractPipeline.this;
         while (p.depth > 0) {
             p = p.previousStage;
@@ -495,16 +512,18 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     final <P_IN> Sink<P_IN> wrapSink(Sink<E_OUT> sink) {
         Objects.requireNonNull(sink);
 
-        for (AbstractPipeline p=AbstractPipeline.this; p.depth > 0; p=p.previousStage) {
+        for ( @SuppressWarnings("rawtypes") AbstractPipeline p=AbstractPipeline.this; p.depth > 0; p=p.previousStage) {
             sink = p.opWrapSink(p.previousStage.combinedFlags, sink);
         }
         return (Sink<P_IN>) sink;
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     final <P_IN> Spliterator<E_OUT> wrapSpliterator(Spliterator<P_IN> sourceSpliterator) {
         if (depth == 0) {
             return (Spliterator<E_OUT>) sourceSpliterator;
@@ -591,16 +610,19 @@
     /**
      * Make a node builder compatible with this stream shape.
      *
-     * @param exactSizeIfKnown if {@literal >=0}, then a node builder will be created that
-     * has a fixed capacity of at most sizeIfKnown elements. If {@literal < 0},
-     * then the node builder has an unfixed capacity. A fixed capacity node
-     * builder will throw exceptions if an element is added after builder has
-     * reached capacity, or is built before the builder has reached capacity.
+     * @param exactSizeIfKnown if {@literal >=0}, then a node builder will be
+     * created that has a fixed capacity of at most sizeIfKnown elements. If
+     * {@literal < 0}, then the node builder has an unfixed capacity. A fixed
+     * capacity node builder will throw exceptions if an element is added after
+     * builder has reached capacity, or is built before the builder has reached
+     * capacity.
+     *
      * @param generator the array generator to be used to create instances of a
      * T[] array. For implementations supporting primitive nodes, this parameter
      * may be ignored.
      * @return a node builder
      */
+    @Override
     abstract Node.Builder<E_OUT> makeNodeBuilder(long exactSizeIfKnown,
                                                  IntFunction<E_OUT[]> generator);
 
@@ -679,6 +701,7 @@
      * @param spliterator the source {@code Spliterator}
      * @return a {@code Spliterator} describing the result of the evaluation
      */
+    @SuppressWarnings("unchecked")
     <P_IN> Spliterator<E_OUT> opEvaluateParallelLazy(PipelineHelper<E_OUT> helper,
                                                      Spliterator<P_IN> spliterator) {
         return opEvaluateParallel(helper, spliterator, i -> (E_OUT[]) new Object[i]).spliterator();
--- a/jdk/src/share/classes/java/util/stream/AbstractShortCircuitTask.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/AbstractShortCircuitTask.java	Wed Jul 05 19:07:11 2017 +0200
@@ -39,6 +39,7 @@
  * @param <K> type of child and sibling tasks
  * @since 1.8
  */
+@SuppressWarnings("serial")
 abstract class AbstractShortCircuitTask<P_IN, P_OUT, R,
                                         K extends AbstractShortCircuitTask<P_IN, P_OUT, R, K>>
         extends AbstractTask<P_IN, P_OUT, R, K> {
@@ -219,7 +220,8 @@
      */
     protected void cancelLaterNodes() {
         // Go up the tree, cancel right siblings of this node and all parents
-        for (K parent = getParent(), node = (K) this; parent != null;
+        for (@SuppressWarnings("unchecked") K parent = getParent(), node = (K) this;
+             parent != null;
              node = parent, parent = parent.getParent()) {
             // If node is a left child of parent, then has a right sibling
             if (parent.leftChild == node) {
--- a/jdk/src/share/classes/java/util/stream/AbstractTask.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/AbstractTask.java	Wed Jul 05 19:07:11 2017 +0200
@@ -73,6 +73,9 @@
  *     }
  * }</pre>
  *
+ * <p>Serialization is not supported as there is no intention to serialize
+ * tasks managed by stream ops.
+ *
  * @param <P_IN> Type of elements input to the pipeline
  * @param <P_OUT> Type of elements output from the pipeline
  * @param <R> Type of intermediate result, which may be different from operation
@@ -80,6 +83,7 @@
  * @param <K> Type of parent, child and sibling tasks
  * @since 1.8
  */
+@SuppressWarnings("serial")
 abstract class AbstractTask<P_IN, P_OUT, R,
                             K extends AbstractTask<P_IN, P_OUT, R, K>>
         extends CountedCompleter<R> {
--- a/jdk/src/share/classes/java/util/stream/Collector.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/Collector.java	Wed Jul 05 19:07:11 2017 +0200
@@ -25,40 +25,45 @@
 package java.util.stream;
 
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.Set;
-import java.util.function.BiFunction;
+import java.util.function.BiConsumer;
 import java.util.function.BinaryOperator;
+import java.util.function.Function;
 import java.util.function.Supplier;
 
 /**
  * A <a href="package-summary.html#Reduction">reduction operation</a> that
- * supports folding input elements into a cumulative result.  The result may be
- * a value or may be a mutable result container.  Examples of operations
- * accumulating results into a mutable result container include: accumulating
- * input elements into a {@code Collection}; concatenating strings into a
- * {@code StringBuilder}; computing summary information about elements such as
- * sum, min, max, or average; computing "pivot table" summaries such as "maximum
- * valued transaction by seller", etc.  Reduction operations can be performed
- * either sequentially or in parallel.
+ * folds input elements into a mutable result container, optionally transforming
+ * the accumulated result into a final representation after all input elements
+ * have been processed.
+ *
+ * <p>Examples of mutable reduction operations include:
+ * accumulating elements into a {@code Collection}; concatenating
+ * strings using a {@code StringBuilder}; computing summary information about
+ * elements such as sum, min, max, or average; computing "pivot table" summaries
+ * such as "maximum valued transaction by seller", etc.  Reduction operations
+ * can be performed either sequentially or in parallel.
  *
  * <p>The following are examples of using the predefined {@code Collector}
  * implementations in {@link Collectors} with the {@code Stream} API to perform
  * mutable reduction tasks:
  * <pre>{@code
- *     // Accumulate elements into a List
- *     List<String> list = stream.collect(Collectors.toList());
+ *     // Accumulate names into a List
+ *     List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
  *
- *     // Accumulate elements into a TreeSet
- *     Set<String> list = stream.collect(Collectors.toCollection(TreeSet::new));
+ *     // Accumulate names into a TreeSet
+ *     Set<String> list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
  *
  *     // Convert elements to strings and concatenate them, separated by commas
- *     String joined = stream.map(Object::toString)
- *                           .collect(Collectors.toStringJoiner(", "))
- *                           .toString();
+ *     String joined = things.stream()
+ *                           .map(Object::toString)
+ *                           .collect(Collectors.joining(", "));
  *
  *     // Find highest-paid employee
  *     Employee highestPaid = employees.stream()
- *                                     .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)));
+ *                                     .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)))
+ *                                     .get();
  *
  *     // Group employees by department
  *     Map<Department, List<Employee>> byDept
@@ -66,7 +71,7 @@
  *                    .collect(Collectors.groupingBy(Employee::getDepartment));
  *
  *     // Find highest-paid employee by department
- *     Map<Department, Employee> highestPaidByDept
+ *     Map<Department, Optional<Employee>> highestPaidByDept
  *         = employees.stream()
  *                    .collect(Collectors.groupingBy(Employee::getDepartment,
  *                                                   Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
@@ -74,43 +79,42 @@
  *     // Partition students into passing and failing
  *     Map<Boolean, List<Student>> passingFailing =
  *         students.stream()
- *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
+ *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
  *
  * }</pre>
  *
- * <p>A {@code Collector} is specified by three functions that work together to
- * manage a result or result container.  They are: creation of an initial
- * result, incorporating a new data element into a result, and combining two
- * results into one. The last function -- combining two results into one -- is
- * used during parallel operations, where subsets of the input are accumulated
- * in parallel, and then the subresults merged into a combined result. The
- * result may be a mutable container or a value.  If the result is mutable, the
- * accumulation and combination functions may either mutate their left argument
- * and return that (such as adding elements to a collection), or return a new
- * result, in which case it should not perform any mutation.
+ * <p>A {@code Collector} is specified by four functions that work together to
+ * accumulate entries into a mutable result container, and optionally perform
+ * a final transform on the result.  They are: creation of a new result container,
+ * incorporating a new data element into a result container, combining two
+ * result containers into one, and performing a final transform on the container.
+ * The combiner function is used during parallel operations, where
+ * subsets of the input are accumulated into separate result
+ * containers, and then the subresults merged into a combined result.  The
+ * combiner function may merge one set of subresults into the other and return
+ * that, or it may return a new object to describe the combined results.
  *
- * <p>Collectors also have a set of characteristics, including
- * {@link Characteristics#CONCURRENT} and
- * {@link Characteristics#STRICTLY_MUTATIVE}.  These characteristics provide
+ * <p>Collectors also have a set of characteristics, such as
+ * {@link Characteristics#CONCURRENT}.  These characteristics provide
  * hints that can be used by a reduction implementation to provide better
  * performance.
  *
  * <p>Libraries that implement reduction based on {@code Collector}, such as
  * {@link Stream#collect(Collector)}, must adhere to the following constraints:
  * <ul>
- *     <li>The first argument passed to the accumulator function, and both
- *     arguments passed to the combiner function, must be the result of a
- *     previous invocation of {@link #resultSupplier()}, {@link #accumulator()},
- *     or {@link #combiner()}.</li>
+ *     <li>The first argument passed to the accumulator function, both
+ *     arguments passed to the combiner function, and the argument passed to the
+ *     finisher function must be the result of a previous invocation of the
+ *     result supplier, accumulator, or combiner functions.</li>
  *     <li>The implementation should not do anything with the result of any of
  *     the result supplier, accumulator, or combiner functions other than to
- *     pass them again to the accumulator or combiner functions, or return them
- *     to the caller of the reduction operation.</li>
- *     <li>If a result is passed to the accumulator or combiner function, and
- *     the same object is not returned from that function, it is never used
- *     again.</li>
- *     <li>Once a result is passed to the combiner function, it is never passed
- *     to the accumulator function again.</li>
+ *     pass them again to the accumulator, combiner, or finisher functions,
+ *     or return them to the caller of the reduction operation.</li>
+ *     <li>If a result is passed to the combiner or finisher
+ *     function, and the same object is not returned from that function, it is
+ *     never used again.</li>
+ *     <li>Once a result is passed to the combiner or finisher function, it
+ *     is never passed to the accumulator function again.</li>
  *     <li>For non-concurrent collectors, any result returned from the result
  *     supplier, accumulator, or combiner functions must be serially
  *     thread-confined.  This enables collection to occur in parallel without
@@ -132,11 +136,10 @@
  * Performing a reduction operation with a {@code Collector} should produce a
  * result equivalent to:
  * <pre>{@code
- *     BiFunction<R,T,R> accumulator = collector.accumulator();
- *     R result = collector.resultSupplier().get();
+ *     R container = collector.supplier().get();
  *     for (T t : data)
- *         result = accumulator.apply(result, t);
- *     return result;
+ *         collector.accumulator().accept(container, t);
+ *     return collector.finisher().apply(container);
  * }</pre>
  *
  * <p>However, the library is free to partition the input, perform the reduction
@@ -149,7 +152,7 @@
  * is accumulating elements into a {@code TreeSet}. In this case, the {@code
  * resultSupplier()} function is {@code () -> new Treeset<T>()}, the
  * {@code accumulator} function is
- * {@code (set, element) -> { set.add(element); return set; }}, and the combiner
+ * {@code (set, element) -> set.add(element) }, and the combiner
  * function is {@code (left, right) -> { left.addAll(right); return left; }}.
  * (This behavior is implemented by
  * {@code Collectors.toCollection(TreeSet::new)}).
@@ -159,51 +162,49 @@
  * @see Stream#collect(Collector)
  * @see Collectors
  *
- * @param <T> the type of input element to the collect operation
- * @param <R> the result type of the collect operation
+ * @param <T> the type of input elements to the reduction operation
+ * @param <A> the mutable accumulation type of the reduction operation (often
+ *           hidden as an implementation detail)
+ * @param <R> the result type of the reduction operation
  * @since 1.8
  */
-public interface Collector<T, R> {
+public interface Collector<T, A, R> {
     /**
-     * A function that creates and returns a new result that represents
-     * "no values".  If the accumulator or combiner functions may mutate their
-     * arguments, this must be a new, empty result container.
+     * A function that creates and returns a new mutable result container.
      *
-     * @return a function which, when invoked, returns a result representing
-     * "no values"
+     * @return a function which returns a new, mutable result container
      */
-    Supplier<R> resultSupplier();
+    Supplier<A> supplier();
 
     /**
-     * A function that folds a new value into a cumulative result.  The result
-     * may be a mutable result container or a value.  The accumulator function
-     * may modify a mutable container and return it, or create a new result and
-     * return that, but if it returns a new result object, it must not modify
-     * any of its arguments.
+     * A function that folds a new value into a mutable result container.
      *
-     * <p>If the collector has the {@link Characteristics#STRICTLY_MUTATIVE}
-     * characteristic, then the accumulator function <em>must</em> always return
-     * its first argument, after possibly mutating its state.
-     *
-     * @return a function which folds a new value into a cumulative result
+     * @return a function which folds a new value into a mutable result container
      */
-    BiFunction<R, T, R> accumulator();
+    BiConsumer<A, T> accumulator();
 
     /**
      * A function that accepts two partial results and merges them.  The
      * combiner function may fold state from one argument into the other and
-     * return that, or may return a new result object, but if it returns
-     * a new result object, it must not modify the state of either of its
-     * arguments.
-     *
-     * <p>If the collector has the {@link Characteristics#STRICTLY_MUTATIVE}
-     * characteristic, then the combiner function <em>must</em> always return
-     * its first argument, after possibly mutating its state.
+     * return that, or may return a new result object.
      *
      * @return a function which combines two partial results into a cumulative
      * result
      */
-    BinaryOperator<R> combiner();
+    BinaryOperator<A> combiner();
+
+    /**
+     * Perform the final transformation from the intermediate accumulation type
+     * {@code A} to the final result representation {@code R}.
+     *
+     * <p>If the characteristic {@code IDENTITY_TRANSFORM} is
+     * set, this function may be presumed to be an identity transform with an
+     * unchecked cast from {@code A} to {@code R}.
+     *
+     * @return a function which transforms the intermediate result to the final
+     * result
+     */
+    Function<A, R> finisher();
 
     /**
      * Returns a {@code Set} of {@code Collector.Characteristics} indicating
@@ -214,6 +215,62 @@
     Set<Characteristics> characteristics();
 
     /**
+     * Returns a new {@code Collector} described by the given {@code supplier},
+     * {@code accumulator}, and {@code combiner} functions.  The resulting
+     * {@code Collector} has the {@code Collector.Characteristics.IDENTITY_FINISH}
+     * characteristic.
+     *
+     * @param supplier The supplier function for the new collector
+     * @param accumulator The accumulator function for the new collector
+     * @param combiner The combiner function for the new collector
+     * @param characteristics The collector characteristics for the new
+     *                        collector
+     * @param <T> The type of input elements for the new collector
+     * @param <R> The type of intermediate accumulation result, and final result,
+     *           for the new collector
+     * @return the new {@code Collector}
+     */
+    public static<T, R> Collector<T, R, R> of(Supplier<R> supplier,
+                                              BiConsumer<R, T> accumulator,
+                                              BinaryOperator<R> combiner,
+                                              Characteristics... characteristics) {
+        Set<Characteristics> cs = (characteristics.length == 0)
+                                  ? Collectors.CH_ID
+                                  : Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH,
+                                                                           characteristics));
+        return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, cs);
+    }
+
+    /**
+     * Returns a new {@code Collector} described by the given {@code supplier},
+     * {@code accumulator}, {@code combiner}, and {@code finisher} functions.
+     *
+     * @param supplier The supplier function for the new collector
+     * @param accumulator The accumulator function for the new collector
+     * @param combiner The combiner function for the new collector
+     * @param finisher The finisher function for the new collector
+     * @param characteristics The collector characteristics for the new
+     *                        collector
+     * @param <T> The type of input elements for the new collector
+     * @param <A> The intermediate accumulation type of the new collector
+     * @param <R> The final result type of the new collector
+     * @return the new {@code Collector}
+     */
+    public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
+                                                 BiConsumer<A, T> accumulator,
+                                                 BinaryOperator<A> combiner,
+                                                 Function<A, R> finisher,
+                                                 Characteristics... characteristics) {
+        Set<Characteristics> cs = Collectors.CH_NOID;
+        if (characteristics.length > 0) {
+            cs = EnumSet.noneOf(Characteristics.class);
+            Collections.addAll(cs, characteristics);
+            cs = Collections.unmodifiableSet(cs);
+        }
+        return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs);
+    }
+
+    /**
      * Characteristics indicating properties of a {@code Collector}, which can
      * be used to optimize reduction implementations.
      */
@@ -222,8 +279,7 @@
          * Indicates that this collector is <em>concurrent</em>, meaning that
          * the result container can support the accumulator function being
          * called concurrently with the same result container from multiple
-         * threads. Concurrent collectors must also always have the
-         * {@code STRICTLY_MUTATIVE} characteristic.
+         * threads.
          *
          * <p>If a {@code CONCURRENT} collector is not also {@code UNORDERED},
          * then it should only be evaluated concurrently if applied to an
@@ -238,12 +294,10 @@
         UNORDERED,
 
         /**
-         * Indicates that this collector operates by strict mutation of its
-         * result container. This means that the {@link #accumulator()} and
-         * {@link #combiner()} functions will always modify the state of and
-         * return their first argument, rather than returning a different result
-         * container.
+         * Indicates that the finisher function is the identity function and
+         * can be elided.  If set, it must be the case that an unchecked cast
+         * from A to R will succeed.
          */
-        STRICTLY_MUTATIVE
+        IDENTITY_FINISH
     }
 }
--- a/jdk/src/share/classes/java/util/stream/Collectors.java	Tue Aug 13 10:34:38 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/Collectors.java	Wed Jul 05 19:07:11 2017 +0200
@@ -27,6 +27,7 @@
 import java.util.AbstractMap;
 import java.util.AbstractSet;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -39,14 +40,16 @@
 import java.util.List;
 import java.util.LongSummaryStatistics;
 import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.StringJoiner;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
@@ -64,20 +67,21 @@
  * mutable reduction tasks:
  *
  * <pre>{@code
- *     // Accumulate elements into a List
- *     List<Person> list = people.collect(Collectors.toList());
+ *     // Accumulate names into a List
+ *     List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
  *
- *     // Accumulate elements into a TreeSet
- *     List<Person> list = people.collect(Collectors.toCollection(TreeSet::new));
+ *     // Accumulate names into a TreeSet
+ *     Set<String> list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
  *
  *     // Convert elements to strings and concatenate them, separated by commas
- *     String joined = stream.map(Object::toString)
- *                           .collect(Collectors.toStringJoiner(", "))
- *                           .toString();
+ *     String joined = things.stream()
+ *                           .map(Object::toString)
+ *                           .collect(Collectors.joining(", "));
  *
  *     // Find highest-paid employee
  *     Employee highestPaid = employees.stream()
- *                                     .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary)));
+ *                                     .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary)))
+ *                                     .get();
  *
  *     // Group employees by department
  *     Map<Department, List<Employee>> byDept
@@ -85,7 +89,7 @@
  *                    .collect(Collectors.groupingBy(Employee::getDepartment));
  *
  *     // Find highest-paid employee by department
- *     Map<Department, Employee> highestPaidByDept
+ *     Map<Department, Optional<Employee>> highestPaidByDept
  *         = employees.stream()
  *                    .collect(Collectors.groupingBy(Employee::getDepartment,
  *                                                   Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
@@ -93,7 +97,7 @@
  *     // Partition students into passing and failing
  *     Map<Boolean, List<Student>> passingFailing =
  *         students.stream()
- *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
+ *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
  *
  * }</pre>
  *
@@ -103,15 +107,19 @@
  */
 public final class Collectors {
 
-    private static final Set<Collector.Characteristics> CH_CONCURRENT
+    static final Set<Collector.Characteristics> CH_CONCURRENT_ID
             = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
-                                                     Collector.Characteristics.STRICTLY_MUTATIVE,
+                                                     Collector.Characteristics.UNORDERED,
+                                                     Collector.Characteristics.IDENTITY_FINISH));
+    static final Set<Collector.Characteristics> CH_CONCURRENT_NOID
+            = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
                                                      Collector.Characteristics.UNORDERED));
-    private static final Set<Collector.Characteristics> CH_STRICT
-            = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.STRICTLY_MUTATIVE));
-    private static final Set<Collector.Characteristics> CH_STRICT_UNORDERED
-            = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.STRICTLY_MUTATIVE,
-                                                     Collector.Characteristics.UNORDERED));
+    static final Set<Collector.Characteristics> CH_ID
+            = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
+    static final Set<Collector.Characteristics> CH_UNORDERED_ID
+            = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED,
+                                                     Collector.Characteristics.IDENTITY_FINISH));
+    static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet();
 
     private Collectors() { }
 
@@ -124,88 +132,64 @@
      *
      * @param <T> the type of input arguments to the merge function
      * @return a merge function which always throw {@code IllegalStateException}
-     *
-     * @see #firstWinsMerger()
-     * @see #lastWinsMerger()
      */
-    public static <T> BinaryOperator<T> throwingMerger() {
+    private static <T> BinaryOperator<T> throwingMerger() {
         return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
     }
 
     /**
-     * Returns a merge function, suitable for use in
-     * {@link Map#merge(Object, Object, BiFunction) Map.merge()} or
-     * {@link #toMap(Function, Function, BinaryOperator) toMap()},
-     * which implements a "first wins" policy.
-     *
-     * @param <T> the type of input arguments to the merge function
-     * @return a merge function which always returns its first argument
-     * @see #lastWinsMerger()
-     * @see #throwingMerger()
-     */
-    public static <T> BinaryOperator<T> firstWinsMerger() {
-        return (u,v) -> u;
-    }
-
-    /**
-     * Returns a merge function, suitable for use in
-     * {@link Map#merge(Object, Object, BiFunction) Map.merge()} or
-     * {@link #toMap(Function, Function, BinaryOperator) toMap()},
-     * which implements a "last wins" policy.
-     *
-     * @param <T> the type of input arguments to the merge function
-     * @return a merge function which always returns its second argument
-     * @see #firstWinsMerger()
-     * @see #throwingMerger()
-     */
-    public static <T> BinaryOperator<T> lastWinsMerger() {
-        return (u,v) -> v;
-    }
-
-    /**
      * Simple implementation class for {@code Collector}.
      *
      * @param <T> the type of elements to be collected
      * @param <R> the type of the result
      */
-    private static final class CollectorImpl<T, R> implements Collector<T,R> {
-        private final Supplier<R> resultSupplier;
-        private final BiFunction<R, T, R> accumulator;
-        private final BinaryOperator<R> combiner;
+    static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
+        private final Supplier<A> supplier;
+        private final BiConsumer<A, T> accumulator;
+        private final BinaryOperator<A> combiner;
+        private final Function<A, R> finisher;
         private final Set<Characteristics> characteristics;
 
-        CollectorImpl(Supplier<R> resultSupplier,
-                      BiFunction<R, T, R> accumulator,
-                      BinaryOperator<R> combiner,
+        CollectorImpl(Supplier<A> supplier,
+                      BiConsumer<A, T> accumulator,
+                      BinaryOperator<A> combiner,
+                      Function<A,R> finisher,
                       Set<Characteristics> characteristics) {
-            this.resultSupplier = resultSupplier;
+            this.supplier = supplier;
             this.accumulator = accumulator;
             this.combiner = combiner;
+            this.finisher = finisher;
             this.characteristics = characteristics;
         }
 
-        CollectorImpl(Supplier<R> resultSupplier,
-                      BiFunction<R, T, R> accumulator,
-                      BinaryOperator<R> combiner) {
-            this(resultSupplier, accumulator, combiner, Collections.emptySet());
+        CollectorImpl(Supplier<A> supplier,