diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index 21ad635..756ec02 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -215,7 +215,7 @@
 LOCAL_SRC_FILES :=  $(call all-test-java-files-under, jsr166-tests)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart core-junit
+LOCAL_JAVA_LIBRARIES := core-oj core-libart core-lambda-stubs core-junit
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := jsr166-tests
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
diff --git a/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java b/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java
index 9e83de2..c293f13 100644
--- a/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AbstractExecutorServiceTest.java
@@ -18,6 +18,7 @@
 import java.util.concurrent.AbstractExecutorService;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
@@ -38,7 +39,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AbstractExecutorServiceTest.class);
     // }
 
     /**
@@ -196,28 +197,25 @@
     public void testInterruptedSubmit() throws InterruptedException {
         final CountDownLatch submitted    = new CountDownLatch(1);
         final CountDownLatch quittingTime = new CountDownLatch(1);
+        final Callable<Void> awaiter = new CheckedCallable<Void>() {
+            public Void realCall() throws InterruptedException {
+                assertTrue(quittingTime.await(2*LONG_DELAY_MS, MILLISECONDS));
+                return null;
+            }};
         final ExecutorService p
             = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS,
                                      new ArrayBlockingQueue<Runnable>(10));
-        final Callable<Void> awaiter = new CheckedCallable<Void>() {
-            public Void realCall() throws InterruptedException {
-                quittingTime.await();
-                return null;
-            }};
-        try {
-            Thread t = new Thread(new CheckedInterruptedRunnable() {
+        try (PoolCleaner cleaner = cleaner(p, quittingTime)) {
+            Thread t = newStartedThread(new CheckedInterruptedRunnable() {
                 public void realRun() throws Exception {
                     Future<Void> future = p.submit(awaiter);
                     submitted.countDown();
                     future.get();
                 }});
-            t.start();
-            submitted.await();
+
+            await(submitted);
             t.interrupt();
-            t.join();
-        } finally {
-            quittingTime.countDown();
-            joinPool(p);
+            awaitTermination(t);
         }
     }
 
@@ -226,34 +224,32 @@
      * throws exception
      */
     public void testSubmitEE() throws InterruptedException {
-        ThreadPoolExecutor p =
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    60, TimeUnit.SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-
-        Callable c = new Callable() {
-            public Object call() { throw new ArithmeticException(); }};
-
-        try {
-            p.submit(c).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof ArithmeticException);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            Callable c = new Callable() {
+                public Object call() { throw new ArithmeticException(); }};
+            try {
+                p.submit(c).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof ArithmeticException);
+            }
         }
-        joinPool(p);
     }
 
     /**
      * invokeAny(null) throws NPE
      */
     public void testInvokeAny1() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
-            e.invokeAny(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -261,13 +257,12 @@
      * invokeAny(empty collection) throws IAE
      */
     public void testInvokeAny2() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>());
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -275,17 +270,16 @@
      * invokeAny(c) throws NPE if c has null elements
      */
     public void testInvokeAny3() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        List<Callable<Long>> l = new ArrayList<Callable<Long>>();
-        l.add(new Callable<Long>() {
-            public Long call() { throw new ArithmeticException(); }});
-        l.add(null);
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<Long>> l = new ArrayList<Callable<Long>>();
+            l.add(new Callable<Long>() {
+                      public Long call() { throw new ArithmeticException(); }});
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -293,16 +287,16 @@
      * invokeAny(c) throws ExecutionException if no task in c completes
      */
     public void testInvokeAny4() throws InterruptedException {
-        ExecutorService e = new DirectExecutorService();
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -310,15 +304,13 @@
      * invokeAny(c) returns result of some task in c if at least one completes
      */
     public void testInvokeAny5() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             String result = e.invokeAny(l);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -326,13 +318,12 @@
      * invokeAll(null) throws NPE
      */
     public void testInvokeAll1() throws InterruptedException {
-        ExecutorService e = new DirectExecutorService();
-        try {
-            e.invokeAll(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -340,12 +331,10 @@
      * invokeAll(empty collection) returns empty collection
      */
     public void testInvokeAll2() throws InterruptedException {
-        ExecutorService e = new DirectExecutorService();
-        try {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -353,16 +342,15 @@
      * invokeAll(c) throws NPE if c has null elements
      */
     public void testInvokeAll3() throws InterruptedException {
-        ExecutorService e = new DirectExecutorService();
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -370,8 +358,8 @@
      * get of returned element of invokeAll(c) throws exception on failed task
      */
     public void testInvokeAll4() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new NPETask());
             List<Future<String>> futures = e.invokeAll(l);
@@ -382,8 +370,6 @@
             } catch (ExecutionException success) {
                 assertTrue(success.getCause() instanceof NullPointerException);
             }
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -391,8 +377,8 @@
      * invokeAll(c) returns results of all completed tasks in c
      */
     public void testInvokeAll5() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
@@ -400,8 +386,6 @@
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -409,13 +393,12 @@
      * timed invokeAny(null) throws NPE
      */
     public void testTimedInvokeAny1() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
-            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -423,15 +406,14 @@
      * timed invokeAny(null time unit) throws NPE
      */
     public void testTimedInvokeAnyNullTimeUnit() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -439,13 +421,13 @@
      * timed invokeAny(empty collection) throws IAE
      */
     public void testTimedInvokeAny2() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(),
+                            MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -453,17 +435,16 @@
      * timed invokeAny(c) throws NPE if c has null elements
      */
     public void testTimedInvokeAny3() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        List<Callable<Long>> l = new ArrayList<Callable<Long>>();
-        l.add(new Callable<Long>() {
-            public Long call() { throw new ArithmeticException(); }});
-        l.add(null);
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<Long>> l = new ArrayList<Callable<Long>>();
+            l.add(new Callable<Long>() {
+                      public Long call() { throw new ArithmeticException(); }});
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -471,16 +452,18 @@
      * timed invokeAny(c) throws ExecutionException if no task completes
      */
     public void testTimedInvokeAny4() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -488,15 +471,15 @@
      * timed invokeAny(c) returns result of some task in c
      */
     public void testTimedInvokeAny5() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -504,13 +487,12 @@
      * timed invokeAll(null) throws NPE
      */
     public void testTimedInvokeAll1() throws InterruptedException {
-        ExecutorService e = new DirectExecutorService();
-        try {
-            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -518,15 +500,14 @@
      * timed invokeAll(null time unit) throws NPE
      */
     public void testTimedInvokeAllNullTimeUnit() throws InterruptedException {
-        ExecutorService e = new DirectExecutorService();
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -534,12 +515,10 @@
      * timed invokeAll(empty collection) returns empty collection
      */
     public void testTimedInvokeAll2() throws InterruptedException {
-        ExecutorService e = new DirectExecutorService();
-        try {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -547,16 +526,15 @@
      * timed invokeAll(c) throws NPE if c has null elements
      */
     public void testTimedInvokeAll3() throws InterruptedException {
-        ExecutorService e = new DirectExecutorService();
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -564,12 +542,12 @@
      * get of returned element of invokeAll(c) throws exception on failed task
      */
     public void testTimedInvokeAll4() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new NPETask());
             List<Future<String>> futures =
-                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
             assertEquals(1, futures.size());
             try {
                 futures.get(0).get();
@@ -577,8 +555,6 @@
             } catch (ExecutionException success) {
                 assertTrue(success.getCause() instanceof NullPointerException);
             }
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -586,41 +562,51 @@
      * timed invokeAll(c) returns results of all completed tasks in c
      */
     public void testTimedInvokeAll5() throws Exception {
-        ExecutorService e = new DirectExecutorService();
-        try {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             List<Future<String>> futures =
-                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
     /**
      * timed invokeAll cancels tasks not completed by timeout
      */
-    public void testTimedInvokeAll6() throws InterruptedException {
-        ExecutorService e = new DirectExecutorService();
-        try {
-            List<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(Executors.callable(possiblyInterruptedRunnable(2 * SHORT_DELAY_MS), TEST_STRING));
-            l.add(new StringTask());
-            List<Future<String>> futures =
-                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
-            assertEquals(l.size(), futures.size());
-            for (Future future : futures)
-                assertTrue(future.isDone());
-            assertFalse(futures.get(0).isCancelled());
-            assertFalse(futures.get(1).isCancelled());
-            assertTrue(futures.get(2).isCancelled());
-        } finally {
-            joinPool(e);
+    public void testTimedInvokeAll6() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            for (long timeout = timeoutMillis();;) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(Executors.callable(possiblyInterruptedRunnable(timeout),
+                                             TEST_STRING));
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    e.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals(TEST_STRING, futures.get(1).get());
+                } catch (CancellationException retryWithLongerTimeout) {
+                    // unusual delay before starting second task
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                    continue;
+                }
+                assertTrue(futures.get(2).isCancelled());
+                break;
+            }
         }
     }
 
diff --git a/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java b/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java
index 2aa7326..bf25668 100644
--- a/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AbstractQueueTest.java
@@ -24,7 +24,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AbstractQueueTest.class);
     // }
 
     static class Succeed extends AbstractQueue<Integer> {
@@ -158,7 +158,7 @@
     public void testAddAll3() {
         Succeed q = new Succeed();
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         try {
             q.addAll(Arrays.asList(ints));
diff --git a/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java b/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java
index 8604d86..c462c73 100644
--- a/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AbstractQueuedLongSynchronizerTest.java
@@ -29,7 +29,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AbstractQueuedLongSynchronizerTest.class);
     // }
 
     /**
@@ -241,25 +241,33 @@
      */
     void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
         long timeoutMillis = timeoutMillis();
-        long startTime = System.nanoTime();
+        long startTime;
         try {
             switch (awaitMethod) {
             case awaitTimed:
+                startTime = System.nanoTime();
                 assertFalse(c.await(timeoutMillis, MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
                 break;
             case awaitNanos:
+                startTime = System.nanoTime();
                 long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
                 long nanosRemaining = c.awaitNanos(nanosTimeout);
                 assertTrue(nanosRemaining <= 0);
+                assertTrue(nanosRemaining > -MILLISECONDS.toNanos(LONG_DELAY_MS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
                 break;
             case awaitUntil:
+                // We shouldn't assume that nanoTime and currentTimeMillis
+                // use the same time source, so don't use nanoTime here.
+                java.util.Date delayedDate = delayedDate(timeoutMillis());
                 assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
+                assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
                 break;
             default:
                 throw new UnsupportedOperationException();
             }
         } catch (InterruptedException ie) { threadUnexpectedException(ie); }
-        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
     }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java b/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java
index b3c4110..d102fc6 100644
--- a/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AbstractQueuedSynchronizerTest.java
@@ -29,7 +29,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AbstractQueuedSynchronizerTest.class);
     // }
 
     /**
@@ -244,25 +244,33 @@
      */
     void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
         long timeoutMillis = timeoutMillis();
-        long startTime = System.nanoTime();
+        long startTime;
         try {
             switch (awaitMethod) {
             case awaitTimed:
+                startTime = System.nanoTime();
                 assertFalse(c.await(timeoutMillis, MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
                 break;
             case awaitNanos:
+                startTime = System.nanoTime();
                 long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
                 long nanosRemaining = c.awaitNanos(nanosTimeout);
                 assertTrue(nanosRemaining <= 0);
+                assertTrue(nanosRemaining > -MILLISECONDS.toNanos(LONG_DELAY_MS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
                 break;
             case awaitUntil:
+                // We shouldn't assume that nanoTime and currentTimeMillis
+                // use the same time source, so don't use nanoTime here.
+                java.util.Date delayedDate = delayedDate(timeoutMillis());
                 assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
+                assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
                 break;
             default:
                 throw new UnsupportedOperationException();
             }
         } catch (InterruptedException ie) { threadUnexpectedException(ie); }
-        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
     }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java
index 247c90e..902ae40 100644
--- a/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ArrayBlockingQueueTest.java
@@ -26,7 +26,7 @@
 
 public class ArrayBlockingQueueTest extends JSR166TestCase {
 
-    // android-note: These tests have been moved into their own separate 
+    // android-note: These tests have been moved into their own separate
     // classes to work around CTS issues.
     //
     // public static class Fair extends BlockingQueueTest {
@@ -34,17 +34,19 @@
     //         return new ArrayBlockingQueue(SIZE, true);
     //     }
     // }
-    //
+
     // public static class NonFair extends BlockingQueueTest {
     //     protected BlockingQueue emptyCollection() {
     //         return new ArrayBlockingQueue(SIZE, false);
     //     }
     // }
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
     //
     // public static void main(String[] args) {
     //     main(suite(), args);
     // }
-    //
     // public static Test suite() {
     //     return newTestSuite(ArrayBlockingQueueTest.class,
     //                         new Fair().testSuite(),
@@ -109,7 +111,7 @@
      */
     public void testConstructor5() {
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = i;
         Collection<Integer> elements = Arrays.asList(ints);
         try {
@@ -171,7 +173,7 @@
             assertEquals(i, q.remove());
         }
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.remainingCapacity());
+            assertEquals(SIZE - i, q.remainingCapacity());
             assertEquals(SIZE, q.size() + q.remainingCapacity());
             assertTrue(q.add(i));
         }
@@ -219,7 +221,7 @@
     public void testAddAll3() {
         ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         try {
             q.addAll(Arrays.asList(ints));
@@ -456,25 +458,23 @@
         final CountDownLatch aboutToWait = new CountDownLatch(1);
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
                 for (int i = 0; i < SIZE; ++i) {
-                    long t0 = System.nanoTime();
                     assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
-                    assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
                 }
-                long t0 = System.nanoTime();
                 aboutToWait.countDown();
                 try {
-                    q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
                     shouldThrow();
                 } catch (InterruptedException success) {
-                    assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
                 }
             }});
 
-        aboutToWait.await();
-        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+        await(aboutToWait);
+        waitForThreadToEnterWaitState(t, LONG_DELAY_MS);
         t.interrupt();
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
         checkEmpty(q);
     }
 
@@ -577,7 +577,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.remove();
         }
     }
@@ -590,7 +590,7 @@
             ArrayBlockingQueue q = populatedQueue(SIZE);
             ArrayBlockingQueue p = populatedQueue(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.remove());
                 assertFalse(q.contains(x));
@@ -624,23 +624,23 @@
             checkToArray(q);
             assertEquals(i, q.poll());
             checkToArray(q);
-            q.add(SIZE+i);
+            q.add(SIZE + i);
         }
         for (int i = 0; i < SIZE; i++) {
             checkToArray(q);
-            assertEquals(SIZE+i, q.poll());
+            assertEquals(SIZE + i, q.poll());
         }
     }
 
     void checkToArray2(ArrayBlockingQueue q) {
         int size = q.size();
-        Integer[] a1 = size == 0 ? null : new Integer[size-1];
+        Integer[] a1 = (size == 0) ? null : new Integer[size - 1];
         Integer[] a2 = new Integer[size];
-        Integer[] a3 = new Integer[size+2];
+        Integer[] a3 = new Integer[size + 2];
         if (size > 0) Arrays.fill(a1, 42);
         Arrays.fill(a2, 42);
         Arrays.fill(a3, 42);
-        Integer[] b1 = size == 0 ? null : (Integer[]) q.toArray(a1);
+        Integer[] b1 = (size == 0) ? null : (Integer[]) q.toArray(a1);
         Integer[] b2 = (Integer[]) q.toArray(a2);
         Integer[] b3 = (Integer[]) q.toArray(a3);
         assertSame(a2, b2);
@@ -654,7 +654,7 @@
             assertSame(b3[i], x);
         }
         assertNull(a3[size]);
-        assertEquals(42, (int) a3[size+1]);
+        assertEquals(42, (int) a3[size + 1]);
         if (size > 0) {
             assertNotSame(a1, b1);
             assertEquals(size, b1.length);
@@ -678,11 +678,11 @@
             checkToArray2(q);
             assertEquals(i, q.poll());
             checkToArray2(q);
-            q.add(SIZE+i);
+            q.add(SIZE + i);
         }
         for (int i = 0; i < SIZE; i++) {
             checkToArray2(q);
-            assertEquals(SIZE+i, q.poll());
+            assertEquals(SIZE + i, q.poll());
         }
     }
 
@@ -793,24 +793,24 @@
         final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
         q.add(one);
         q.add(two);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertFalse(q.offer(three));
-                threadsStarted.await();
-                assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
-                assertEquals(0, q.remainingCapacity());
-            }});
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(q.offer(three));
+                    threadsStarted.await();
+                    assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
+                    assertEquals(0, q.remainingCapacity());
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                assertEquals(0, q.remainingCapacity());
-                assertSame(one, q.take());
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertEquals(0, q.remainingCapacity());
+                    assertSame(one, q.take());
+                }});
+        }
     }
 
     /**
@@ -819,22 +819,22 @@
     public void testPollInExecutor() {
         final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertNull(q.poll());
-                threadsStarted.await();
-                assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
-                checkEmpty(q);
-            }});
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                q.put(one);
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
     }
 
     /**
@@ -886,7 +886,7 @@
         final ArrayBlockingQueue q = populatedQueue(SIZE);
         Thread t = new Thread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                q.put(new Integer(SIZE+1));
+                q.put(new Integer(SIZE + 1));
             }});
 
         t.start();
@@ -903,7 +903,7 @@
      * drainTo(c, n) empties first min(n, size) elements of queue into c
      */
     public void testDrainToN() {
-        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE*2);
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE * 2);
         for (int i = 0; i < SIZE + 2; ++i) {
             for (int j = 0; j < SIZE; j++)
                 assertTrue(q.offer(new Integer(j)));
@@ -911,7 +911,7 @@
             q.drainTo(l, i);
             int k = (i < SIZE) ? i : SIZE;
             assertEquals(k, l.size());
-            assertEquals(SIZE-k, q.size());
+            assertEquals(SIZE - k, q.size());
             for (int j = 0; j < k; ++j)
                 assertEquals(l.get(j), new Integer(j));
             do {} while (q.poll() != null);
diff --git a/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java b/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java
index 16290e9..23cc6b9 100644
--- a/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ArrayDequeTest.java
@@ -26,7 +26,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ArrayDequeTest.class);
     // }
 
     /**
@@ -65,8 +65,7 @@
      */
     public void testConstructor4() {
         try {
-            Integer[] ints = new Integer[SIZE];
-            new ArrayDeque(Arrays.asList(ints));
+            new ArrayDeque(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -75,10 +74,10 @@
      * Initializing from Collection with some null elements throws NPE
      */
     public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             new ArrayDeque(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -116,7 +115,7 @@
     public void testSize() {
         ArrayDeque q = populatedDeque(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.removeFirst();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -129,8 +128,8 @@
      * push(null) throws NPE
      */
     public void testPushNull() {
+        ArrayDeque q = new ArrayDeque(1);
         try {
-            ArrayDeque q = new ArrayDeque(1);
             q.push(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -164,8 +163,8 @@
      * offer(null) throws NPE
      */
     public void testOfferNull() {
+        ArrayDeque q = new ArrayDeque();
         try {
-            ArrayDeque q = new ArrayDeque();
             q.offer(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -175,8 +174,8 @@
      * offerFirst(null) throws NPE
      */
     public void testOfferFirstNull() {
+        ArrayDeque q = new ArrayDeque();
         try {
-            ArrayDeque q = new ArrayDeque();
             q.offerFirst(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -186,8 +185,8 @@
      * offerLast(null) throws NPE
      */
     public void testOfferLastNull() {
+        ArrayDeque q = new ArrayDeque();
         try {
-            ArrayDeque q = new ArrayDeque();
             q.offerLast(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -230,8 +229,8 @@
      * add(null) throws NPE
      */
     public void testAddNull() {
+        ArrayDeque q = new ArrayDeque();
         try {
-            ArrayDeque q = new ArrayDeque();
             q.add(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -241,8 +240,8 @@
      * addFirst(null) throws NPE
      */
     public void testAddFirstNull() {
+        ArrayDeque q = new ArrayDeque();
         try {
-            ArrayDeque q = new ArrayDeque();
             q.addFirst(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -252,8 +251,8 @@
      * addLast(null) throws NPE
      */
     public void testAddLastNull() {
+        ArrayDeque q = new ArrayDeque();
         try {
-            ArrayDeque q = new ArrayDeque();
             q.addLast(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -296,8 +295,8 @@
      * addAll(null) throws NPE
      */
     public void testAddAll1() {
+        ArrayDeque q = new ArrayDeque();
         try {
-            ArrayDeque q = new ArrayDeque();
             q.addAll(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -307,10 +306,9 @@
      * addAll of a collection with null elements throws NPE
      */
     public void testAddAll2() {
+        ArrayDeque q = new ArrayDeque();
         try {
-            ArrayDeque q = new ArrayDeque();
-            Integer[] ints = new Integer[SIZE];
-            q.addAll(Arrays.asList(ints));
+            q.addAll(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -320,11 +318,11 @@
      * possibly adding some elements
      */
     public void testAddAll3() {
+        ArrayDeque q = new ArrayDeque();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            ArrayDeque q = new ArrayDeque();
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -361,7 +359,7 @@
      */
     public void testPollLast() {
         ArrayDeque q = populatedDeque(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.pollLast());
         }
         assertNull(q.pollLast());
@@ -401,14 +399,14 @@
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertTrue(q.contains(i-1));
+            assertTrue(q.contains(i - 1));
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertFalse(q.remove(i+1));
-            assertFalse(q.contains(i+1));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
         }
         assertTrue(q.isEmpty());
     }
@@ -446,7 +444,7 @@
      */
     public void testPeekLast() {
         ArrayDeque q = populatedDeque(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.peekLast());
             assertEquals(i, q.pollLast());
             assertTrue(q.peekLast() == null ||
@@ -490,7 +488,7 @@
      */
     public void testLastElement() {
         ArrayDeque q = populatedDeque(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.getLast());
             assertEquals(i, q.pollLast());
         }
@@ -541,7 +539,7 @@
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.removeFirstOccurrence(new Integer(i)));
-            assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+            assertFalse(q.removeFirstOccurrence(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
@@ -556,7 +554,7 @@
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.removeLastOccurrence(new Integer(i)));
-            assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+            assertFalse(q.removeLastOccurrence(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
@@ -611,7 +609,7 @@
             boolean changed = q.retainAll(p);
             assertEquals(changed, (i > 0));
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.removeFirst();
         }
     }
@@ -624,7 +622,7 @@
             ArrayDeque q = populatedDeque(SIZE);
             ArrayDeque p = populatedDeque(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 assertFalse(q.contains(p.removeFirst()));
             }
@@ -656,23 +654,23 @@
         for (int i = 0; i < SIZE; i++) {
             checkToArray(q);
             assertEquals(i, q.poll());
-            q.addLast(SIZE+i);
+            q.addLast(SIZE + i);
         }
         for (int i = 0; i < SIZE; i++) {
             checkToArray(q);
-            assertEquals(SIZE+i, q.poll());
+            assertEquals(SIZE + i, q.poll());
         }
     }
 
     void checkToArray2(ArrayDeque q) {
         int size = q.size();
-        Integer[] a1 = size == 0 ? null : new Integer[size-1];
+        Integer[] a1 = (size == 0) ? null : new Integer[size - 1];
         Integer[] a2 = new Integer[size];
-        Integer[] a3 = new Integer[size+2];
+        Integer[] a3 = new Integer[size + 2];
         if (size > 0) Arrays.fill(a1, 42);
         Arrays.fill(a2, 42);
         Arrays.fill(a3, 42);
-        Integer[] b1 = size == 0 ? null : (Integer[]) q.toArray(a1);
+        Integer[] b1 = (size == 0) ? null : (Integer[]) q.toArray(a1);
         Integer[] b2 = (Integer[]) q.toArray(a2);
         Integer[] b3 = (Integer[]) q.toArray(a3);
         assertSame(a2, b2);
@@ -686,7 +684,7 @@
             assertSame(b3[i], x);
         }
         assertNull(a3[size]);
-        assertEquals(42, (int) a3[size+1]);
+        assertEquals(42, (int) a3[size + 1]);
         if (size > 0) {
             assertNotSame(a1, b1);
             assertEquals(size, b1.length);
@@ -709,11 +707,11 @@
         for (int i = 0; i < SIZE; i++) {
             checkToArray2(q);
             assertEquals(i, q.poll());
-            q.addLast(SIZE+i);
+            q.addLast(SIZE + i);
         }
         for (int i = 0; i < SIZE; i++) {
             checkToArray2(q);
-            assertEquals(SIZE+i, q.poll());
+            assertEquals(SIZE + i, q.poll());
         }
     }
 
@@ -787,18 +785,18 @@
         final Random rng = new Random();
         for (int iters = 0; iters < 100; ++iters) {
             int max = rng.nextInt(5) + 2;
-            int split = rng.nextInt(max-1) + 1;
+            int split = rng.nextInt(max - 1) + 1;
             for (int j = 1; j <= max; ++j)
                 q.add(new Integer(j));
             Iterator it = q.iterator();
             for (int j = 1; j <= split; ++j)
                 assertEquals(it.next(), new Integer(j));
             it.remove();
-            assertEquals(it.next(), new Integer(split+1));
+            assertEquals(it.next(), new Integer(split + 1));
             for (int j = 1; j <= split; ++j)
                 q.remove(new Integer(j));
             it = q.iterator();
-            for (int j = split+1; j <= max; ++j) {
+            for (int j = split + 1; j <= max; ++j) {
                 assertEquals(it.next(), new Integer(j));
                 it.remove();
             }
@@ -855,18 +853,18 @@
         final Random rng = new Random();
         for (int iters = 0; iters < 100; ++iters) {
             int max = rng.nextInt(5) + 2;
-            int split = rng.nextInt(max-1) + 1;
+            int split = rng.nextInt(max - 1) + 1;
             for (int j = max; j >= 1; --j)
                 q.add(new Integer(j));
             Iterator it = q.descendingIterator();
             for (int j = 1; j <= split; ++j)
                 assertEquals(it.next(), new Integer(j));
             it.remove();
-            assertEquals(it.next(), new Integer(split+1));
+            assertEquals(it.next(), new Integer(split + 1));
             for (int j = 1; j <= split; ++j)
                 q.remove(new Integer(j));
             it = q.descendingIterator();
-            for (int j = split+1; j <= max; ++j) {
+            for (int j = split + 1; j <= max; ++j) {
                 assertEquals(it.next(), new Integer(j));
                 it.remove();
             }
diff --git a/jsr166-tests/src/test/java/jsr166/Atomic8Test.java b/jsr166-tests/src/test/java/jsr166/Atomic8Test.java
new file mode 100644
index 0000000..f81c44f
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/Atomic8Test.java
@@ -0,0 +1,574 @@
+/*
+ * Written by Doug Lea and Martin Buchholz 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 jsr166;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicLongArray;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class Atomic8Test extends JSR166TestCase {
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(Atomic8Test.class);
+    // }
+
+    /*
+     * Tests of atomic class methods accepting lambdas
+     * introduced in JDK8.
+     */
+
+    static long addLong17(long x) { return x + 17; }
+    static int addInt17(int x) { return x + 17; }
+    static Integer addInteger17(Integer x) {
+        return new Integer(x.intValue() + 17);
+    }
+    static Integer sumInteger(Integer x, Integer y) {
+        return new Integer(x.intValue() + y.intValue());
+    }
+
+    volatile long aLongField;
+    volatile int anIntField;
+    volatile Integer anIntegerField;
+
+    AtomicLongFieldUpdater aLongFieldUpdater() {
+        return AtomicLongFieldUpdater.newUpdater
+            (Atomic8Test.class, "aLongField");
+    }
+
+    AtomicIntegerFieldUpdater anIntFieldUpdater() {
+        return AtomicIntegerFieldUpdater.newUpdater
+            (Atomic8Test.class, "anIntField");
+    }
+
+    AtomicReferenceFieldUpdater<Atomic8Test,Integer> anIntegerFieldUpdater() {
+        return AtomicReferenceFieldUpdater.newUpdater
+            (Atomic8Test.class, Integer.class, "anIntegerField");
+    }
+
+    /**
+     * AtomicLong getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testLongGetAndUpdate() {
+        AtomicLong a = new AtomicLong(1L);
+        assertEquals(1L, a.getAndUpdate(Atomic8Test::addLong17));
+        assertEquals(18L, a.getAndUpdate(Atomic8Test::addLong17));
+        assertEquals(35L, a.get());
+    }
+
+    /**
+     * AtomicLong updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongUpdateAndGet() {
+        AtomicLong a = new AtomicLong(1L);
+        assertEquals(18L, a.updateAndGet(Atomic8Test::addLong17));
+        assertEquals(35L, a.updateAndGet(Atomic8Test::addLong17));
+    }
+
+    /**
+     * AtomicLong getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testLongGetAndAccumulate() {
+        AtomicLong a = new AtomicLong(1L);
+        assertEquals(1L, a.getAndAccumulate(2L, Long::sum));
+        assertEquals(3L, a.getAndAccumulate(3L, Long::sum));
+        assertEquals(6L, a.get());
+    }
+
+    /**
+     * AtomicLong accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongAccumulateAndGet() {
+        AtomicLong a = new AtomicLong(1L);
+        assertEquals(7L, a.accumulateAndGet(6L, Long::sum));
+        assertEquals(10L, a.accumulateAndGet(3L, Long::sum));
+        assertEquals(10L, a.get());
+    }
+
+    /**
+     * AtomicInteger getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testIntGetAndUpdate() {
+        AtomicInteger a = new AtomicInteger(1);
+        assertEquals(1, a.getAndUpdate(Atomic8Test::addInt17));
+        assertEquals(18, a.getAndUpdate(Atomic8Test::addInt17));
+        assertEquals(35, a.get());
+    }
+
+    /**
+     * AtomicInteger updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntUpdateAndGet() {
+        AtomicInteger a = new AtomicInteger(1);
+        assertEquals(18, a.updateAndGet(Atomic8Test::addInt17));
+        assertEquals(35, a.updateAndGet(Atomic8Test::addInt17));
+        assertEquals(35, a.get());
+    }
+
+    /**
+     * AtomicInteger getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testIntGetAndAccumulate() {
+        AtomicInteger a = new AtomicInteger(1);
+        assertEquals(1, a.getAndAccumulate(2, Integer::sum));
+        assertEquals(3, a.getAndAccumulate(3, Integer::sum));
+        assertEquals(6, a.get());
+    }
+
+    /**
+     * AtomicInteger accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntAccumulateAndGet() {
+        AtomicInteger a = new AtomicInteger(1);
+        assertEquals(7, a.accumulateAndGet(6, Integer::sum));
+        assertEquals(10, a.accumulateAndGet(3, Integer::sum));
+        assertEquals(10, a.get());
+    }
+
+    /**
+     * AtomicReference getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testReferenceGetAndUpdate() {
+        AtomicReference<Integer> a = new AtomicReference<Integer>(one);
+        assertEquals(new Integer(1), a.getAndUpdate(Atomic8Test::addInteger17));
+        assertEquals(new Integer(18), a.getAndUpdate(Atomic8Test::addInteger17));
+        assertEquals(new Integer(35), a.get());
+    }
+
+    /**
+     * AtomicReference updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testReferenceUpdateAndGet() {
+        AtomicReference<Integer> a = new AtomicReference<Integer>(one);
+        assertEquals(new Integer(18), a.updateAndGet(Atomic8Test::addInteger17));
+        assertEquals(new Integer(35), a.updateAndGet(Atomic8Test::addInteger17));
+        assertEquals(new Integer(35), a.get());
+    }
+
+    /**
+     * AtomicReference getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testReferenceGetAndAccumulate() {
+        AtomicReference<Integer> a = new AtomicReference<Integer>(one);
+        assertEquals(new Integer(1), a.getAndAccumulate(2, Atomic8Test::sumInteger));
+        assertEquals(new Integer(3), a.getAndAccumulate(3, Atomic8Test::sumInteger));
+        assertEquals(new Integer(6), a.get());
+    }
+
+    /**
+     * AtomicReference accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testReferenceAccumulateAndGet() {
+        AtomicReference<Integer> a = new AtomicReference<Integer>(one);
+        assertEquals(new Integer(7), a.accumulateAndGet(6, Atomic8Test::sumInteger));
+        assertEquals(new Integer(10), a.accumulateAndGet(3, Atomic8Test::sumInteger));
+        assertEquals(new Integer(10), a.get());
+    }
+
+    /**
+     * AtomicLongArray getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testLongArrayGetAndUpdate() {
+        AtomicLongArray a = new AtomicLongArray(1);
+        a.set(0, 1);
+        assertEquals(1L, a.getAndUpdate(0, Atomic8Test::addLong17));
+        assertEquals(18L, a.getAndUpdate(0, Atomic8Test::addLong17));
+        assertEquals(35L, a.get(0));
+    }
+
+    /**
+     * AtomicLongArray updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongArrayUpdateAndGet() {
+        AtomicLongArray a = new AtomicLongArray(1);
+        a.set(0, 1);
+        assertEquals(18L, a.updateAndGet(0, Atomic8Test::addLong17));
+        assertEquals(35L, a.updateAndGet(0, Atomic8Test::addLong17));
+        assertEquals(35L, a.get(0));
+    }
+
+    /**
+     * AtomicLongArray getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testLongArrayGetAndAccumulate() {
+        AtomicLongArray a = new AtomicLongArray(1);
+        a.set(0, 1);
+        assertEquals(1L, a.getAndAccumulate(0, 2L, Long::sum));
+        assertEquals(3L, a.getAndAccumulate(0, 3L, Long::sum));
+        assertEquals(6L, a.get(0));
+    }
+
+    /**
+     * AtomicLongArray accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongArrayAccumulateAndGet() {
+        AtomicLongArray a = new AtomicLongArray(1);
+        a.set(0, 1);
+        assertEquals(7L, a.accumulateAndGet(0, 6L, Long::sum));
+        assertEquals(10L, a.accumulateAndGet(0, 3L, Long::sum));
+        assertEquals(10L, a.get(0));
+    }
+
+    /**
+     * AtomicIntegerArray getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testIntArrayGetAndUpdate() {
+        AtomicIntegerArray a = new AtomicIntegerArray(1);
+        a.set(0, 1);
+        assertEquals(1, a.getAndUpdate(0, Atomic8Test::addInt17));
+        assertEquals(18, a.getAndUpdate(0, Atomic8Test::addInt17));
+        assertEquals(35, a.get(0));
+    }
+
+    /**
+     * AtomicIntegerArray updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntArrayUpdateAndGet() {
+        AtomicIntegerArray a = new AtomicIntegerArray(1);
+        a.set(0, 1);
+        assertEquals(18, a.updateAndGet(0, Atomic8Test::addInt17));
+        assertEquals(35, a.updateAndGet(0, Atomic8Test::addInt17));
+        assertEquals(35, a.get(0));
+    }
+
+    /**
+     * AtomicIntegerArray getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testIntArrayGetAndAccumulate() {
+        AtomicIntegerArray a = new AtomicIntegerArray(1);
+        a.set(0, 1);
+        assertEquals(1, a.getAndAccumulate(0, 2, Integer::sum));
+        assertEquals(3, a.getAndAccumulate(0, 3, Integer::sum));
+        assertEquals(6, a.get(0));
+    }
+
+    /**
+     * AtomicIntegerArray accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntArrayAccumulateAndGet() {
+        AtomicIntegerArray a = new AtomicIntegerArray(1);
+        a.set(0, 1);
+        assertEquals(7, a.accumulateAndGet(0, 6, Integer::sum));
+        assertEquals(10, a.accumulateAndGet(0, 3, Integer::sum));
+    }
+
+    /**
+     * AtomicReferenceArray getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testReferenceArrayGetAndUpdate() {
+        AtomicReferenceArray<Integer> a = new AtomicReferenceArray<Integer>(1);
+        a.set(0, one);
+        assertEquals(new Integer(1), a.getAndUpdate(0, Atomic8Test::addInteger17));
+        assertEquals(new Integer(18), a.getAndUpdate(0, Atomic8Test::addInteger17));
+        assertEquals(new Integer(35), a.get(0));
+    }
+
+    /**
+     * AtomicReferenceArray updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testReferenceArrayUpdateAndGet() {
+        AtomicReferenceArray<Integer> a = new AtomicReferenceArray<Integer>(1);
+        a.set(0, one);
+        assertEquals(new Integer(18), a.updateAndGet(0, Atomic8Test::addInteger17));
+        assertEquals(new Integer(35), a.updateAndGet(0, Atomic8Test::addInteger17));
+    }
+
+    /**
+     * AtomicReferenceArray getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testReferenceArrayGetAndAccumulate() {
+        AtomicReferenceArray<Integer> a = new AtomicReferenceArray<Integer>(1);
+        a.set(0, one);
+        assertEquals(new Integer(1), a.getAndAccumulate(0, 2, Atomic8Test::sumInteger));
+        assertEquals(new Integer(3), a.getAndAccumulate(0, 3, Atomic8Test::sumInteger));
+        assertEquals(new Integer(6), a.get(0));
+    }
+
+    /**
+     * AtomicReferenceArray accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testReferenceArrayAccumulateAndGet() {
+        AtomicReferenceArray<Integer> a = new AtomicReferenceArray<Integer>(1);
+        a.set(0, one);
+        assertEquals(new Integer(7), a.accumulateAndGet(0, 6, Atomic8Test::sumInteger));
+        assertEquals(new Integer(10), a.accumulateAndGet(0, 3, Atomic8Test::sumInteger));
+    }
+
+    /**
+     * AtomicLongFieldUpdater getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testLongFieldUpdaterGetAndUpdate() {
+        AtomicLongFieldUpdater a = aLongFieldUpdater();
+        a.set(this, 1);
+        assertEquals(1L, a.getAndUpdate(this, Atomic8Test::addLong17));
+        assertEquals(18L, a.getAndUpdate(this, Atomic8Test::addLong17));
+        assertEquals(35L, a.get(this));
+        assertEquals(35L, aLongField);
+    }
+
+    /**
+     * AtomicLongFieldUpdater updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongFieldUpdaterUpdateAndGet() {
+        AtomicLongFieldUpdater a = aLongFieldUpdater();
+        a.set(this, 1);
+        assertEquals(18L, a.updateAndGet(this, Atomic8Test::addLong17));
+        assertEquals(35L, a.updateAndGet(this, Atomic8Test::addLong17));
+        assertEquals(35L, a.get(this));
+        assertEquals(35L, aLongField);
+    }
+
+    /**
+     * AtomicLongFieldUpdater getAndAccumulate returns previous value
+     * and updates with supplied function.
+     */
+    public void testLongFieldUpdaterGetAndAccumulate() {
+        AtomicLongFieldUpdater a = aLongFieldUpdater();
+        a.set(this, 1);
+        assertEquals(1L, a.getAndAccumulate(this, 2L, Long::sum));
+        assertEquals(3L, a.getAndAccumulate(this, 3L, Long::sum));
+        assertEquals(6L, a.get(this));
+        assertEquals(6L, aLongField);
+    }
+
+    /**
+     * AtomicLongFieldUpdater accumulateAndGet updates with supplied
+     * function and returns result.
+     */
+    public void testLongFieldUpdaterAccumulateAndGet() {
+        AtomicLongFieldUpdater a = aLongFieldUpdater();
+        a.set(this, 1);
+        assertEquals(7L, a.accumulateAndGet(this, 6L, Long::sum));
+        assertEquals(10L, a.accumulateAndGet(this, 3L, Long::sum));
+        assertEquals(10L, a.get(this));
+        assertEquals(10L, aLongField);
+    }
+
+    /**
+     * AtomicIntegerFieldUpdater getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testIntegerFieldUpdaterGetAndUpdate() {
+        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
+        a.set(this, 1);
+        assertEquals(1, a.getAndUpdate(this, Atomic8Test::addInt17));
+        assertEquals(18, a.getAndUpdate(this, Atomic8Test::addInt17));
+        assertEquals(35, a.get(this));
+        assertEquals(35, anIntField);
+    }
+
+    /**
+     * AtomicIntegerFieldUpdater updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntegerFieldUpdaterUpdateAndGet() {
+        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
+        a.set(this, 1);
+        assertEquals(18, a.updateAndGet(this, Atomic8Test::addInt17));
+        assertEquals(35, a.updateAndGet(this, Atomic8Test::addInt17));
+        assertEquals(35, a.get(this));
+        assertEquals(35, anIntField);
+    }
+
+    /**
+     * AtomicIntegerFieldUpdater getAndAccumulate returns previous value
+     * and updates with supplied function.
+     */
+    public void testIntegerFieldUpdaterGetAndAccumulate() {
+        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
+        a.set(this, 1);
+        assertEquals(1, a.getAndAccumulate(this, 2, Integer::sum));
+        assertEquals(3, a.getAndAccumulate(this, 3, Integer::sum));
+        assertEquals(6, a.get(this));
+        assertEquals(6, anIntField);
+    }
+
+    /**
+     * AtomicIntegerFieldUpdater accumulateAndGet updates with supplied
+     * function and returns result.
+     */
+    public void testIntegerFieldUpdaterAccumulateAndGet() {
+        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
+        a.set(this, 1);
+        assertEquals(7, a.accumulateAndGet(this, 6, Integer::sum));
+        assertEquals(10, a.accumulateAndGet(this, 3, Integer::sum));
+        assertEquals(10, a.get(this));
+        assertEquals(10, anIntField);
+    }
+
+    /**
+     * AtomicReferenceFieldUpdater getAndUpdate returns previous value
+     * and updates result of supplied function
+     */
+    public void testReferenceFieldUpdaterGetAndUpdate() {
+        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
+        a.set(this, one);
+        assertEquals(new Integer(1), a.getAndUpdate(this, Atomic8Test::addInteger17));
+        assertEquals(new Integer(18), a.getAndUpdate(this, Atomic8Test::addInteger17));
+        assertEquals(new Integer(35), a.get(this));
+        assertEquals(new Integer(35), anIntegerField);
+    }
+
+    /**
+     * AtomicReferenceFieldUpdater updateAndGet updates with supplied
+     * function and returns result.
+     */
+    public void testReferenceFieldUpdaterUpdateAndGet() {
+        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
+        a.set(this, one);
+        assertEquals(new Integer(18), a.updateAndGet(this, Atomic8Test::addInteger17));
+        assertEquals(new Integer(35), a.updateAndGet(this, Atomic8Test::addInteger17));
+        assertEquals(new Integer(35), a.get(this));
+        assertEquals(new Integer(35), anIntegerField);
+    }
+
+    /**
+     * AtomicReferenceFieldUpdater returns previous value and updates
+     * with supplied function.
+     */
+    public void testReferenceFieldUpdaterGetAndAccumulate() {
+        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
+        a.set(this, one);
+        assertEquals(new Integer(1), a.getAndAccumulate(this, 2, Atomic8Test::sumInteger));
+        assertEquals(new Integer(3), a.getAndAccumulate(this, 3, Atomic8Test::sumInteger));
+        assertEquals(new Integer(6), a.get(this));
+        assertEquals(new Integer(6), anIntegerField);
+    }
+
+    /**
+     * AtomicReferenceFieldUpdater accumulateAndGet updates with
+     * supplied function and returns result.
+     */
+    public void testReferenceFieldUpdaterAccumulateAndGet() {
+        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
+        a.set(this, one);
+        assertEquals(new Integer(7), a.accumulateAndGet(this, 6, Atomic8Test::sumInteger));
+        assertEquals(new Integer(10), a.accumulateAndGet(this, 3, Atomic8Test::sumInteger));
+        assertEquals(new Integer(10), a.get(this));
+        assertEquals(new Integer(10), anIntegerField);
+    }
+
+    /**
+     * All Atomic getAndUpdate methods throw NullPointerException on
+     * null function argument
+     */
+    public void testGetAndUpdateNPE() {
+        Runnable[] throwingActions = {
+            () -> new AtomicLong().getAndUpdate(null),
+            () -> new AtomicInteger().getAndUpdate(null),
+            () -> new AtomicReference().getAndUpdate(null),
+            () -> new AtomicLongArray(1).getAndUpdate(0, null),
+            () -> new AtomicIntegerArray(1).getAndUpdate(0, null),
+            () -> new AtomicReferenceArray(1).getAndUpdate(0, null),
+            () -> aLongFieldUpdater().getAndUpdate(this, null),
+            () -> anIntFieldUpdater().getAndUpdate(this, null),
+            () -> anIntegerFieldUpdater().getAndUpdate(this, null),
+            ////() -> aLongFieldUpdater().getAndUpdate(null, Atomic8Test::addLong17),
+            ////() -> anIntFieldUpdater().getAndUpdate(null, Atomic8Test::addInt17),
+            ////() -> anIntegerFieldUpdater().getAndUpdate(null, Atomic8Test::addInteger17),
+        };
+        assertThrows(NullPointerException.class, throwingActions);
+    }
+
+    /**
+     * All Atomic updateAndGet methods throw NullPointerException on null function argument
+     */
+    public void testUpdateAndGetNPE() {
+        Runnable[] throwingActions = {
+            () -> new AtomicLong().updateAndGet(null),
+            () -> new AtomicInteger().updateAndGet(null),
+            () -> new AtomicReference().updateAndGet(null),
+            () -> new AtomicLongArray(1).updateAndGet(0, null),
+            () -> new AtomicIntegerArray(1).updateAndGet(0, null),
+            () -> new AtomicReferenceArray(1).updateAndGet(0, null),
+            () -> aLongFieldUpdater().updateAndGet(this, null),
+            () -> anIntFieldUpdater().updateAndGet(this, null),
+            () -> anIntegerFieldUpdater().updateAndGet(this, null),
+        };
+        assertThrows(NullPointerException.class, throwingActions);
+    }
+
+    /**
+     * All Atomic getAndAccumulate methods throw NullPointerException
+     * on null function argument
+     */
+    public void testGetAndAccumulateNPE() {
+        Runnable[] throwingActions = {
+            () -> new AtomicLong().getAndAccumulate(1L, null),
+            () -> new AtomicInteger().getAndAccumulate(1, null),
+            () -> new AtomicReference().getAndAccumulate(one, null),
+            () -> new AtomicLongArray(1).getAndAccumulate(0, 1L, null),
+            () -> new AtomicIntegerArray(1).getAndAccumulate(0, 1, null),
+            () -> new AtomicReferenceArray(1).getAndAccumulate(0, one, null),
+            () -> aLongFieldUpdater().getAndAccumulate(this, 1L, null),
+            () -> anIntFieldUpdater().getAndAccumulate(this, 1, null),
+            () -> anIntegerFieldUpdater().getAndAccumulate(this, one, null),
+        };
+        assertThrows(NullPointerException.class, throwingActions);
+    }
+
+    /**
+     * All Atomic accumulateAndGet methods throw NullPointerException
+     * on null function argument
+     */
+    public void testAccumulateAndGetNPE() {
+        Runnable[] throwingActions = {
+            () -> new AtomicLong().accumulateAndGet(1L, null),
+            () -> new AtomicInteger().accumulateAndGet(1, null),
+            () -> new AtomicReference().accumulateAndGet(one, null),
+            () -> new AtomicLongArray(1).accumulateAndGet(0, 1L, null),
+            () -> new AtomicIntegerArray(1).accumulateAndGet(0, 1, null),
+            () -> new AtomicReferenceArray(1).accumulateAndGet(0, one, null),
+            () -> aLongFieldUpdater().accumulateAndGet(this, 1L, null),
+            () -> anIntFieldUpdater().accumulateAndGet(this, 1, null),
+            () -> anIntegerFieldUpdater().accumulateAndGet(this, one, null),
+        };
+        assertThrows(NullPointerException.class, throwingActions);
+    }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java b/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java
index bfe3fc6..6f5decf 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicBooleanTest.java
@@ -21,7 +21,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicBooleanTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java
index 670b9ce..c9e32aa 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerArrayTest.java
@@ -15,6 +15,7 @@
 import junit.framework.TestSuite;
 
 public class AtomicIntegerArrayTest extends JSR166TestCase {
+
     // android-note: Removed because the CTS runner does a bad job of
     // retrying tests that have suite() declarations.
     //
@@ -22,7 +23,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicIntegerArrayTest.class);
     // }
 
     /**
@@ -290,7 +291,7 @@
                     assertTrue(v >= 0);
                     if (v != 0) {
                         done = false;
-                        if (aa.compareAndSet(i, v, v-1))
+                        if (aa.compareAndSet(i, v, v - 1))
                             ++counts;
                     }
                 }
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
index ef75b46..c8d3856 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerFieldUpdaterTest.java
@@ -15,8 +15,10 @@
 
 public class AtomicIntegerFieldUpdaterTest extends JSR166TestCase {
     volatile int x = 0;
+    protected volatile int protectedField;
+    private volatile int privateField;
     int w;
-    long z;
+    float z;
     // android-note: Removed because the CTS runner does a bad job of
     // retrying tests that have suite() declarations.
     //
@@ -24,7 +26,59 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicIntegerFieldUpdaterTest.class);
+    // }
+
+    // for testing subclass access
+    // android-note: Removed because android doesn't restrict reflection access
+    // static class AtomicIntegerFieldUpdaterTestSubclass extends AtomicIntegerFieldUpdaterTest {
+    //     public void checkPrivateAccess() {
+    //         try {
+    //             AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+    //                 AtomicIntegerFieldUpdater.newUpdater
+    //                 (AtomicIntegerFieldUpdaterTest.class, "privateField");
+    //             shouldThrow();
+    //         } catch (RuntimeException success) {
+    //             assertNotNull(success.getCause());
+    //         }
+    //     }
+
+    //     public void checkCompareAndSetProtectedSub() {
+    //         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+    //             AtomicIntegerFieldUpdater.newUpdater
+    //             (AtomicIntegerFieldUpdaterTest.class, "protectedField");
+    //         this.protectedField = 1;
+    //         assertTrue(a.compareAndSet(this, 1, 2));
+    //         assertTrue(a.compareAndSet(this, 2, -4));
+    //         assertEquals(-4, a.get(this));
+    //         assertFalse(a.compareAndSet(this, -5, 7));
+    //         assertEquals(-4, a.get(this));
+    //         assertTrue(a.compareAndSet(this, -4, 7));
+    //         assertEquals(7, a.get(this));
+    //     }
+    // }
+
+    // static class UnrelatedClass {
+    //     public void checkPackageAccess(AtomicIntegerFieldUpdaterTest obj) {
+    //         obj.x = 72;
+    //         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+    //             AtomicIntegerFieldUpdater.newUpdater
+    //             (AtomicIntegerFieldUpdaterTest.class, "x");
+    //         assertEquals(72, a.get(obj));
+    //         assertTrue(a.compareAndSet(obj, 72, 73));
+    //         assertEquals(73, a.get(obj));
+    //     }
+
+    //     public void checkPrivateAccess(AtomicIntegerFieldUpdaterTest obj) {
+    //         try {
+    //             AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
+    //                 AtomicIntegerFieldUpdater.newUpdater
+    //                 (AtomicIntegerFieldUpdaterTest.class, "privateField");
+    //             throw new AssertionError("should throw");
+    //         } catch (RuntimeException success) {
+    //             assertNotNull(success.getCause());
+    //         }
+    //     }
     // }
 
     AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) {
@@ -65,6 +119,26 @@
     }
 
     /**
+     * construction using private field from subclass throws RuntimeException
+     */
+    // android-note: Removed because android doesn't restrict reflection access
+    // public void testPrivateFieldInSubclass() {
+    //     AtomicIntegerFieldUpdaterTestSubclass s =
+    //         new AtomicIntegerFieldUpdaterTestSubclass();
+    //     s.checkPrivateAccess();
+    // }
+
+    /**
+     * construction from unrelated class; package access is allowed,
+     * private access is not
+     */
+    // android-note: Removed because android doesn't restrict reflection access
+    // public void testUnrelatedClassAccess() {
+    //     new UnrelatedClass().checkPackageAccess(this);
+    //     new UnrelatedClass().checkPrivateAccess(this);
+    // }
+
+    /**
      * get returns the last value set or assigned
      */
     public void testGetSet() {
@@ -109,6 +183,34 @@
     }
 
     /**
+     * compareAndSet succeeds in changing protected field value if
+     * equal to expected else fails
+     */
+    public void testCompareAndSetProtected() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("protectedField");
+        protectedField = 1;
+        assertTrue(a.compareAndSet(this, 1, 2));
+        assertTrue(a.compareAndSet(this, 2, -4));
+        assertEquals(-4, a.get(this));
+        assertFalse(a.compareAndSet(this, -5, 7));
+        assertEquals(-4, a.get(this));
+        assertTrue(a.compareAndSet(this, -4, 7));
+        assertEquals(7, a.get(this));
+    }
+
+    /**
+     * compareAndSet succeeds in changing protected field value if
+     * equal to expected else fails
+     */
+    // android-note: Removed because android doesn't restrict reflection access
+    // public void testCompareAndSetProtectedInSubclass() {
+    //     AtomicIntegerFieldUpdaterTestSubclass s =
+    //         new AtomicIntegerFieldUpdaterTestSubclass();
+    //     s.checkCompareAndSetProtectedSub();
+    // }
+
+    /**
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java b/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java
index cf73810..6392c54 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicIntegerTest.java
@@ -21,7 +21,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicIntegerTest.class);
     // }
 
     final int[] VALUES = {
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java
index 08df01e..a60ecfd 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicLongArrayTest.java
@@ -22,7 +22,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicLongArrayTest.class);
     // }
 
     /**
@@ -290,7 +290,7 @@
                     assertTrue(v >= 0);
                     if (v != 0) {
                         done = false;
-                        if (aa.compareAndSet(i, v, v-1))
+                        if (aa.compareAndSet(i, v, v - 1))
                             ++counts;
                     }
                 }
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
index 204f814..d46280b 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicLongFieldUpdaterTest.java
@@ -15,9 +15,10 @@
 
 public class AtomicLongFieldUpdaterTest extends JSR166TestCase {
     volatile long x = 0;
-    int z;
+    protected volatile long protectedField;
+    private volatile long privateField;
     long w;
-
+    float z;
     // android-note: Removed because the CTS runner does a bad job of
     // retrying tests that have suite() declarations.
     //
@@ -25,7 +26,59 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicLongFieldUpdaterTest.class);
+    // }
+
+    // for testing subclass access
+    // android-note: Removed because android doesn't restrict reflection access
+    // static class AtomicLongFieldUpdaterTestSubclass extends AtomicLongFieldUpdaterTest {
+    //     public void checkPrivateAccess() {
+    //         try {
+    //             AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+    //                 AtomicLongFieldUpdater.newUpdater
+    //                 (AtomicLongFieldUpdaterTest.class, "privateField");
+    //             shouldThrow();
+    //         } catch (RuntimeException success) {
+    //             assertNotNull(success.getCause());
+    //         }
+    //     }
+
+    //     public void checkCompareAndSetProtectedSub() {
+    //         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+    //             AtomicLongFieldUpdater.newUpdater
+    //             (AtomicLongFieldUpdaterTest.class, "protectedField");
+    //         this.protectedField = 1;
+    //         assertTrue(a.compareAndSet(this, 1, 2));
+    //         assertTrue(a.compareAndSet(this, 2, -4));
+    //         assertEquals(-4, a.get(this));
+    //         assertFalse(a.compareAndSet(this, -5, 7));
+    //         assertEquals(-4, a.get(this));
+    //         assertTrue(a.compareAndSet(this, -4, 7));
+    //         assertEquals(7, a.get(this));
+    //     }
+    // }
+
+    // static class UnrelatedClass {
+    //     public void checkPackageAccess(AtomicLongFieldUpdaterTest obj) {
+    //         obj.x = 72L;
+    //         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+    //             AtomicLongFieldUpdater.newUpdater
+    //             (AtomicLongFieldUpdaterTest.class, "x");
+    //         assertEquals(72L, a.get(obj));
+    //         assertTrue(a.compareAndSet(obj, 72L, 73L));
+    //         assertEquals(73L, a.get(obj));
+    //     }
+
+    //     public void checkPrivateAccess(AtomicLongFieldUpdaterTest obj) {
+    //         try {
+    //             AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a =
+    //                 AtomicLongFieldUpdater.newUpdater
+    //                 (AtomicLongFieldUpdaterTest.class, "privateField");
+    //             throw new AssertionError("should throw");
+    //         } catch (RuntimeException success) {
+    //             assertNotNull(success.getCause());
+    //         }
+    //     }
     // }
 
     AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> updaterFor(String fieldName) {
@@ -66,6 +119,26 @@
     }
 
     /**
+     * construction using private field from subclass throws RuntimeException
+     */
+    // android-note: Removed because android doesn't restrict reflection access
+    // public void testPrivateFieldInSubclass() {
+    //     AtomicLongFieldUpdaterTestSubclass s =
+    //         new AtomicLongFieldUpdaterTestSubclass();
+    //     s.checkPrivateAccess();
+    // }
+
+    /**
+     * construction from unrelated class; package access is allowed,
+     * private access is not
+     */
+    // android-note: Removed because android doesn't restrict reflection access
+    // public void testUnrelatedClassAccess() {
+    //     new UnrelatedClass().checkPackageAccess(this);
+    //     new UnrelatedClass().checkPrivateAccess(this);
+    // }
+
+    /**
      * get returns the last value set or assigned
      */
     public void testGetSet() {
@@ -110,6 +183,34 @@
     }
 
     /**
+     * compareAndSet succeeds in changing protected field value if
+     * equal to expected else fails
+     */
+    public void testCompareAndSetProtected() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("protectedField");
+        protectedField = 1;
+        assertTrue(a.compareAndSet(this, 1, 2));
+        assertTrue(a.compareAndSet(this, 2, -4));
+        assertEquals(-4, a.get(this));
+        assertFalse(a.compareAndSet(this, -5, 7));
+        assertEquals(-4, a.get(this));
+        assertTrue(a.compareAndSet(this, -4, 7));
+        assertEquals(7, a.get(this));
+    }
+
+    /**
+     * compareAndSet succeeds in changing protected field value if
+     * equal to expected else fails
+     */
+    // android-note: Removed because android doesn't restrict reflection access
+    // public void testCompareAndSetProtectedInSubclass() {
+    //     AtomicLongFieldUpdaterTestSubclass s =
+    //         new AtomicLongFieldUpdaterTestSubclass();
+    //     s.checkCompareAndSetProtectedSub();
+    // }
+
+    /**
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java b/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java
index b9c1722..a8ee7c6 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicLongTest.java
@@ -21,7 +21,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicLongTest.class);
     // }
 
     final long[] VALUES = {
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java b/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java
index 61b6b1b..bd4e8cb 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicMarkableReferenceTest.java
@@ -21,7 +21,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicMarkableReferenceTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java
index 1df2f9f..f3aab44 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceArrayTest.java
@@ -22,7 +22,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicReferenceArrayTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
index 4b0d946..9b2e9a9 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceFieldUpdaterTest.java
@@ -15,6 +15,8 @@
 
 public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase {
     volatile Integer x = null;
+    protected volatile Integer protectedField;
+    private volatile Integer privateField;
     Object z;
     Integer w;
     volatile int i;
@@ -26,10 +28,62 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicReferenceFieldUpdaterTest.class);
     // }
 
-    AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) {
+    // for testing subclass access
+    // android-note: Removed because android doesn't restrict reflection access
+    // static class AtomicReferenceFieldUpdaterTestSubclass extends AtomicReferenceFieldUpdaterTest {
+    //     public void checkPrivateAccess() {
+    //         try {
+    //             AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+    //                 AtomicReferenceFieldUpdater.newUpdater
+    //                 (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
+    //             shouldThrow();
+    //         } catch (RuntimeException success) {
+    //             assertNotNull(success.getCause());
+    //         }
+    //     }
+
+    //     public void checkCompareAndSetProtectedSub() {
+    //         AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+    //             AtomicReferenceFieldUpdater.newUpdater
+    //             (AtomicReferenceFieldUpdaterTest.class, Integer.class, "protectedField");
+    //         this.protectedField = one;
+    //         assertTrue(a.compareAndSet(this, one, two));
+    //         assertTrue(a.compareAndSet(this, two, m4));
+    //         assertSame(m4, a.get(this));
+    //         assertFalse(a.compareAndSet(this, m5, seven));
+    //         assertFalse(seven == a.get(this));
+    //         assertTrue(a.compareAndSet(this, m4, seven));
+    //         assertSame(seven, a.get(this));
+    //     }
+    // }
+
+    // static class UnrelatedClass {
+    //     public void checkPackageAccess(AtomicReferenceFieldUpdaterTest obj) {
+    //         obj.x = one;
+    //         AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+    //             AtomicReferenceFieldUpdater.newUpdater
+    //             (AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
+    //         assertSame(one, a.get(obj));
+    //         assertTrue(a.compareAndSet(obj, one, two));
+    //         assertSame(two, a.get(obj));
+    //     }
+
+    //     public void checkPrivateAccess(AtomicReferenceFieldUpdaterTest obj) {
+    //         try {
+    //             AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest,Integer> a =
+    //                 AtomicReferenceFieldUpdater.newUpdater
+    //                 (AtomicReferenceFieldUpdaterTest.class, Integer.class, "privateField");
+    //             throw new AssertionError("should throw");
+    //         } catch (RuntimeException success) {
+    //             assertNotNull(success.getCause());
+    //         }
+    //     }
+    // }
+
+    static AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> updaterFor(String fieldName) {
         return AtomicReferenceFieldUpdater.newUpdater
             (AtomicReferenceFieldUpdaterTest.class, Integer.class, fieldName);
     }
@@ -77,6 +131,26 @@
     }
 
     /**
+     * construction using private field from subclass throws RuntimeException
+     */
+    // android-note: Removed because android doesn't restrict reflection access
+    // public void testPrivateFieldInSubclass() {
+    //     AtomicReferenceFieldUpdaterTestSubclass s =
+    //         new AtomicReferenceFieldUpdaterTestSubclass();
+    //     s.checkPrivateAccess();
+    // }
+
+    /**
+     * construction from unrelated class; package access is allowed,
+     * private access is not
+     */
+    // android-note: Removed because android doesn't restrict reflection access
+    // public void testUnrelatedClassAccess() {
+    //     new UnrelatedClass().checkPackageAccess(this);
+    //     new UnrelatedClass().checkPrivateAccess(this);
+    // }
+
+    /**
      * get returns the last value set or assigned
      */
     public void testGetSet() {
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java b/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java
index 457182f..4728970 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicReferenceTest.java
@@ -21,7 +21,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicReferenceTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java b/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java
index b3ff06a..a2e8c7f 100644
--- a/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java
+++ b/jsr166-tests/src/test/java/jsr166/AtomicStampedReferenceTest.java
@@ -21,7 +21,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(AtomicStampedReferenceTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java
index db0f03d..1a188e1 100644
--- a/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/BlockingQueueTest.java
@@ -39,9 +39,9 @@
     // android-note: Explicitly instantiated.
     //
     // public Test testSuite() {
-    //    // TODO: filter the returned tests using the configuration
-    //    // information provided by the subclass via protected methods.
-    //    return new TestSuite(this.getClass());
+    //     // TODO: filter the returned tests using the configuration
+    //     // information provided by the subclass via protected methods.
+    //     return new TestSuite(this.getClass());
     // }
 
     //----------------------------------------------------------------
@@ -239,6 +239,8 @@
                     shouldThrow();
                 } catch (InterruptedException success) {}
                 assertFalse(Thread.interrupted());
+
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
         barrier.await();
@@ -352,20 +354,20 @@
                 assertEquals((pass == 0), q.contains(elts[i]));
                 assertEquals((pass == 0), q.remove(elts[i]));
                 assertFalse(q.contains(elts[i]));
-                assertTrue(q.contains(elts[i-1]));
+                assertTrue(q.contains(elts[i - 1]));
                 if (i < size - 1)
-                    assertTrue(q.contains(elts[i+1]));
+                    assertTrue(q.contains(elts[i + 1]));
             }
         }
         if (size > 0)
             assertTrue(q.contains(elts[0]));
-        for (int i = size-2; i >= 0; i -= 2) {
+        for (int i = size - 2; i >= 0; i -= 2) {
             assertTrue(q.contains(elts[i]));
-            assertFalse(q.contains(elts[i+1]));
+            assertFalse(q.contains(elts[i + 1]));
             assertTrue(q.remove(elts[i]));
             assertFalse(q.contains(elts[i]));
-            assertFalse(q.remove(elts[i+1]));
-            assertFalse(q.contains(elts[i+1]));
+            assertFalse(q.remove(elts[i + 1]));
+            assertFalse(q.contains(elts[i + 1]));
         }
         checkEmpty(q);
     }
diff --git a/jsr166-tests/src/test/java/jsr166/Collection8Test.java b/jsr166-tests/src/test/java/jsr166/Collection8Test.java
new file mode 100644
index 0000000..634182b
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/Collection8Test.java
@@ -0,0 +1,104 @@
+/*
+ * Written by Doug Lea and Martin Buchholz 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 jsr166;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Consumer;
+
+import junit.framework.Test;
+
+/**
+ * Contains tests applicable to all jdk8+ Collection implementations.
+ * An extension of CollectionTest.
+ */
+public class Collection8Test extends JSR166TestCase {
+    final CollectionImplementation impl;
+
+    /** Tests are parameterized by a Collection implementation. */
+    Collection8Test(CollectionImplementation impl, String methodName) {
+        super(methodName);
+        this.impl = impl;
+    }
+
+    public static Test testSuite(CollectionImplementation impl) {
+        return parameterizedTestSuite(Collection8Test.class,
+                                      CollectionImplementation.class,
+                                      impl);
+    }
+
+    /**
+     * stream().forEach returns elements in the collection
+     */
+    // TODO(streams):
+    // public void testForEach() throws Throwable {
+    //     final Collection c = impl.emptyCollection();
+    //     final AtomicLong count = new AtomicLong(0L);
+    //     final Object x = impl.makeElement(1);
+    //     final Object y = impl.makeElement(2);
+    //     final ArrayList found = new ArrayList();
+    //     Consumer<Object> spy = (o) -> { found.add(o); };
+    //     c.stream().forEach(spy);
+    //     assertTrue(found.isEmpty());
+
+    //     assertTrue(c.add(x));
+    //     c.stream().forEach(spy);
+    //     assertEquals(Collections.singletonList(x), found);
+    //     found.clear();
+
+    //     assertTrue(c.add(y));
+    //     c.stream().forEach(spy);
+    //     assertEquals(2, found.size());
+    //     assertTrue(found.contains(x));
+    //     assertTrue(found.contains(y));
+    //     found.clear();
+
+    //     c.clear();
+    //     c.stream().forEach(spy);
+    //     assertTrue(found.isEmpty());
+    // }
+
+    // public void testForEachConcurrentStressTest() throws Throwable {
+    //     if (!impl.isConcurrent()) return;
+    //     final Collection c = impl.emptyCollection();
+    //     final long testDurationMillis = timeoutMillis();
+    //     final AtomicBoolean done = new AtomicBoolean(false);
+    //     final Object elt = impl.makeElement(1);
+    //     final Future<?> f1, f2;
+    //     final ExecutorService pool = Executors.newCachedThreadPool();
+    //     try (PoolCleaner cleaner = cleaner(pool, done)) {
+    //         final CountDownLatch threadsStarted = new CountDownLatch(2);
+    //         Runnable checkElt = () -> {
+    //             threadsStarted.countDown();
+    //             while (!done.get())
+    //                 c.stream().forEach((x) -> { assertSame(x, elt); }); };
+    //         Runnable addRemove = () -> {
+    //             threadsStarted.countDown();
+    //             while (!done.get()) {
+    //                 assertTrue(c.add(elt));
+    //                 assertTrue(c.remove(elt));
+    //             }};
+    //         f1 = pool.submit(checkElt);
+    //         f2 = pool.submit(addRemove);
+    //         Thread.sleep(testDurationMillis);
+    //     }
+    //     assertNull(f1.get(0L, MILLISECONDS));
+    //     assertNull(f2.get(0L, MILLISECONDS));
+    // }
+
+    // public void testCollection8DebugFail() { fail(); }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/CollectionImplementation.java b/jsr166-tests/src/test/java/jsr166/CollectionImplementation.java
new file mode 100644
index 0000000..4ba5bda
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/CollectionImplementation.java
@@ -0,0 +1,21 @@
+/*
+ * Written by Doug Lea and Martin Buchholz 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 jsr166;
+
+import java.util.Collection;
+
+/** Allows tests to work with different Collection implementations. */
+public interface CollectionImplementation {
+    /** Returns the Collection class. */
+    public Class<?> klazz();
+    /** Returns an empty collection. */
+    public Collection emptyCollection();
+    public Object makeElement(int i);
+    public boolean isConcurrent();
+    public boolean permitsNulls();
+}
diff --git a/jsr166-tests/src/test/java/jsr166/CollectionTest.java b/jsr166-tests/src/test/java/jsr166/CollectionTest.java
new file mode 100644
index 0000000..44ef66d
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/CollectionTest.java
@@ -0,0 +1,43 @@
+/*
+ * Written by Doug Lea and Martin Buchholz 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 jsr166;
+
+import java.util.Collection;
+
+import junit.framework.Test;
+
+/**
+ * Contains tests applicable to all Collection implementations.
+ */
+public class CollectionTest extends JSR166TestCase {
+    final CollectionImplementation impl;
+
+    /** Tests are parameterized by a Collection implementation. */
+    CollectionTest(CollectionImplementation impl, String methodName) {
+        super(methodName);
+        this.impl = impl;
+    }
+
+    public static Test testSuite(CollectionImplementation impl) {
+        return newTestSuite
+            (parameterizedTestSuite(CollectionTest.class,
+                                    CollectionImplementation.class,
+                                    impl),
+             jdk8ParameterizedTestSuite(CollectionTest.class,
+                                        CollectionImplementation.class,
+                                        impl));
+    }
+
+    /** A test of the CollectionImplementation implementation ! */
+    public void testEmptyMeansEmpty() {
+        assertTrue(impl.emptyCollection().isEmpty());
+        assertEquals(0, impl.emptyCollection().size());
+    }
+
+    // public void testCollectionDebugFail() { fail(); }
+}
diff --git a/jsr166-tests/src/test/java/jsr166/CompletableFutureTest.java b/jsr166-tests/src/test/java/jsr166/CompletableFutureTest.java
new file mode 100644
index 0000000..1372cc4
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/CompletableFutureTest.java
@@ -0,0 +1,3959 @@
+/*
+ * Written by Doug Lea and Martin Buchholz 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 jsr166;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.CompletableFuture.completedFuture;
+import static java.util.concurrent.CompletableFuture.failedFuture;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+// TODO(streams):
+//import java.util.stream.Collectors;
+//import java.util.stream.Stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CompletableFutureTest extends JSR166TestCase {
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(CompletableFutureTest.class);
+    // }
+
+    static class CFException extends RuntimeException {}
+
+    void checkIncomplete(CompletableFuture<?> f) {
+        assertFalse(f.isDone());
+        assertFalse(f.isCancelled());
+        assertTrue(f.toString().contains("Not completed"));
+        try {
+            assertNull(f.getNow(null));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            f.get(0L, SECONDS);
+            shouldThrow();
+        }
+        catch (TimeoutException success) {}
+        catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
+        checkTimedGet(f, value);
+
+        try {
+            assertEquals(value, f.join());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertEquals(value, f.getNow(null));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertEquals(value, f.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        assertTrue(f.isDone());
+        assertFalse(f.isCancelled());
+        assertFalse(f.isCompletedExceptionally());
+        assertTrue(f.toString().contains("[Completed normally]"));
+    }
+
+    /**
+     * Returns the "raw" internal exceptional completion of f,
+     * without any additional wrapping with CompletionException.
+     */
+    <U> Throwable exceptionalCompletion(CompletableFuture<U> f) {
+        // handle (and whenComplete) can distinguish between "direct"
+        // and "wrapped" exceptional completion
+        return f.handle((U u, Throwable t) -> t).join();
+    }
+
+    void checkCompletedExceptionally(CompletableFuture<?> f,
+                                     boolean wrapped,
+                                     Consumer<Throwable> checker) {
+        Throwable cause = exceptionalCompletion(f);
+        if (wrapped) {
+            assertTrue(cause instanceof CompletionException);
+            cause = cause.getCause();
+        }
+        checker.accept(cause);
+
+        long startTime = System.nanoTime();
+        try {
+            f.get(LONG_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(cause, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
+
+        try {
+            f.join();
+            shouldThrow();
+        } catch (CompletionException success) {
+            assertSame(cause, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            f.getNow(null);
+            shouldThrow();
+        } catch (CompletionException success) {
+            assertSame(cause, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            f.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(cause, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        assertFalse(f.isCancelled());
+        assertTrue(f.isDone());
+        assertTrue(f.isCompletedExceptionally());
+        assertTrue(f.toString().contains("[Completed exceptionally]"));
+    }
+
+    void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
+        checkCompletedExceptionally(f, true,
+            (t) -> assertTrue(t instanceof CFException));
+    }
+
+    void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
+        checkCompletedExceptionally(f, true,
+            (t) -> assertTrue(t instanceof CancellationException));
+    }
+
+    void checkCompletedWithTimeoutException(CompletableFuture<?> f) {
+        checkCompletedExceptionally(f, false,
+            (t) -> assertTrue(t instanceof TimeoutException));
+    }
+
+    void checkCompletedWithWrappedException(CompletableFuture<?> f,
+                                            Throwable ex) {
+        checkCompletedExceptionally(f, true, (t) -> assertSame(t, ex));
+    }
+
+    void checkCompletedExceptionally(CompletableFuture<?> f, Throwable ex) {
+        checkCompletedExceptionally(f, false, (t) -> assertSame(t, ex));
+    }
+
+    void checkCancelled(CompletableFuture<?> f) {
+        long startTime = System.nanoTime();
+        try {
+            f.get(LONG_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
+
+        try {
+            f.join();
+            shouldThrow();
+        } catch (CancellationException success) {}
+        try {
+            f.getNow(null);
+            shouldThrow();
+        } catch (CancellationException success) {}
+        try {
+            f.get();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        assertTrue(exceptionalCompletion(f) instanceof CancellationException);
+
+        assertTrue(f.isDone());
+        assertTrue(f.isCompletedExceptionally());
+        assertTrue(f.isCancelled());
+        assertTrue(f.toString().contains("[Completed exceptionally]"));
+    }
+
+    /**
+     * A newly constructed CompletableFuture is incomplete, as indicated
+     * by methods isDone, isCancelled, and getNow
+     */
+    public void testConstructor() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        checkIncomplete(f);
+    }
+
+    /**
+     * complete completes normally, as indicated by methods isDone,
+     * isCancelled, join, get, and getNow
+     */
+    public void testComplete() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        checkIncomplete(f);
+        assertTrue(f.complete(v1));
+        assertFalse(f.complete(v1));
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * completeExceptionally completes exceptionally, as indicated by
+     * methods isDone, isCancelled, join, get, and getNow
+     */
+    public void testCompleteExceptionally() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CFException ex = new CFException();
+        checkIncomplete(f);
+        f.completeExceptionally(ex);
+        checkCompletedExceptionally(f, ex);
+    }
+
+    /**
+     * cancel completes exceptionally and reports cancelled, as indicated by
+     * methods isDone, isCancelled, join, get, and getNow
+     */
+    public void testCancel() {
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        checkIncomplete(f);
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        assertTrue(f.cancel(!mayInterruptIfRunning));
+        checkCancelled(f);
+    }}
+
+    /**
+     * obtrudeValue forces completion with given value
+     */
+    public void testObtrudeValue() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        checkIncomplete(f);
+        assertTrue(f.complete(one));
+        checkCompletedNormally(f, one);
+        f.obtrudeValue(three);
+        checkCompletedNormally(f, three);
+        f.obtrudeValue(two);
+        checkCompletedNormally(f, two);
+        f = new CompletableFuture<>();
+        f.obtrudeValue(three);
+        checkCompletedNormally(f, three);
+        f.obtrudeValue(null);
+        checkCompletedNormally(f, null);
+        f = new CompletableFuture<>();
+        f.completeExceptionally(new CFException());
+        f.obtrudeValue(four);
+        checkCompletedNormally(f, four);
+    }
+
+    /**
+     * obtrudeException forces completion with given exception
+     */
+    public void testObtrudeException() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CFException ex;
+        CompletableFuture<Integer> f;
+
+        f = new CompletableFuture<>();
+        assertTrue(f.complete(v1));
+        for (int i = 0; i < 2; i++) {
+            f.obtrudeException(ex = new CFException());
+            checkCompletedExceptionally(f, ex);
+        }
+
+        f = new CompletableFuture<>();
+        for (int i = 0; i < 2; i++) {
+            f.obtrudeException(ex = new CFException());
+            checkCompletedExceptionally(f, ex);
+        }
+
+        f = new CompletableFuture<>();
+        f.completeExceptionally(ex = new CFException());
+        f.obtrudeValue(v1);
+        checkCompletedNormally(f, v1);
+        f.obtrudeException(ex = new CFException());
+        checkCompletedExceptionally(f, ex);
+        f.completeExceptionally(new CFException());
+        checkCompletedExceptionally(f, ex);
+        assertFalse(f.complete(v1));
+        checkCompletedExceptionally(f, ex);
+    }}
+
+    /**
+     * getNumberOfDependents returns number of dependent tasks
+     */
+    public void testGetNumberOfDependents() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        assertEquals(0, f.getNumberOfDependents());
+        final CompletableFuture<Void> g = m.thenRun(f, new Noop(m));
+        assertEquals(1, f.getNumberOfDependents());
+        assertEquals(0, g.getNumberOfDependents());
+        final CompletableFuture<Void> h = m.thenRun(f, new Noop(m));
+        assertEquals(2, f.getNumberOfDependents());
+        assertEquals(0, h.getNumberOfDependents());
+        assertTrue(f.complete(v1));
+        checkCompletedNormally(g, null);
+        checkCompletedNormally(h, null);
+        assertEquals(0, f.getNumberOfDependents());
+        assertEquals(0, g.getNumberOfDependents());
+        assertEquals(0, h.getNumberOfDependents());
+    }}
+
+    /**
+     * toString indicates current completion state
+     */
+    public void testToString() {
+        CompletableFuture<String> f;
+
+        f = new CompletableFuture<String>();
+        assertTrue(f.toString().contains("[Not completed]"));
+
+        assertTrue(f.complete("foo"));
+        assertTrue(f.toString().contains("[Completed normally]"));
+
+        f = new CompletableFuture<String>();
+        assertTrue(f.completeExceptionally(new IndexOutOfBoundsException()));
+        assertTrue(f.toString().contains("[Completed exceptionally]"));
+
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
+            f = new CompletableFuture<String>();
+            assertTrue(f.cancel(mayInterruptIfRunning));
+            assertTrue(f.toString().contains("[Completed exceptionally]"));
+        }
+    }
+
+    /**
+     * completedFuture returns a completed CompletableFuture with given value
+     */
+    public void testCompletedFuture() {
+        CompletableFuture<String> f = CompletableFuture.completedFuture("test");
+        checkCompletedNormally(f, "test");
+    }
+
+    abstract class CheckedAction {
+        int invocationCount = 0;
+        final ExecutionMode m;
+        CheckedAction(ExecutionMode m) { this.m = m; }
+        void invoked() {
+            m.checkExecutionMode();
+            assertEquals(0, invocationCount++);
+        }
+        void assertNotInvoked() { assertEquals(0, invocationCount); }
+        void assertInvoked() { assertEquals(1, invocationCount); }
+    }
+
+    abstract class CheckedIntegerAction extends CheckedAction {
+        Integer value;
+        CheckedIntegerAction(ExecutionMode m) { super(m); }
+        void assertValue(Integer expected) {
+            assertInvoked();
+            assertEquals(expected, value);
+        }
+    }
+
+    class IntegerSupplier extends CheckedAction
+        implements Supplier<Integer>
+    {
+        final Integer value;
+        IntegerSupplier(ExecutionMode m, Integer value) {
+            super(m);
+            this.value = value;
+        }
+        public Integer get() {
+            invoked();
+            return value;
+        }
+    }
+
+    // A function that handles and produces null values as well.
+    static Integer inc(Integer x) {
+        return (x == null) ? null : x + 1;
+    }
+
+    class NoopConsumer extends CheckedIntegerAction
+        implements Consumer<Integer>
+    {
+        NoopConsumer(ExecutionMode m) { super(m); }
+        public void accept(Integer x) {
+            invoked();
+            value = x;
+        }
+    }
+
+    class IncFunction extends CheckedIntegerAction
+        implements Function<Integer,Integer>
+    {
+        IncFunction(ExecutionMode m) { super(m); }
+        public Integer apply(Integer x) {
+            invoked();
+            return value = inc(x);
+        }
+    }
+
+    // Choose non-commutative actions for better coverage
+    // A non-commutative function that handles and produces null values as well.
+    static Integer subtract(Integer x, Integer y) {
+        return (x == null && y == null) ? null :
+            ((x == null) ? 42 : x.intValue())
+            - ((y == null) ? 99 : y.intValue());
+    }
+
+    class SubtractAction extends CheckedIntegerAction
+        implements BiConsumer<Integer, Integer>
+    {
+        SubtractAction(ExecutionMode m) { super(m); }
+        public void accept(Integer x, Integer y) {
+            invoked();
+            value = subtract(x, y);
+        }
+    }
+
+    class SubtractFunction extends CheckedIntegerAction
+        implements BiFunction<Integer, Integer, Integer>
+    {
+        SubtractFunction(ExecutionMode m) { super(m); }
+        public Integer apply(Integer x, Integer y) {
+            invoked();
+            return value = subtract(x, y);
+        }
+    }
+
+    class Noop extends CheckedAction implements Runnable {
+        Noop(ExecutionMode m) { super(m); }
+        public void run() {
+            invoked();
+        }
+    }
+
+    class FailingSupplier extends CheckedAction
+        implements Supplier<Integer>
+    {
+        FailingSupplier(ExecutionMode m) { super(m); }
+        public Integer get() {
+            invoked();
+            throw new CFException();
+        }
+    }
+
+    class FailingConsumer extends CheckedIntegerAction
+        implements Consumer<Integer>
+    {
+        FailingConsumer(ExecutionMode m) { super(m); }
+        public void accept(Integer x) {
+            invoked();
+            value = x;
+            throw new CFException();
+        }
+    }
+
+    class FailingBiConsumer extends CheckedIntegerAction
+        implements BiConsumer<Integer, Integer>
+    {
+        FailingBiConsumer(ExecutionMode m) { super(m); }
+        public void accept(Integer x, Integer y) {
+            invoked();
+            value = subtract(x, y);
+            throw new CFException();
+        }
+    }
+
+    class FailingFunction extends CheckedIntegerAction
+        implements Function<Integer, Integer>
+    {
+        FailingFunction(ExecutionMode m) { super(m); }
+        public Integer apply(Integer x) {
+            invoked();
+            value = x;
+            throw new CFException();
+        }
+    }
+
+    class FailingBiFunction extends CheckedIntegerAction
+        implements BiFunction<Integer, Integer, Integer>
+    {
+        FailingBiFunction(ExecutionMode m) { super(m); }
+        public Integer apply(Integer x, Integer y) {
+            invoked();
+            value = subtract(x, y);
+            throw new CFException();
+        }
+    }
+
+    class FailingRunnable extends CheckedAction implements Runnable {
+        FailingRunnable(ExecutionMode m) { super(m); }
+        public void run() {
+            invoked();
+            throw new CFException();
+        }
+    }
+
+    class CompletableFutureInc extends CheckedIntegerAction
+        implements Function<Integer, CompletableFuture<Integer>>
+    {
+        CompletableFutureInc(ExecutionMode m) { super(m); }
+        public CompletableFuture<Integer> apply(Integer x) {
+            invoked();
+            value = x;
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            assertTrue(f.complete(inc(x)));
+            return f;
+        }
+    }
+
+    class FailingCompletableFutureFunction extends CheckedIntegerAction
+        implements Function<Integer, CompletableFuture<Integer>>
+    {
+        FailingCompletableFutureFunction(ExecutionMode m) { super(m); }
+        public CompletableFuture<Integer> apply(Integer x) {
+            invoked();
+            value = x;
+            throw new CFException();
+        }
+    }
+
+    // Used for explicit executor tests
+    static final class ThreadExecutor implements Executor {
+        final AtomicInteger count = new AtomicInteger(0);
+        static final ThreadGroup tg = new ThreadGroup("ThreadExecutor");
+        static boolean startedCurrentThread() {
+            return Thread.currentThread().getThreadGroup() == tg;
+        }
+
+        public void execute(Runnable r) {
+            count.getAndIncrement();
+            new Thread(tg, r).start();
+        }
+    }
+
+    static final boolean defaultExecutorIsCommonPool
+        = ForkJoinPool.getCommonPoolParallelism() > 1;
+
+    /**
+     * Permits the testing of parallel code for the 3 different
+     * execution modes without copy/pasting all the test methods.
+     */
+    enum ExecutionMode {
+        SYNC {
+            public void checkExecutionMode() {
+                assertFalse(ThreadExecutor.startedCurrentThread());
+                assertNull(ForkJoinTask.getPool());
+            }
+            public CompletableFuture<Void> runAsync(Runnable a) {
+                throw new UnsupportedOperationException();
+            }
+            public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
+                throw new UnsupportedOperationException();
+            }
+            public <T> CompletableFuture<Void> thenRun
+                (CompletableFuture<T> f, Runnable a) {
+                return f.thenRun(a);
+            }
+            public <T> CompletableFuture<Void> thenAccept
+                (CompletableFuture<T> f, Consumer<? super T> a) {
+                return f.thenAccept(a);
+            }
+            public <T,U> CompletableFuture<U> thenApply
+                (CompletableFuture<T> f, Function<? super T,U> a) {
+                return f.thenApply(a);
+            }
+            public <T,U> CompletableFuture<U> thenCompose
+                (CompletableFuture<T> f,
+                 Function<? super T,? extends CompletionStage<U>> a) {
+                return f.thenCompose(a);
+            }
+            public <T,U> CompletableFuture<U> handle
+                (CompletableFuture<T> f,
+                 BiFunction<? super T,Throwable,? extends U> a) {
+                return f.handle(a);
+            }
+            public <T> CompletableFuture<T> whenComplete
+                (CompletableFuture<T> f,
+                 BiConsumer<? super T,? super Throwable> a) {
+                return f.whenComplete(a);
+            }
+            public <T,U> CompletableFuture<Void> runAfterBoth
+                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
+                return f.runAfterBoth(g, a);
+            }
+            public <T,U> CompletableFuture<Void> thenAcceptBoth
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiConsumer<? super T,? super U> a) {
+                return f.thenAcceptBoth(g, a);
+            }
+            public <T,U,V> CompletableFuture<V> thenCombine
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiFunction<? super T,? super U,? extends V> a) {
+                return f.thenCombine(g, a);
+            }
+            public <T> CompletableFuture<Void> runAfterEither
+                (CompletableFuture<T> f,
+                 CompletionStage<?> g,
+                 java.lang.Runnable a) {
+                return f.runAfterEither(g, a);
+            }
+            public <T> CompletableFuture<Void> acceptEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Consumer<? super T> a) {
+                return f.acceptEither(g, a);
+            }
+            public <T,U> CompletableFuture<U> applyToEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Function<? super T,U> a) {
+                return f.applyToEither(g, a);
+            }
+        },
+
+        ASYNC {
+            public void checkExecutionMode() {
+                assertEquals(defaultExecutorIsCommonPool,
+                             (ForkJoinPool.commonPool() == ForkJoinTask.getPool()));
+            }
+            public CompletableFuture<Void> runAsync(Runnable a) {
+                return CompletableFuture.runAsync(a);
+            }
+            public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
+                return CompletableFuture.supplyAsync(a);
+            }
+            public <T> CompletableFuture<Void> thenRun
+                (CompletableFuture<T> f, Runnable a) {
+                return f.thenRunAsync(a);
+            }
+            public <T> CompletableFuture<Void> thenAccept
+                (CompletableFuture<T> f, Consumer<? super T> a) {
+                return f.thenAcceptAsync(a);
+            }
+            public <T,U> CompletableFuture<U> thenApply
+                (CompletableFuture<T> f, Function<? super T,U> a) {
+                return f.thenApplyAsync(a);
+            }
+            public <T,U> CompletableFuture<U> thenCompose
+                (CompletableFuture<T> f,
+                 Function<? super T,? extends CompletionStage<U>> a) {
+                return f.thenComposeAsync(a);
+            }
+            public <T,U> CompletableFuture<U> handle
+                (CompletableFuture<T> f,
+                 BiFunction<? super T,Throwable,? extends U> a) {
+                return f.handleAsync(a);
+            }
+            public <T> CompletableFuture<T> whenComplete
+                (CompletableFuture<T> f,
+                 BiConsumer<? super T,? super Throwable> a) {
+                return f.whenCompleteAsync(a);
+            }
+            public <T,U> CompletableFuture<Void> runAfterBoth
+                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
+                return f.runAfterBothAsync(g, a);
+            }
+            public <T,U> CompletableFuture<Void> thenAcceptBoth
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiConsumer<? super T,? super U> a) {
+                return f.thenAcceptBothAsync(g, a);
+            }
+            public <T,U,V> CompletableFuture<V> thenCombine
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiFunction<? super T,? super U,? extends V> a) {
+                return f.thenCombineAsync(g, a);
+            }
+            public <T> CompletableFuture<Void> runAfterEither
+                (CompletableFuture<T> f,
+                 CompletionStage<?> g,
+                 java.lang.Runnable a) {
+                return f.runAfterEitherAsync(g, a);
+            }
+            public <T> CompletableFuture<Void> acceptEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Consumer<? super T> a) {
+                return f.acceptEitherAsync(g, a);
+            }
+            public <T,U> CompletableFuture<U> applyToEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Function<? super T,U> a) {
+                return f.applyToEitherAsync(g, a);
+            }
+        },
+
+        EXECUTOR {
+            public void checkExecutionMode() {
+                assertTrue(ThreadExecutor.startedCurrentThread());
+            }
+            public CompletableFuture<Void> runAsync(Runnable a) {
+                return CompletableFuture.runAsync(a, new ThreadExecutor());
+            }
+            public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
+                return CompletableFuture.supplyAsync(a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<Void> thenRun
+                (CompletableFuture<T> f, Runnable a) {
+                return f.thenRunAsync(a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<Void> thenAccept
+                (CompletableFuture<T> f, Consumer<? super T> a) {
+                return f.thenAcceptAsync(a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<U> thenApply
+                (CompletableFuture<T> f, Function<? super T,U> a) {
+                return f.thenApplyAsync(a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<U> thenCompose
+                (CompletableFuture<T> f,
+                 Function<? super T,? extends CompletionStage<U>> a) {
+                return f.thenComposeAsync(a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<U> handle
+                (CompletableFuture<T> f,
+                 BiFunction<? super T,Throwable,? extends U> a) {
+                return f.handleAsync(a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<T> whenComplete
+                (CompletableFuture<T> f,
+                 BiConsumer<? super T,? super Throwable> a) {
+                return f.whenCompleteAsync(a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<Void> runAfterBoth
+                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
+                return f.runAfterBothAsync(g, a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<Void> thenAcceptBoth
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiConsumer<? super T,? super U> a) {
+                return f.thenAcceptBothAsync(g, a, new ThreadExecutor());
+            }
+            public <T,U,V> CompletableFuture<V> thenCombine
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiFunction<? super T,? super U,? extends V> a) {
+                return f.thenCombineAsync(g, a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<Void> runAfterEither
+                (CompletableFuture<T> f,
+                 CompletionStage<?> g,
+                 java.lang.Runnable a) {
+                return f.runAfterEitherAsync(g, a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<Void> acceptEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Consumer<? super T> a) {
+                return f.acceptEitherAsync(g, a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<U> applyToEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Function<? super T,U> a) {
+                return f.applyToEitherAsync(g, a, new ThreadExecutor());
+            }
+        };
+
+        public abstract void checkExecutionMode();
+        public abstract CompletableFuture<Void> runAsync(Runnable a);
+        public abstract <U> CompletableFuture<U> supplyAsync(Supplier<U> a);
+        public abstract <T> CompletableFuture<Void> thenRun
+            (CompletableFuture<T> f, Runnable a);
+        public abstract <T> CompletableFuture<Void> thenAccept
+            (CompletableFuture<T> f, Consumer<? super T> a);
+        public abstract <T,U> CompletableFuture<U> thenApply
+            (CompletableFuture<T> f, Function<? super T,U> a);
+        public abstract <T,U> CompletableFuture<U> thenCompose
+            (CompletableFuture<T> f,
+             Function<? super T,? extends CompletionStage<U>> a);
+        public abstract <T,U> CompletableFuture<U> handle
+            (CompletableFuture<T> f,
+             BiFunction<? super T,Throwable,? extends U> a);
+        public abstract <T> CompletableFuture<T> whenComplete
+            (CompletableFuture<T> f,
+             BiConsumer<? super T,? super Throwable> a);
+        public abstract <T,U> CompletableFuture<Void> runAfterBoth
+            (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a);
+        public abstract <T,U> CompletableFuture<Void> thenAcceptBoth
+            (CompletableFuture<T> f,
+             CompletionStage<? extends U> g,
+             BiConsumer<? super T,? super U> a);
+        public abstract <T,U,V> CompletableFuture<V> thenCombine
+            (CompletableFuture<T> f,
+             CompletionStage<? extends U> g,
+             BiFunction<? super T,? super U,? extends V> a);
+        public abstract <T> CompletableFuture<Void> runAfterEither
+            (CompletableFuture<T> f,
+             CompletionStage<?> g,
+             java.lang.Runnable a);
+        public abstract <T> CompletableFuture<Void> acceptEither
+            (CompletableFuture<T> f,
+             CompletionStage<? extends T> g,
+             Consumer<? super T> a);
+        public abstract <T,U> CompletableFuture<U> applyToEither
+            (CompletableFuture<T> f,
+             CompletionStage<? extends T> g,
+             Function<? super T,U> a);
+    }
+
+    /**
+     * exceptionally action is not invoked when source completes
+     * normally, and source result is propagated
+     */
+    public void testExceptionally_normalCompletion() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = f.exceptionally
+            ((Throwable t) -> {
+                a.getAndIncrement();
+                threadFail("should not be called");
+                return null;            // unreached
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedNormally(g, v1);
+        checkCompletedNormally(f, v1);
+        assertEquals(0, a.get());
+    }}
+
+    /**
+     * exceptionally action completes with function value on source
+     * exception
+     */
+    public void testExceptionally_exceptionalCompletion() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        final CompletableFuture<Integer> g = f.exceptionally
+            ((Throwable t) -> {
+                ExecutionMode.SYNC.checkExecutionMode();
+                threadAssertSame(t, ex);
+                a.getAndIncrement();
+                return v1;
+            });
+        if (createIncomplete) f.completeExceptionally(ex);
+
+        checkCompletedNormally(g, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If an "exceptionally action" throws an exception, it completes
+     * exceptionally with that exception
+     */
+    public void testExceptionally_exceptionalCompletionActionFailed() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex1 = new CFException();
+        final CFException ex2 = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) f.completeExceptionally(ex1);
+        final CompletableFuture<Integer> g = f.exceptionally
+            ((Throwable t) -> {
+                ExecutionMode.SYNC.checkExecutionMode();
+                threadAssertSame(t, ex1);
+                a.getAndIncrement();
+                throw ex2;
+            });
+        if (createIncomplete) f.completeExceptionally(ex1);
+
+        checkCompletedWithWrappedException(g, ex2);
+        checkCompletedExceptionally(f, ex1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * whenComplete action executes on normal completion, propagating
+     * source result.
+     */
+    public void testWhenComplete_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(result, v1);
+                threadAssertNull(t);
+                a.getAndIncrement();
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedNormally(g, v1);
+        checkCompletedNormally(f, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * whenComplete action executes on exceptional completion, propagating
+     * source result.
+     */
+    public void testWhenComplete_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertSame(t, ex);
+                a.getAndIncrement();
+            });
+        if (createIncomplete) f.completeExceptionally(ex);
+
+        checkCompletedWithWrappedException(g, ex);
+        checkCompletedExceptionally(f, ex);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * whenComplete action executes on cancelled source, propagating
+     * CancellationException.
+     */
+    public void testWhenComplete_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertTrue(t instanceof CancellationException);
+                a.getAndIncrement();
+            });
+        if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+
+        checkCompletedWithWrappedCancellationException(g);
+        checkCancelled(f);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If a whenComplete action throws an exception when triggered by
+     * a normal completion, it completes exceptionally
+     */
+    public void testWhenComplete_sourceCompletedNormallyActionFailed() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(result, v1);
+                threadAssertNull(t);
+                a.getAndIncrement();
+                throw ex;
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedWithWrappedException(g, ex);
+        checkCompletedNormally(f, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If a whenComplete action throws an exception when triggered by
+     * a source completion that also throws an exception, the source
+     * exception takes precedence (unlike handle)
+     */
+    public void testWhenComplete_sourceFailedActionFailed() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex1 = new CFException();
+        final CFException ex2 = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+
+        if (!createIncomplete) f.completeExceptionally(ex1);
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(t, ex1);
+                threadAssertNull(result);
+                a.getAndIncrement();
+                throw ex2;
+            });
+        if (createIncomplete) f.completeExceptionally(ex1);
+
+        checkCompletedWithWrappedException(g, ex1);
+        checkCompletedExceptionally(f, ex1);
+        if (testImplementationDetails) {
+            assertEquals(1, ex1.getSuppressed().length);
+            assertSame(ex2, ex1.getSuppressed()[0]);
+        }
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * handle action completes normally with function value on normal
+     * completion of source
+     */
+    public void testHandle_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final AtomicInteger a = new AtomicInteger(0);
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(result, v1);
+                threadAssertNull(t);
+                a.getAndIncrement();
+                return inc(v1);
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedNormally(g, inc(v1));
+        checkCompletedNormally(f, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * handle action completes normally with function value on
+     * exceptional completion of source
+     */
+    public void testHandle_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertSame(t, ex);
+                a.getAndIncrement();
+                return v1;
+            });
+        if (createIncomplete) f.completeExceptionally(ex);
+
+        checkCompletedNormally(g, v1);
+        checkCompletedExceptionally(f, ex);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * handle action completes normally with function value on
+     * cancelled source
+     */
+    public void testHandle_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final AtomicInteger a = new AtomicInteger(0);
+        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertTrue(t instanceof CancellationException);
+                a.getAndIncrement();
+                return v1;
+            });
+        if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+
+        checkCompletedNormally(g, v1);
+        checkCancelled(f);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If a "handle action" throws an exception when triggered by
+     * a normal completion, it completes exceptionally
+     */
+    public void testHandle_sourceCompletedNormallyActionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(result, v1);
+                threadAssertNull(t);
+                a.getAndIncrement();
+                throw ex;
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedWithWrappedException(g, ex);
+        checkCompletedNormally(f, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If a "handle action" throws an exception when triggered by
+     * a source completion that also throws an exception, the action
+     * exception takes precedence (unlike whenComplete)
+     */
+    public void testHandle_sourceFailedActionFailed() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex1 = new CFException();
+        final CFException ex2 = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+
+        if (!createIncomplete) f.completeExceptionally(ex1);
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertSame(ex1, t);
+                a.getAndIncrement();
+                throw ex2;
+            });
+        if (createIncomplete) f.completeExceptionally(ex1);
+
+        checkCompletedWithWrappedException(g, ex2);
+        checkCompletedExceptionally(f, ex1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * runAsync completes after running Runnable
+     */
+    public void testRunAsync_normalCompletion() {
+        ExecutionMode[] executionModes = {
+            ExecutionMode.ASYNC,
+            ExecutionMode.EXECUTOR,
+        };
+        for (ExecutionMode m : executionModes)
+    {
+        final Noop r = new Noop(m);
+        final CompletableFuture<Void> f = m.runAsync(r);
+        assertNull(f.join());
+        checkCompletedNormally(f, null);
+        r.assertInvoked();
+    }}
+
+    /**
+     * failing runAsync completes exceptionally after running Runnable
+     */
+    public void testRunAsync_exceptionalCompletion() {
+        ExecutionMode[] executionModes = {
+            ExecutionMode.ASYNC,
+            ExecutionMode.EXECUTOR,
+        };
+        for (ExecutionMode m : executionModes)
+    {
+        final FailingRunnable r = new FailingRunnable(m);
+        final CompletableFuture<Void> f = m.runAsync(r);
+        checkCompletedWithWrappedCFException(f);
+        r.assertInvoked();
+    }}
+
+    /**
+     * supplyAsync completes with result of supplier
+     */
+    public void testSupplyAsync_normalCompletion() {
+        ExecutionMode[] executionModes = {
+            ExecutionMode.ASYNC,
+            ExecutionMode.EXECUTOR,
+        };
+        for (ExecutionMode m : executionModes)
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final IntegerSupplier r = new IntegerSupplier(m, v1);
+        final CompletableFuture<Integer> f = m.supplyAsync(r);
+        assertSame(v1, f.join());
+        checkCompletedNormally(f, v1);
+        r.assertInvoked();
+    }}
+
+    /**
+     * Failing supplyAsync completes exceptionally
+     */
+    public void testSupplyAsync_exceptionalCompletion() {
+        ExecutionMode[] executionModes = {
+            ExecutionMode.ASYNC,
+            ExecutionMode.EXECUTOR,
+        };
+        for (ExecutionMode m : executionModes)
+    {
+        FailingSupplier r = new FailingSupplier(m);
+        CompletableFuture<Integer> f = m.supplyAsync(r);
+        checkCompletedWithWrappedCFException(f);
+        r.assertInvoked();
+    }}
+
+    // seq completion methods
+
+    /**
+     * thenRun result completes normally after normal completion of source
+     */
+    public void testThenRun_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
+        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
+
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        checkCompletedNormally(h4, null);
+        checkCompletedNormally(h5, null);
+        checkCompletedNormally(f, v1);
+        for (Noop r : rs) r.assertInvoked();
+    }}
+
+    /**
+     * thenRun result completes exceptionally after exceptional
+     * completion of source
+     */
+    public void testThenRun_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(f.completeExceptionally(ex));
+        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
+        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
+
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedWithWrappedException(h4, ex);
+        checkCompletedWithWrappedException(h5, ex);
+        checkCompletedExceptionally(f, ex);
+        for (Noop r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenRun result completes exceptionally if source cancelled
+     */
+    public void testThenRun_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
+        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
+
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        checkCompletedWithWrappedCancellationException(h4);
+        checkCompletedWithWrappedCancellationException(h5);
+        checkCancelled(f);
+        for (Noop r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenRun result completes exceptionally if action does
+     */
+    public void testThenRun_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final FailingRunnable[] rs = new FailingRunnable[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
+
+        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
+        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
+
+        checkCompletedWithWrappedCFException(h0);
+        checkCompletedWithWrappedCFException(h1);
+        checkCompletedWithWrappedCFException(h2);
+        checkCompletedWithWrappedCFException(h3);
+        checkCompletedWithWrappedCFException(h4);
+        checkCompletedWithWrappedCFException(h5);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * thenApply result completes normally after normal completion of source
+     */
+    public void testThenApply_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
+
+        checkCompletedNormally(h0, inc(v1));
+        checkCompletedNormally(h1, inc(v1));
+        checkCompletedNormally(h2, inc(v1));
+        checkCompletedNormally(h3, inc(v1));
+        checkCompletedNormally(f, v1);
+        for (IncFunction r : rs) r.assertValue(inc(v1));
+    }}
+
+    /**
+     * thenApply result completes exceptionally after exceptional
+     * completion of source
+     */
+    public void testThenApply_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
+        assertTrue(f.completeExceptionally(ex));
+        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedExceptionally(f, ex);
+        for (IncFunction r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenApply result completes exceptionally if source cancelled
+     */
+    public void testThenApply_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        checkCancelled(f);
+        for (IncFunction r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenApply result completes exceptionally if action does
+     */
+    public void testThenApply_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final FailingFunction[] rs = new FailingFunction[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedCFException(h0);
+        checkCompletedWithWrappedCFException(h1);
+        checkCompletedWithWrappedCFException(h2);
+        checkCompletedWithWrappedCFException(h3);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * thenAccept result completes normally after normal completion of source
+     */
+    public void testThenAccept_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
+
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        checkCompletedNormally(f, v1);
+        for (NoopConsumer r : rs) r.assertValue(v1);
+    }}
+
+    /**
+     * thenAccept result completes exceptionally after exceptional
+     * completion of source
+     */
+    public void testThenAccept_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
+        assertTrue(f.completeExceptionally(ex));
+        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedExceptionally(f, ex);
+        for (NoopConsumer r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenAccept result completes exceptionally if source cancelled
+     */
+    public void testThenAccept_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        checkCancelled(f);
+        for (NoopConsumer r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenAccept result completes exceptionally if action does
+     */
+    public void testThenAccept_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final FailingConsumer[] rs = new FailingConsumer[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedCFException(h0);
+        checkCompletedWithWrappedCFException(h1);
+        checkCompletedWithWrappedCFException(h2);
+        checkCompletedWithWrappedCFException(h3);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * thenCombine result completes normally after normal completion
+     * of sources
+     */
+    public void testThenCombine_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final SubtractFunction[] rs = new SubtractFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new SubtractFunction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Integer> h0 = m.thenCombine(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.thenCombine(fst, fst, rs[1]);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.thenCombine(fst, fst, rs[3]);
+        checkIncomplete(h0); rs[0].assertNotInvoked();
+        checkIncomplete(h2); rs[2].assertNotInvoked();
+        checkCompletedNormally(h1, subtract(w1, w1));
+        checkCompletedNormally(h3, subtract(w1, w1));
+        rs[1].assertValue(subtract(w1, w1));
+        rs[3].assertValue(subtract(w1, w1));
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Integer> h4 = m.thenCombine(f, g, rs[4]);
+
+        checkCompletedNormally(h0, subtract(v1, v2));
+        checkCompletedNormally(h2, subtract(v1, v2));
+        checkCompletedNormally(h4, subtract(v1, v2));
+        rs[0].assertValue(subtract(v1, v2));
+        rs[2].assertValue(subtract(v1, v2));
+        rs[4].assertValue(subtract(v1, v2));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * thenCombine result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testThenCombine_exceptionalCompletion() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final SubtractFunction r1 = new SubtractFunction(m);
+        final SubtractFunction r2 = new SubtractFunction(m);
+        final SubtractFunction r3 = new SubtractFunction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.completeExceptionally(ex) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.completeExceptionally(ex);
+
+        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
+
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCompletedExceptionally(failFirst ? fst : snd, ex);
+    }}
+
+    /**
+     * thenCombine result completes exceptionally if either source cancelled
+     */
+    public void testThenCombine_sourceCancelled() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final SubtractFunction r1 = new SubtractFunction(m);
+        final SubtractFunction r2 = new SubtractFunction(m);
+        final SubtractFunction r3 = new SubtractFunction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.cancel(mayInterruptIfRunning) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.cancel(mayInterruptIfRunning);
+
+        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
+
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCancelled(failFirst ? fst : snd);
+    }}
+
+    /**
+     * thenCombine result completes exceptionally if action does
+     */
+    public void testThenCombine_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingBiFunction r1 = new FailingBiFunction(m);
+        final FailingBiFunction r2 = new FailingBiFunction(m);
+        final FailingBiFunction r3 = new FailingBiFunction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
+
+        checkCompletedWithWrappedCFException(h1);
+        checkCompletedWithWrappedCFException(h2);
+        checkCompletedWithWrappedCFException(h3);
+        r1.assertInvoked();
+        r2.assertInvoked();
+        r3.assertInvoked();
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * thenAcceptBoth result completes normally after normal
+     * completion of sources
+     */
+    public void testThenAcceptBoth_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final SubtractAction r1 = new SubtractAction(m);
+        final SubtractAction r2 = new SubtractAction(m);
+        final SubtractAction r3 = new SubtractAction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
+
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        r1.assertValue(subtract(v1, v2));
+        r2.assertValue(subtract(v1, v2));
+        r3.assertValue(subtract(v1, v2));
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * thenAcceptBoth result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testThenAcceptBoth_exceptionalCompletion() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final SubtractAction r1 = new SubtractAction(m);
+        final SubtractAction r2 = new SubtractAction(m);
+        final SubtractAction r3 = new SubtractAction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.completeExceptionally(ex) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.completeExceptionally(ex);
+
+        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
+
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCompletedExceptionally(failFirst ? fst : snd, ex);
+    }}
+
+    /**
+     * thenAcceptBoth result completes exceptionally if either source cancelled
+     */
+    public void testThenAcceptBoth_sourceCancelled() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final SubtractAction r1 = new SubtractAction(m);
+        final SubtractAction r2 = new SubtractAction(m);
+        final SubtractAction r3 = new SubtractAction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.cancel(mayInterruptIfRunning) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.cancel(mayInterruptIfRunning);
+
+        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
+
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCancelled(failFirst ? fst : snd);
+    }}
+
+    /**
+     * thenAcceptBoth result completes exceptionally if action does
+     */
+    public void testThenAcceptBoth_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingBiConsumer r1 = new FailingBiConsumer(m);
+        final FailingBiConsumer r2 = new FailingBiConsumer(m);
+        final FailingBiConsumer r3 = new FailingBiConsumer(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
+
+        checkCompletedWithWrappedCFException(h1);
+        checkCompletedWithWrappedCFException(h2);
+        checkCompletedWithWrappedCFException(h3);
+        r1.assertInvoked();
+        r2.assertInvoked();
+        r3.assertInvoked();
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * runAfterBoth result completes normally after normal
+     * completion of sources
+     */
+    public void testRunAfterBoth_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final Noop r1 = new Noop(m);
+        final Noop r2 = new Noop(m);
+        final Noop r3 = new Noop(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
+
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        r1.assertInvoked();
+        r2.assertInvoked();
+        r3.assertInvoked();
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * runAfterBoth result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testRunAfterBoth_exceptionalCompletion() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final Noop r1 = new Noop(m);
+        final Noop r2 = new Noop(m);
+        final Noop r3 = new Noop(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.completeExceptionally(ex) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.completeExceptionally(ex);
+
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
+
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCompletedExceptionally(failFirst ? fst : snd, ex);
+    }}
+
+    /**
+     * runAfterBoth result completes exceptionally if either source cancelled
+     */
+    public void testRunAfterBoth_sourceCancelled() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final Noop r1 = new Noop(m);
+        final Noop r2 = new Noop(m);
+        final Noop r3 = new Noop(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.cancel(mayInterruptIfRunning) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.cancel(mayInterruptIfRunning);
+
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
+
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCancelled(failFirst ? fst : snd);
+    }}
+
+    /**
+     * runAfterBoth result completes exceptionally if action does
+     */
+    public void testRunAfterBoth_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingRunnable r1 = new FailingRunnable(m);
+        final FailingRunnable r2 = new FailingRunnable(m);
+        final FailingRunnable r3 = new FailingRunnable(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
+
+        checkCompletedWithWrappedCFException(h1);
+        checkCompletedWithWrappedCFException(h2);
+        checkCompletedWithWrappedCFException(h3);
+        r1.assertInvoked();
+        r2.assertInvoked();
+        r3.assertInvoked();
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * applyToEither result completes normally after normal completion
+     * of either source
+     */
+    public void testApplyToEither_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.complete(v1);
+        checkCompletedNormally(h0, inc(v1));
+        checkCompletedNormally(h1, inc(v1));
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+        checkCompletedNormally(h2, inc(v1));
+        checkCompletedNormally(h3, inc(v1));
+        g.complete(v2);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
+        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
+        rs[4].assertValue(h4.join());
+        rs[5].assertValue(h5.join());
+        assertTrue(Objects.equals(inc(v1), h4.join()) ||
+                   Objects.equals(inc(v2), h4.join()));
+        assertTrue(Objects.equals(inc(v1), h5.join()) ||
+                   Objects.equals(inc(v2), h5.join()));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+        checkCompletedNormally(h0, inc(v1));
+        checkCompletedNormally(h1, inc(v1));
+        checkCompletedNormally(h2, inc(v1));
+        checkCompletedNormally(h3, inc(v1));
+        for (int i = 0; i < 4; i++) rs[i].assertValue(inc(v1));
+    }}
+
+    /**
+     * applyToEither result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testApplyToEither_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.completeExceptionally(ex);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        g.complete(v1);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
+        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
+        try {
+            assertEquals(inc(v1), h4.join());
+            rs[4].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h4, ex);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h5.join());
+            rs[5].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h5, ex);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCompletedExceptionally(f, ex);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedWithWrappedException(h4, ex);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    public void testApplyToEither_exceptionalCompletion2() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+
+        // unspecified behavior - both source completions available
+        try {
+            assertEquals(inc(v1), h0.join());
+            rs[0].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h0, ex);
+            rs[0].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h1.join());
+            rs[1].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h1, ex);
+            rs[1].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h2.join());
+            rs[2].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h2, ex);
+            rs[2].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h3.join());
+            rs[3].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h3, ex);
+            rs[3].assertNotInvoked();
+        }
+
+        checkCompletedNormally(f, v1);
+        checkCompletedExceptionally(g, ex);
+    }}
+
+    /**
+     * applyToEither result completes exceptionally if either source cancelled
+     */
+    public void testApplyToEither_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.cancel(mayInterruptIfRunning);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        g.complete(v1);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
+        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
+        try {
+            assertEquals(inc(v1), h4.join());
+            rs[4].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h4);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h5.join());
+            rs[5].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h5);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCancelled(f);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    public void testApplyToEither_sourceCancelled2() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        assertTrue(fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
+        assertTrue(!fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+
+        // unspecified behavior - both source completions available
+        try {
+            assertEquals(inc(v1), h0.join());
+            rs[0].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h0);
+            rs[0].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h1.join());
+            rs[1].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h1);
+            rs[1].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h2.join());
+            rs[2].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h2);
+            rs[2].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h3.join());
+            rs[3].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h3);
+            rs[3].assertNotInvoked();
+        }
+
+        checkCompletedNormally(f, v1);
+        checkCancelled(g);
+    }}
+
+    /**
+     * applyToEither result completes exceptionally if action does
+     */
+    public void testApplyToEither_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingFunction[] rs = new FailingFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        f.complete(v1);
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+        checkCompletedWithWrappedCFException(h0);
+        checkCompletedWithWrappedCFException(h1);
+        checkCompletedWithWrappedCFException(h2);
+        checkCompletedWithWrappedCFException(h3);
+        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
+
+        g.complete(v2);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
+        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
+
+        checkCompletedWithWrappedCFException(h4);
+        assertTrue(Objects.equals(v1, rs[4].value) ||
+                   Objects.equals(v2, rs[4].value));
+        checkCompletedWithWrappedCFException(h5);
+        assertTrue(Objects.equals(v1, rs[5].value) ||
+                   Objects.equals(v2, rs[5].value));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * acceptEither result completes normally after normal completion
+     * of either source
+     */
+    public void testAcceptEither_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.complete(v1);
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        rs[0].assertValue(v1);
+        rs[1].assertValue(v1);
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        rs[2].assertValue(v1);
+        rs[3].assertValue(v1);
+        g.complete(v2);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
+        checkCompletedNormally(h4, null);
+        checkCompletedNormally(h5, null);
+        assertTrue(Objects.equals(v1, rs[4].value) ||
+                   Objects.equals(v2, rs[4].value));
+        assertTrue(Objects.equals(v1, rs[5].value) ||
+                   Objects.equals(v2, rs[5].value));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
+    }}
+
+    /**
+     * acceptEither result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testAcceptEither_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final NoopConsumer[] rs = new NoopConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.completeExceptionally(ex);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+
+        g.complete(v1);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
+        try {
+            assertNull(h4.join());
+            rs[4].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h4, ex);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertNull(h5.join());
+            rs[5].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h5, ex);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCompletedExceptionally(f, ex);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedWithWrappedException(h4, ex);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    public void testAcceptEither_exceptionalCompletion2() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final NoopConsumer[] rs = new NoopConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+
+        // unspecified behavior - both source completions available
+        try {
+            assertEquals(null, h0.join());
+            rs[0].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h0, ex);
+            rs[0].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h1.join());
+            rs[1].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h1, ex);
+            rs[1].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h2.join());
+            rs[2].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h2, ex);
+            rs[2].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h3.join());
+            rs[3].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h3, ex);
+            rs[3].assertNotInvoked();
+        }
+
+        checkCompletedNormally(f, v1);
+        checkCompletedExceptionally(g, ex);
+    }}
+
+    /**
+     * acceptEither result completes exceptionally if either source cancelled
+     */
+    public void testAcceptEither_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.cancel(mayInterruptIfRunning);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+
+        g.complete(v1);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
+        try {
+            assertNull(h4.join());
+            rs[4].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h4);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertNull(h5.join());
+            rs[5].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h5);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCancelled(f);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    /**
+     * acceptEither result completes exceptionally if action does
+     */
+    public void testAcceptEither_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingConsumer[] rs = new FailingConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        f.complete(v1);
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+        checkCompletedWithWrappedCFException(h0);
+        checkCompletedWithWrappedCFException(h1);
+        checkCompletedWithWrappedCFException(h2);
+        checkCompletedWithWrappedCFException(h3);
+        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
+
+        g.complete(v2);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
+
+        checkCompletedWithWrappedCFException(h4);
+        assertTrue(Objects.equals(v1, rs[4].value) ||
+                   Objects.equals(v2, rs[4].value));
+        checkCompletedWithWrappedCFException(h5);
+        assertTrue(Objects.equals(v1, rs[5].value) ||
+                   Objects.equals(v2, rs[5].value));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * runAfterEither result completes normally after normal completion
+     * of either source
+     */
+    public void testRunAfterEither_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.complete(v1);
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        rs[0].assertInvoked();
+        rs[1].assertInvoked();
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        rs[2].assertInvoked();
+        rs[3].assertInvoked();
+
+        g.complete(v2);
+
+        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        checkCompletedNormally(h4, null);
+        checkCompletedNormally(h5, null);
+        for (int i = 0; i < 6; i++) rs[i].assertInvoked();
+    }}
+
+    /**
+     * runAfterEither result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testRunAfterEither_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        assertTrue(f.completeExceptionally(ex));
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+
+        assertTrue(g.complete(v1));
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
+        try {
+            assertNull(h4.join());
+            rs[4].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h4, ex);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertNull(h5.join());
+            rs[5].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h5, ex);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCompletedExceptionally(f, ex);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedWithWrappedException(h4, ex);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    public void testRunAfterEither_exceptionalCompletion2() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        assertTrue( fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+
+        // unspecified behavior - both source completions available
+        try {
+            assertEquals(null, h0.join());
+            rs[0].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h0, ex);
+            rs[0].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h1.join());
+            rs[1].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h1, ex);
+            rs[1].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h2.join());
+            rs[2].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h2, ex);
+            rs[2].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h3.join());
+            rs[3].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h3, ex);
+            rs[3].assertNotInvoked();
+        }
+
+        checkCompletedNormally(f, v1);
+        checkCompletedExceptionally(g, ex);
+    }}
+
+    /**
+     * runAfterEither result completes exceptionally if either source cancelled
+     */
+    public void testRunAfterEither_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.cancel(mayInterruptIfRunning);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+
+        assertTrue(g.complete(v1));
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
+        try {
+            assertNull(h4.join());
+            rs[4].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h4);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertNull(h5.join());
+            rs[5].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h5);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCancelled(f);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    /**
+     * runAfterEither result completes exceptionally if action does
+     */
+    public void testRunAfterEither_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingRunnable[] rs = new FailingRunnable[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+        checkCompletedWithWrappedCFException(h0);
+        checkCompletedWithWrappedCFException(h1);
+        checkCompletedWithWrappedCFException(h2);
+        checkCompletedWithWrappedCFException(h3);
+        for (int i = 0; i < 4; i++) rs[i].assertInvoked();
+        assertTrue(g.complete(v2));
+        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
+        checkCompletedWithWrappedCFException(h4);
+        checkCompletedWithWrappedCFException(h5);
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+        for (int i = 0; i < 6; i++) rs[i].assertInvoked();
+    }}
+
+    /**
+     * thenCompose result completes normally after normal completion of source
+     */
+    public void testThenCompose_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFutureInc r = new CompletableFutureInc(m);
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.thenCompose(f, r);
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedNormally(g, inc(v1));
+        checkCompletedNormally(f, v1);
+        r.assertValue(v1);
+    }}
+
+    /**
+     * thenCompose result completes exceptionally after exceptional
+     * completion of source
+     */
+    public void testThenCompose_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        final CFException ex = new CFException();
+        final CompletableFutureInc r = new CompletableFutureInc(m);
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        final CompletableFuture<Integer> g = m.thenCompose(f, r);
+        if (createIncomplete) f.completeExceptionally(ex);
+
+        checkCompletedWithWrappedException(g, ex);
+        checkCompletedExceptionally(f, ex);
+        r.assertNotInvoked();
+    }}
+
+    /**
+     * thenCompose result completes exceptionally if action does
+     */
+    public void testThenCompose_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final FailingCompletableFutureFunction r
+            = new FailingCompletableFutureFunction(m);
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.thenCompose(f, r);
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedWithWrappedCFException(g);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * thenCompose result completes exceptionally if source cancelled
+     */
+    public void testThenCompose_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFutureInc r = new CompletableFutureInc(m);
+        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> g = m.thenCompose(f, r);
+        if (createIncomplete) {
+            checkIncomplete(g);
+            assertTrue(f.cancel(mayInterruptIfRunning));
+        }
+
+        checkCompletedWithWrappedCancellationException(g);
+        checkCancelled(f);
+    }}
+
+    /**
+     * thenCompose result completes exceptionally if the result of the action does
+     */
+    public void testThenCompose_actionReturnsFailingFuture() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (int order = 0; order < 6; order++)
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CompletableFuture<Integer> h;
+        // Test all permutations of orders
+        switch (order) {
+        case 0:
+            assertTrue(f.complete(v1));
+            assertTrue(g.completeExceptionally(ex));
+            h = m.thenCompose(f, (x -> g));
+            break;
+        case 1:
+            assertTrue(f.complete(v1));
+            h = m.thenCompose(f, (x -> g));
+            assertTrue(g.completeExceptionally(ex));
+            break;
+        case 2:
+            assertTrue(g.completeExceptionally(ex));
+            assertTrue(f.complete(v1));
+            h = m.thenCompose(f, (x -> g));
+            break;
+        case 3:
+            assertTrue(g.completeExceptionally(ex));
+            h = m.thenCompose(f, (x -> g));
+            assertTrue(f.complete(v1));
+            break;
+        case 4:
+            h = m.thenCompose(f, (x -> g));
+            assertTrue(f.complete(v1));
+            assertTrue(g.completeExceptionally(ex));
+            break;
+        case 5:
+            h = m.thenCompose(f, (x -> g));
+            assertTrue(f.complete(v1));
+            assertTrue(g.completeExceptionally(ex));
+            break;
+        default: throw new AssertionError();
+        }
+
+        checkCompletedExceptionally(g, ex);
+        checkCompletedWithWrappedException(h, ex);
+        checkCompletedNormally(f, v1);
+    }}
+
+    // other static methods
+
+    /**
+     * allOf(no component futures) returns a future completed normally
+     * with the value null
+     */
+    public void testAllOf_empty() throws Exception {
+        CompletableFuture<Void> f = CompletableFuture.allOf();
+        checkCompletedNormally(f, null);
+    }
+
+    /**
+     * allOf returns a future completed normally with the value null
+     * when all components complete normally
+     */
+    public void testAllOf_normal() throws Exception {
+        for (int k = 1; k < 10; k++) {
+            CompletableFuture<Integer>[] fs
+                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
+            for (int i = 0; i < k; i++) {
+                checkIncomplete(f);
+                checkIncomplete(CompletableFuture.allOf(fs));
+                fs[i].complete(one);
+            }
+            checkCompletedNormally(f, null);
+            checkCompletedNormally(CompletableFuture.allOf(fs), null);
+        }
+    }
+
+    public void testAllOf_backwards() throws Exception {
+        for (int k = 1; k < 10; k++) {
+            CompletableFuture<Integer>[] fs
+                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
+            for (int i = k - 1; i >= 0; i--) {
+                checkIncomplete(f);
+                checkIncomplete(CompletableFuture.allOf(fs));
+                fs[i].complete(one);
+            }
+            checkCompletedNormally(f, null);
+            checkCompletedNormally(CompletableFuture.allOf(fs), null);
+        }
+    }
+
+    public void testAllOf_exceptional() throws Exception {
+        for (int k = 1; k < 10; k++) {
+            CompletableFuture<Integer>[] fs
+                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
+            CFException ex = new CFException();
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
+            for (int i = 0; i < k; i++) {
+                checkIncomplete(f);
+                checkIncomplete(CompletableFuture.allOf(fs));
+                if (i != k / 2) {
+                    fs[i].complete(i);
+                    checkCompletedNormally(fs[i], i);
+                } else {
+                    fs[i].completeExceptionally(ex);
+                    checkCompletedExceptionally(fs[i], ex);
+                }
+            }
+            checkCompletedWithWrappedException(f, ex);
+            checkCompletedWithWrappedException(CompletableFuture.allOf(fs), ex);
+        }
+    }
+
+    /**
+     * anyOf(no component futures) returns an incomplete future
+     */
+    public void testAnyOf_empty() throws Exception {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Object> f = CompletableFuture.anyOf();
+        checkIncomplete(f);
+
+        f.complete(v1);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * anyOf returns a future completed normally with a value when
+     * a component future does
+     */
+    public void testAnyOf_normal() throws Exception {
+        for (int k = 0; k < 10; k++) {
+            CompletableFuture[] fs = new CompletableFuture[k];
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
+            checkIncomplete(f);
+            for (int i = 0; i < k; i++) {
+                fs[i].complete(i);
+                checkCompletedNormally(f, 0);
+                int x = (int) CompletableFuture.anyOf(fs).join();
+                assertTrue(0 <= x && x <= i);
+            }
+        }
+    }
+    public void testAnyOf_normal_backwards() throws Exception {
+        for (int k = 0; k < 10; k++) {
+            CompletableFuture[] fs = new CompletableFuture[k];
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
+            checkIncomplete(f);
+            for (int i = k - 1; i >= 0; i--) {
+                fs[i].complete(i);
+                checkCompletedNormally(f, k - 1);
+                int x = (int) CompletableFuture.anyOf(fs).join();
+                assertTrue(i <= x && x <= k - 1);
+            }
+        }
+    }
+
+    /**
+     * anyOf result completes exceptionally when any component does.
+     */
+    public void testAnyOf_exceptional() throws Exception {
+        for (int k = 0; k < 10; k++) {
+            CompletableFuture[] fs = new CompletableFuture[k];
+            CFException[] exs = new CFException[k];
+            for (int i = 0; i < k; i++) {
+                fs[i] = new CompletableFuture<>();
+                exs[i] = new CFException();
+            }
+            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
+            checkIncomplete(f);
+            for (int i = 0; i < k; i++) {
+                fs[i].completeExceptionally(exs[i]);
+                checkCompletedWithWrappedException(f, exs[0]);
+                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
+            }
+        }
+    }
+
+    public void testAnyOf_exceptional_backwards() throws Exception {
+        for (int k = 0; k < 10; k++) {
+            CompletableFuture[] fs = new CompletableFuture[k];
+            CFException[] exs = new CFException[k];
+            for (int i = 0; i < k; i++) {
+                fs[i] = new CompletableFuture<>();
+                exs[i] = new CFException();
+            }
+            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
+            checkIncomplete(f);
+            for (int i = k - 1; i >= 0; i--) {
+                fs[i].completeExceptionally(exs[i]);
+                checkCompletedWithWrappedException(f, exs[k - 1]);
+                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
+            }
+        }
+    }
+
+    /**
+     * Completion methods throw NullPointerException with null arguments
+     */
+    public void testNPE() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = new CompletableFuture<>();
+        CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
+        ThreadExecutor exec = new ThreadExecutor();
+
+        Runnable[] throwingActions = {
+            () -> CompletableFuture.supplyAsync(null),
+            () -> CompletableFuture.supplyAsync(null, exec),
+            () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.SYNC, 42), null),
+
+            () -> CompletableFuture.runAsync(null),
+            () -> CompletableFuture.runAsync(null, exec),
+            () -> CompletableFuture.runAsync(() -> {}, null),
+
+            () -> f.completeExceptionally(null),
+
+            () -> f.thenApply(null),
+            () -> f.thenApplyAsync(null),
+            () -> f.thenApplyAsync((x) -> x, null),
+            () -> f.thenApplyAsync(null, exec),
+
+            () -> f.thenAccept(null),
+            () -> f.thenAcceptAsync(null),
+            () -> f.thenAcceptAsync((x) -> {} , null),
+            () -> f.thenAcceptAsync(null, exec),
+
+            () -> f.thenRun(null),
+            () -> f.thenRunAsync(null),
+            () -> f.thenRunAsync(() -> {} , null),
+            () -> f.thenRunAsync(null, exec),
+
+            () -> f.thenCombine(g, null),
+            () -> f.thenCombineAsync(g, null),
+            () -> f.thenCombineAsync(g, null, exec),
+            () -> f.thenCombine(nullFuture, (x, y) -> x),
+            () -> f.thenCombineAsync(nullFuture, (x, y) -> x),
+            () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec),
+            () -> f.thenCombineAsync(g, (x, y) -> x, null),
+
+            () -> f.thenAcceptBoth(g, null),
+            () -> f.thenAcceptBothAsync(g, null),
+            () -> f.thenAcceptBothAsync(g, null, exec),
+            () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}),
+            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}),
+            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec),
+            () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null),
+
+            () -> f.runAfterBoth(g, null),
+            () -> f.runAfterBothAsync(g, null),
+            () -> f.runAfterBothAsync(g, null, exec),
+            () -> f.runAfterBoth(nullFuture, () -> {}),
+            () -> f.runAfterBothAsync(nullFuture, () -> {}),
+            () -> f.runAfterBothAsync(nullFuture, () -> {}, exec),
+            () -> f.runAfterBothAsync(g, () -> {}, null),
+
+            () -> f.applyToEither(g, null),
+            () -> f.applyToEitherAsync(g, null),
+            () -> f.applyToEitherAsync(g, null, exec),
+            () -> f.applyToEither(nullFuture, (x) -> x),
+            () -> f.applyToEitherAsync(nullFuture, (x) -> x),
+            () -> f.applyToEitherAsync(nullFuture, (x) -> x, exec),
+            () -> f.applyToEitherAsync(g, (x) -> x, null),
+
+            () -> f.acceptEither(g, null),
+            () -> f.acceptEitherAsync(g, null),
+            () -> f.acceptEitherAsync(g, null, exec),
+            () -> f.acceptEither(nullFuture, (x) -> {}),
+            () -> f.acceptEitherAsync(nullFuture, (x) -> {}),
+            () -> f.acceptEitherAsync(nullFuture, (x) -> {}, exec),
+            () -> f.acceptEitherAsync(g, (x) -> {}, null),
+
+            () -> f.runAfterEither(g, null),
+            () -> f.runAfterEitherAsync(g, null),
+            () -> f.runAfterEitherAsync(g, null, exec),
+            () -> f.runAfterEither(nullFuture, () -> {}),
+            () -> f.runAfterEitherAsync(nullFuture, () -> {}),
+            () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec),
+            () -> f.runAfterEitherAsync(g, () -> {}, null),
+
+            () -> f.thenCompose(null),
+            () -> f.thenComposeAsync(null),
+            () -> f.thenComposeAsync(new CompletableFutureInc(ExecutionMode.EXECUTOR), null),
+            () -> f.thenComposeAsync(null, exec),
+
+            () -> f.exceptionally(null),
+
+            () -> f.handle(null),
+
+            () -> CompletableFuture.allOf((CompletableFuture<?>)null),
+            () -> CompletableFuture.allOf((CompletableFuture<?>[])null),
+            () -> CompletableFuture.allOf(f, null),
+            () -> CompletableFuture.allOf(null, f),
+
+            () -> CompletableFuture.anyOf((CompletableFuture<?>)null),
+            () -> CompletableFuture.anyOf((CompletableFuture<?>[])null),
+            () -> CompletableFuture.anyOf(f, null),
+            () -> CompletableFuture.anyOf(null, f),
+
+            () -> f.obtrudeException(null),
+
+            () -> CompletableFuture.delayedExecutor(1L, SECONDS, null),
+            () -> CompletableFuture.delayedExecutor(1L, null, new ThreadExecutor()),
+            () -> CompletableFuture.delayedExecutor(1L, null),
+
+            () -> f.orTimeout(1L, null),
+            () -> f.completeOnTimeout(42, 1L, null),
+
+            () -> CompletableFuture.failedFuture(null),
+            () -> CompletableFuture.failedStage(null),
+        };
+
+        assertThrows(NullPointerException.class, throwingActions);
+        assertEquals(0, exec.count.get());
+    }
+
+    /**
+     * toCompletableFuture returns this CompletableFuture.
+     */
+    public void testToCompletableFuture() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        assertSame(f, f.toCompletableFuture());
+    }
+
+    // jdk9
+
+    /**
+     * newIncompleteFuture returns an incomplete CompletableFuture
+     */
+    public void testNewIncompleteFuture() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = f.newIncompleteFuture();
+        checkIncomplete(f);
+        checkIncomplete(g);
+        f.complete(v1);
+        checkCompletedNormally(f, v1);
+        checkIncomplete(g);
+        g.complete(v1);
+        checkCompletedNormally(g, v1);
+        assertSame(g.getClass(), CompletableFuture.class);
+    }}
+
+    /**
+     * completedStage returns a completed CompletionStage
+     */
+    public void testCompletedStage() {
+        AtomicInteger x = new AtomicInteger(0);
+        AtomicReference<Throwable> r = new AtomicReference<Throwable>();
+        CompletionStage<Integer> f = CompletableFuture.completedStage(1);
+        f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
+        assertEquals(x.get(), 1);
+        assertNull(r.get());
+    }
+
+    /**
+     * defaultExecutor by default returns the commonPool if
+     * it supports more than one thread.
+     */
+    public void testDefaultExecutor() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        Executor e = f.defaultExecutor();
+        Executor c = ForkJoinPool.commonPool();
+        if (ForkJoinPool.getCommonPoolParallelism() > 1)
+            assertSame(e, c);
+        else
+            assertNotSame(e, c);
+    }
+
+    /**
+     * failedFuture returns a CompletableFuture completed
+     * exceptionally with the given Exception
+     */
+    public void testFailedFuture() {
+        CFException ex = new CFException();
+        CompletableFuture<Integer> f = CompletableFuture.failedFuture(ex);
+        checkCompletedExceptionally(f, ex);
+    }
+
+    /**
+     * failedFuture(null) throws NPE
+     */
+    public void testFailedFuture_null() {
+        try {
+            CompletableFuture<Integer> f = CompletableFuture.failedFuture(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * copy returns a CompletableFuture that is completed normally,
+     * with the same value, when source is.
+     */
+    public void testCopy() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = f.copy();
+        checkIncomplete(f);
+        checkIncomplete(g);
+        f.complete(1);
+        checkCompletedNormally(f, 1);
+        checkCompletedNormally(g, 1);
+    }
+
+    /**
+     * copy returns a CompletableFuture that is completed exceptionally
+     * when source is.
+     */
+    public void testCopy2() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = f.copy();
+        checkIncomplete(f);
+        checkIncomplete(g);
+        CFException ex = new CFException();
+        f.completeExceptionally(ex);
+        checkCompletedExceptionally(f, ex);
+        checkCompletedWithWrappedException(g, ex);
+    }
+
+    /**
+     * minimalCompletionStage returns a CompletableFuture that is
+     * completed normally, with the same value, when source is.
+     */
+    public void testMinimalCompletionStage() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletionStage<Integer> g = f.minimalCompletionStage();
+        AtomicInteger x = new AtomicInteger(0);
+        AtomicReference<Throwable> r = new AtomicReference<Throwable>();
+        checkIncomplete(f);
+        g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
+        f.complete(1);
+        checkCompletedNormally(f, 1);
+        assertEquals(x.get(), 1);
+        assertNull(r.get());
+    }
+
+    /**
+     * minimalCompletionStage returns a CompletableFuture that is
+     * completed exceptionally when source is.
+     */
+    public void testMinimalCompletionStage2() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletionStage<Integer> g = f.minimalCompletionStage();
+        AtomicInteger x = new AtomicInteger(0);
+        AtomicReference<Throwable> r = new AtomicReference<Throwable>();
+        g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
+        checkIncomplete(f);
+        CFException ex = new CFException();
+        f.completeExceptionally(ex);
+        checkCompletedExceptionally(f, ex);
+        assertEquals(x.get(), 0);
+        assertEquals(r.get().getCause(), ex);
+    }
+
+    /**
+     * failedStage returns a CompletionStage completed
+     * exceptionally with the given Exception
+     */
+    public void testFailedStage() {
+        CFException ex = new CFException();
+        CompletionStage<Integer> f = CompletableFuture.failedStage(ex);
+        AtomicInteger x = new AtomicInteger(0);
+        AtomicReference<Throwable> r = new AtomicReference<Throwable>();
+        f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
+        assertEquals(x.get(), 0);
+        assertEquals(r.get(), ex);
+    }
+
+    /**
+     * completeAsync completes with value of given supplier
+     */
+    public void testCompleteAsync() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        f.completeAsync(() -> v1);
+        f.join();
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * completeAsync completes exceptionally if given supplier throws
+     */
+    public void testCompleteAsync2() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CFException ex = new CFException();
+        f.completeAsync(() -> {if (true) throw ex; return 1;});
+        try {
+            f.join();
+            shouldThrow();
+        } catch (CompletionException success) {}
+        checkCompletedWithWrappedException(f, ex);
+    }
+
+    /**
+     * completeAsync with given executor completes with value of given supplier
+     */
+    public void testCompleteAsync3() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        ThreadExecutor executor = new ThreadExecutor();
+        f.completeAsync(() -> v1, executor);
+        assertSame(v1, f.join());
+        checkCompletedNormally(f, v1);
+        assertEquals(1, executor.count.get());
+    }}
+
+    /**
+     * completeAsync with given executor completes exceptionally if
+     * given supplier throws
+     */
+    public void testCompleteAsync4() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CFException ex = new CFException();
+        ThreadExecutor executor = new ThreadExecutor();
+        f.completeAsync(() -> {if (true) throw ex; return 1;}, executor);
+        try {
+            f.join();
+            shouldThrow();
+        } catch (CompletionException success) {}
+        checkCompletedWithWrappedException(f, ex);
+        assertEquals(1, executor.count.get());
+    }
+
+    /**
+     * orTimeout completes with TimeoutException if not complete
+     */
+    public void testOrTimeout_timesOut() {
+        long timeoutMillis = timeoutMillis();
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        long startTime = System.nanoTime();
+        f.orTimeout(timeoutMillis, MILLISECONDS);
+        checkCompletedWithTimeoutException(f);
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+    }
+
+    /**
+     * orTimeout completes normally if completed before timeout
+     */
+    public void testOrTimeout_completed() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = new CompletableFuture<>();
+        long startTime = System.nanoTime();
+        f.complete(v1);
+        f.orTimeout(LONG_DELAY_MS, MILLISECONDS);
+        g.orTimeout(LONG_DELAY_MS, MILLISECONDS);
+        g.complete(v1);
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v1);
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
+    }}
+
+    /**
+     * completeOnTimeout completes with given value if not complete
+     */
+    public void testCompleteOnTimeout_timesOut() {
+        testInParallel(() -> testCompleteOnTimeout_timesOut(42),
+                       () -> testCompleteOnTimeout_timesOut(null));
+    }
+
+    public void testCompleteOnTimeout_timesOut(Integer v) {
+        long timeoutMillis = timeoutMillis();
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        long startTime = System.nanoTime();
+        f.completeOnTimeout(v, timeoutMillis, MILLISECONDS);
+        assertSame(v, f.join());
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+        f.complete(99);         // should have no effect
+        checkCompletedNormally(f, v);
+    }
+
+    /**
+     * completeOnTimeout has no effect if completed within timeout
+     */
+    public void testCompleteOnTimeout_completed() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = new CompletableFuture<>();
+        long startTime = System.nanoTime();
+        f.complete(v1);
+        f.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS);
+        g.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS);
+        g.complete(v1);
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v1);
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
+    }}
+
+    /**
+     * delayedExecutor returns an executor that delays submission
+     */
+    public void testDelayedExecutor() {
+        testInParallel(() -> testDelayedExecutor(null, null),
+                       () -> testDelayedExecutor(null, 1),
+                       () -> testDelayedExecutor(new ThreadExecutor(), 1),
+                       () -> testDelayedExecutor(new ThreadExecutor(), 1));
+    }
+
+    public void testDelayedExecutor(Executor executor, Integer v) throws Exception {
+        long timeoutMillis = timeoutMillis();
+        // Use an "unreasonably long" long timeout to catch lingering threads
+        long longTimeoutMillis = 1000 * 60 * 60 * 24;
+        final Executor delayer, longDelayer;
+        if (executor == null) {
+            delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS);
+            longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS);
+        } else {
+            delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS, executor);
+            longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS, executor);
+        }
+        long startTime = System.nanoTime();
+        CompletableFuture<Integer> f =
+            CompletableFuture.supplyAsync(() -> v, delayer);
+        CompletableFuture<Integer> g =
+            CompletableFuture.supplyAsync(() -> v, longDelayer);
+
+        assertNull(g.getNow(null));
+
+        assertSame(v, f.get(LONG_DELAY_MS, MILLISECONDS));
+        long millisElapsed = millisElapsedSince(startTime);
+        assertTrue(millisElapsed >= timeoutMillis);
+        assertTrue(millisElapsed < LONG_DELAY_MS / 2);
+
+        checkCompletedNormally(f, v);
+
+        checkIncomplete(g);
+        assertTrue(g.cancel(true));
+    }
+
+    //--- tests of implementation details; not part of official tck ---
+
+    Object resultOf(CompletableFuture<?> f) {
+        try {
+            java.lang.reflect.Field resultField
+                = CompletableFuture.class.getDeclaredField("result");
+            resultField.setAccessible(true);
+            return resultField.get(f);
+        } catch (Throwable t) { throw new AssertionError(t); }
+    }
+
+    public void testExceptionPropagationReusesResultObject() {
+        if (!testImplementationDetails) return;
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> v42 = CompletableFuture.completedFuture(42);
+        final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
+
+        List<Function<CompletableFuture<Integer>, CompletableFuture<?>>> funs
+            = new ArrayList<>();
+
+        funs.add((y) -> m.thenRun(y, new Noop(m)));
+        funs.add((y) -> m.thenAccept(y, new NoopConsumer(m)));
+        funs.add((y) -> m.thenApply(y, new IncFunction(m)));
+
+        funs.add((y) -> m.runAfterEither(y, incomplete, new Noop(m)));
+        funs.add((y) -> m.acceptEither(y, incomplete, new NoopConsumer(m)));
+        funs.add((y) -> m.applyToEither(y, incomplete, new IncFunction(m)));
+
+        funs.add((y) -> m.runAfterBoth(y, v42, new Noop(m)));
+        funs.add((y) -> m.thenAcceptBoth(y, v42, new SubtractAction(m)));
+        funs.add((y) -> m.thenCombine(y, v42, new SubtractFunction(m)));
+
+        funs.add((y) -> m.whenComplete(y, (Integer r, Throwable t) -> {}));
+
+        funs.add((y) -> m.thenCompose(y, new CompletableFutureInc(m)));
+
+        funs.add((y) -> CompletableFuture.allOf(new CompletableFuture<?>[] {y, v42}));
+        funs.add((y) -> CompletableFuture.anyOf(new CompletableFuture<?>[] {y, incomplete}));
+
+        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
+                 fun : funs) {
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            f.completeExceptionally(ex);
+            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
+            checkCompletedWithWrappedException(src, ex);
+            CompletableFuture<?> dep = fun.apply(src);
+            checkCompletedWithWrappedException(dep, ex);
+            assertSame(resultOf(src), resultOf(dep));
+        }
+
+        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
+                 fun : funs) {
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
+            CompletableFuture<?> dep = fun.apply(src);
+            f.completeExceptionally(ex);
+            checkCompletedWithWrappedException(src, ex);
+            checkCompletedWithWrappedException(dep, ex);
+            assertSame(resultOf(src), resultOf(dep));
+        }
+
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
+                 fun : funs) {
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            f.cancel(mayInterruptIfRunning);
+            checkCancelled(f);
+            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
+            checkCompletedWithWrappedCancellationException(src);
+            CompletableFuture<?> dep = fun.apply(src);
+            checkCompletedWithWrappedCancellationException(dep);
+            assertSame(resultOf(src), resultOf(dep));
+        }
+
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
+                 fun : funs) {
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
+            CompletableFuture<?> dep = fun.apply(src);
+            f.cancel(mayInterruptIfRunning);
+            checkCancelled(f);
+            checkCompletedWithWrappedCancellationException(src);
+            checkCompletedWithWrappedCancellationException(dep);
+            assertSame(resultOf(src), resultOf(dep));
+        }
+    }}
+
+    /**
+     * Minimal completion stages throw UOE for all non-CompletionStage methods
+     */
+   // TODO(streams):
+    // public void testMinimalCompletionStage_minimality() {
+    //     if (!testImplementationDetails) return;
+    //     Function<Method, String> toSignature =
+    //         (method) -> method.getName() + Arrays.toString(method.getParameterTypes());
+    //     Predicate<Method> isNotStatic =
+    //         (method) -> (method.getModifiers() & Modifier.STATIC) == 0;
+    //     List<Method> minimalMethods =
+    //         Stream.of(Object.class, CompletionStage.class)
+    //         .flatMap((klazz) -> Stream.of(klazz.getMethods()))
+    //         .filter(isNotStatic)
+    //         .collect(Collectors.toList());
+    //     // Methods from CompletableFuture permitted NOT to throw UOE
+    //     String[] signatureWhitelist = {
+    //         "newIncompleteFuture[]",
+    //         "defaultExecutor[]",
+    //         "minimalCompletionStage[]",
+    //         "copy[]",
+    //     };
+    //     Set<String> permittedMethodSignatures =
+    //         Stream.concat(minimalMethods.stream().map(toSignature),
+    //                       Stream.of(signatureWhitelist))
+    //         .collect(Collectors.toSet());
+    //     List<Method> allMethods = Stream.of(CompletableFuture.class.getMethods())
+    //         .filter(isNotStatic)
+    //         .filter((method) -> !permittedMethodSignatures.contains(toSignature.apply(method)))
+    //         .collect(Collectors.toList());
+
+    //     CompletionStage<Integer> minimalStage =
+    //         new CompletableFuture<Integer>().minimalCompletionStage();
+
+    //     List<Method> bugs = new ArrayList<>();
+    //     for (Method method : allMethods) {
+    //         Class<?>[] parameterTypes = method.getParameterTypes();
+    //         Object[] args = new Object[parameterTypes.length];
+    //         // Manufacture boxed primitives for primitive params
+    //         for (int i = 0; i < args.length; i++) {
+    //             Class<?> type = parameterTypes[i];
+    //             if (parameterTypes[i] == boolean.class)
+    //                 args[i] = false;
+    //             else if (parameterTypes[i] == int.class)
+    //                 args[i] = 0;
+    //             else if (parameterTypes[i] == long.class)
+    //                 args[i] = 0L;
+    //         }
+    //         try {
+    //             method.invoke(minimalStage, args);
+    //             bugs.add(method);
+    //         }
+    //         catch (java.lang.reflect.InvocationTargetException expected) {
+    //             if (! (expected.getCause() instanceof UnsupportedOperationException)) {
+    //                 bugs.add(method);
+    //                 // expected.getCause().printStackTrace();
+    //             }
+    //         }
+    //         catch (ReflectiveOperationException bad) { throw new Error(bad); }
+    //     }
+    //     if (!bugs.isEmpty())
+    //         throw new Error("Methods did not throw UOE: " + bugs.toString());
+    // }
+
+    static class Monad {
+        static class ZeroException extends RuntimeException {
+            public ZeroException() { super("monadic zero"); }
+        }
+        // "return", "unit"
+        static <T> CompletableFuture<T> unit(T value) {
+            return completedFuture(value);
+        }
+        // monadic zero ?
+        static <T> CompletableFuture<T> zero() {
+            return failedFuture(new ZeroException());
+        }
+        // >=>
+        static <T,U,V> Function<T, CompletableFuture<V>> compose
+            (Function<T, CompletableFuture<U>> f,
+             Function<U, CompletableFuture<V>> g) {
+            return (x) -> f.apply(x).thenCompose(g);
+        }
+
+        static void assertZero(CompletableFuture<?> f) {
+            try {
+                f.getNow(null);
+                throw new AssertionFailedError("should throw");
+            } catch (CompletionException success) {
+                assertTrue(success.getCause() instanceof ZeroException);
+            }
+        }
+
+        static <T> void assertFutureEquals(CompletableFuture<T> f,
+                                           CompletableFuture<T> g) {
+            T fval = null, gval = null;
+            Throwable fex = null, gex = null;
+
+            try { fval = f.get(); }
+            catch (ExecutionException ex) { fex = ex.getCause(); }
+            catch (Throwable ex) { fex = ex; }
+
+            try { gval = g.get(); }
+            catch (ExecutionException ex) { gex = ex.getCause(); }
+            catch (Throwable ex) { gex = ex; }
+
+            if (fex != null || gex != null)
+                assertSame(fex.getClass(), gex.getClass());
+            else
+                assertEquals(fval, gval);
+        }
+
+        static class PlusFuture<T> extends CompletableFuture<T> {
+            AtomicReference<Throwable> firstFailure = new AtomicReference<>(null);
+        }
+
+        /** Implements "monadic plus". */
+        static <T> CompletableFuture<T> plus(CompletableFuture<? extends T> f,
+                                             CompletableFuture<? extends T> g) {
+            PlusFuture<T> plus = new PlusFuture<T>();
+            BiConsumer<T, Throwable> action = (T result, Throwable ex) -> {
+                try {
+                    if (ex == null) {
+                        if (plus.complete(result))
+                            if (plus.firstFailure.get() != null)
+                                plus.firstFailure.set(null);
+                    }
+                    else if (plus.firstFailure.compareAndSet(null, ex)) {
+                        if (plus.isDone())
+                            plus.firstFailure.set(null);
+                    }
+                    else {
+                        // first failure has precedence
+                        Throwable first = plus.firstFailure.getAndSet(null);
+
+                        // may fail with "Self-suppression not permitted"
+                        try { first.addSuppressed(ex); }
+                        catch (Exception ignored) {}
+
+                        plus.completeExceptionally(first);
+                    }
+                } catch (Throwable unexpected) {
+                    plus.completeExceptionally(unexpected);
+                }
+            };
+            f.whenComplete(action);
+            g.whenComplete(action);
+            return plus;
+        }
+    }
+
+    /**
+     * CompletableFuture is an additive monad - sort of.
+     * https://en.wikipedia.org/wiki/Monad_(functional_programming)#Additive_monads
+     */
+    public void testAdditiveMonad() throws Throwable {
+        Function<Long, CompletableFuture<Long>> unit = Monad::unit;
+        CompletableFuture<Long> zero = Monad.zero();
+
+        // Some mutually non-commutative functions
+        Function<Long, CompletableFuture<Long>> triple
+            = (x) -> Monad.unit(3 * x);
+        Function<Long, CompletableFuture<Long>> inc
+            = (x) -> Monad.unit(x + 1);
+
+        // unit is a right identity: m >>= unit === m
+        Monad.assertFutureEquals(inc.apply(5L).thenCompose(unit),
+                                 inc.apply(5L));
+        // unit is a left identity: (unit x) >>= f === f x
+        Monad.assertFutureEquals(unit.apply(5L).thenCompose(inc),
+                                 inc.apply(5L));
+
+        // associativity: (m >>= f) >>= g === m >>= ( \x -> (f x >>= g) )
+        Monad.assertFutureEquals(
+            unit.apply(5L).thenCompose(inc).thenCompose(triple),
+            unit.apply(5L).thenCompose((x) -> inc.apply(x).thenCompose(triple)));
+
+        // The case for CompletableFuture as an additive monad is weaker...
+
+        // zero is a monadic zero
+        Monad.assertZero(zero);
+
+        // left zero: zero >>= f === zero
+        Monad.assertZero(zero.thenCompose(inc));
+        // right zero: f >>= (\x -> zero) === zero
+        Monad.assertZero(inc.apply(5L).thenCompose((x) -> zero));
+
+        // f plus zero === f
+        Monad.assertFutureEquals(Monad.unit(5L),
+                                 Monad.plus(Monad.unit(5L), zero));
+        // zero plus f === f
+        Monad.assertFutureEquals(Monad.unit(5L),
+                                 Monad.plus(zero, Monad.unit(5L)));
+        // zero plus zero === zero
+        Monad.assertZero(Monad.plus(zero, zero));
+        {
+            CompletableFuture<Long> f = Monad.plus(Monad.unit(5L),
+                                                   Monad.unit(8L));
+            // non-determinism
+            assertTrue(f.get() == 5L || f.get() == 8L);
+        }
+
+        CompletableFuture<Long> godot = new CompletableFuture<>();
+        // f plus godot === f (doesn't wait for godot)
+        Monad.assertFutureEquals(Monad.unit(5L),
+                                 Monad.plus(Monad.unit(5L), godot));
+        // godot plus f === f (doesn't wait for godot)
+        Monad.assertFutureEquals(Monad.unit(5L),
+                                 Monad.plus(godot, Monad.unit(5L)));
+    }
+
+//     static <U> U join(CompletionStage<U> stage) {
+//         CompletableFuture<U> f = new CompletableFuture<>();
+//         stage.whenComplete((v, ex) -> {
+//             if (ex != null) f.completeExceptionally(ex); else f.complete(v);
+//         });
+//         return f.join();
+//     }
+
+//     static <U> boolean isDone(CompletionStage<U> stage) {
+//         CompletableFuture<U> f = new CompletableFuture<>();
+//         stage.whenComplete((v, ex) -> {
+//             if (ex != null) f.completeExceptionally(ex); else f.complete(v);
+//         });
+//         return f.isDone();
+//     }
+
+//     static <U> U join2(CompletionStage<U> stage) {
+//         return stage.toCompletableFuture().copy().join();
+//     }
+
+//     static <U> boolean isDone2(CompletionStage<U> stage) {
+//         return stage.toCompletableFuture().copy().isDone();
+//     }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentHashMap8Test.java b/jsr166-tests/src/test/java/jsr166/ConcurrentHashMap8Test.java
new file mode 100644
index 0000000..60de8b9
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentHashMap8Test.java
@@ -0,0 +1,1096 @@
+/*
+ * 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 jsr166;
+
+import static java.util.Spliterator.CONCURRENT;
+import static java.util.Spliterator.DISTINCT;
+import static java.util.Spliterator.NONNULL;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiFunction;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ConcurrentHashMap8Test extends JSR166TestCase {
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(ConcurrentHashMap8Test.class);
+    // }
+
+    /**
+     * Returns a new map from Integers 1-5 to Strings "A"-"E".
+     */
+    private static ConcurrentHashMap map5() {
+        ConcurrentHashMap map = new ConcurrentHashMap(5);
+        assertTrue(map.isEmpty());
+        map.put(one, "A");
+        map.put(two, "B");
+        map.put(three, "C");
+        map.put(four, "D");
+        map.put(five, "E");
+        assertFalse(map.isEmpty());
+        assertEquals(5, map.size());
+        return map;
+    }
+
+    /**
+     * getOrDefault returns value if present, else default
+     */
+    public void testGetOrDefault() {
+        ConcurrentHashMap map = map5();
+        assertEquals(map.getOrDefault(one, "Z"), "A");
+        assertEquals(map.getOrDefault(six, "Z"), "Z");
+    }
+
+    /**
+     * computeIfAbsent adds when the given key is not present
+     */
+    public void testComputeIfAbsent() {
+        ConcurrentHashMap map = map5();
+        map.computeIfAbsent(six, (x) -> "Z");
+        assertTrue(map.containsKey(six));
+    }
+
+    /**
+     * computeIfAbsent does not replace if the key is already present
+     */
+    public void testComputeIfAbsent2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("A", map.computeIfAbsent(one, (x) -> "Z"));
+    }
+
+    /**
+     * computeIfAbsent does not add if function returns null
+     */
+    public void testComputeIfAbsent3() {
+        ConcurrentHashMap map = map5();
+        map.computeIfAbsent(six, (x) -> null);
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * computeIfPresent does not replace if the key is already present
+     */
+    public void testComputeIfPresent() {
+        ConcurrentHashMap map = map5();
+        map.computeIfPresent(six, (x, y) -> "Z");
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * computeIfPresent adds when the given key is not present
+     */
+    public void testComputeIfPresent2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Z", map.computeIfPresent(one, (x, y) -> "Z"));
+    }
+
+    /**
+     * compute does not replace if the function returns null
+     */
+    public void testCompute() {
+        ConcurrentHashMap map = map5();
+        map.compute(six, (x, y) -> null);
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * compute adds when the given key is not present
+     */
+    public void testCompute2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Z", map.compute(six, (x, y) -> "Z"));
+    }
+
+    /**
+     * compute replaces when the given key is present
+     */
+    public void testCompute3() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Z", map.compute(one, (x, y) -> "Z"));
+    }
+
+    /**
+     * compute removes when the given key is present and function returns null
+     */
+    public void testCompute4() {
+        ConcurrentHashMap map = map5();
+        map.compute(one, (x, y) -> null);
+        assertFalse(map.containsKey(one));
+    }
+
+    /**
+     * merge adds when the given key is not present
+     */
+    public void testMerge1() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Y", map.merge(six, "Y", (x, y) -> "Z"));
+    }
+
+    /**
+     * merge replaces when the given key is present
+     */
+    public void testMerge2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Z", map.merge(one, "Y", (x, y) -> "Z"));
+    }
+
+    /**
+     * merge removes when the given key is present and function returns null
+     */
+    public void testMerge3() {
+        ConcurrentHashMap map = map5();
+        map.merge(one, "Y", (x, y) -> null);
+        assertFalse(map.containsKey(one));
+    }
+
+    static Set<Integer> populatedSet(int n) {
+        Set<Integer> a = ConcurrentHashMap.<Integer>newKeySet();
+        assertTrue(a.isEmpty());
+        for (int i = 0; i < n; i++)
+            assertTrue(a.add(i));
+        assertEquals(n == 0, a.isEmpty());
+        assertEquals(n, a.size());
+        return a;
+    }
+
+    static Set populatedSet(Integer[] elements) {
+        Set<Integer> a = ConcurrentHashMap.<Integer>newKeySet();
+        assertTrue(a.isEmpty());
+        for (int i = 0; i < elements.length; i++)
+            assertTrue(a.add(elements[i]));
+        assertFalse(a.isEmpty());
+        assertEquals(elements.length, a.size());
+        return a;
+    }
+
+    /**
+     * replaceAll replaces all matching values.
+     */
+    public void testReplaceAll() {
+        ConcurrentHashMap<Integer, String> map = map5();
+        map.replaceAll((x, y) -> { return x > 3 ? "Z" : y; });
+        assertEquals("A", map.get(one));
+        assertEquals("B", map.get(two));
+        assertEquals("C", map.get(three));
+        assertEquals("Z", map.get(four));
+        assertEquals("Z", map.get(five));
+    }
+
+    /**
+     * Default-constructed set is empty
+     */
+    public void testNewKeySet() {
+        Set a = ConcurrentHashMap.newKeySet();
+        assertTrue(a.isEmpty());
+    }
+
+    /**
+     * keySet.add adds the key with the established value to the map;
+     * remove removes it.
+     */
+    public void testKeySetAddRemove() {
+        ConcurrentHashMap map = map5();
+        Set set1 = map.keySet();
+        Set set2 = map.keySet(true);
+        set2.add(six);
+        assertTrue(((ConcurrentHashMap.KeySetView)set2).getMap() == map);
+        assertTrue(((ConcurrentHashMap.KeySetView)set1).getMap() == map);
+        assertEquals(set2.size(), map.size());
+        assertEquals(set1.size(), map.size());
+        assertTrue((Boolean)map.get(six));
+        assertTrue(set1.contains(six));
+        assertTrue(set2.contains(six));
+        set2.remove(six);
+        assertNull(map.get(six));
+        assertFalse(set1.contains(six));
+        assertFalse(set2.contains(six));
+    }
+
+    /**
+     * keySet.addAll adds each element from the given collection
+     */
+    public void testAddAll() {
+        Set full = populatedSet(3);
+        assertTrue(full.addAll(Arrays.asList(three, four, five)));
+        assertEquals(6, full.size());
+        assertFalse(full.addAll(Arrays.asList(three, four, five)));
+        assertEquals(6, full.size());
+    }
+
+    /**
+     * keySet.addAll adds each element from the given collection that did not
+     * already exist in the set
+     */
+    public void testAddAll2() {
+        Set full = populatedSet(3);
+        // "one" is duplicate and will not be added
+        assertTrue(full.addAll(Arrays.asList(three, four, one)));
+        assertEquals(5, full.size());
+        assertFalse(full.addAll(Arrays.asList(three, four, one)));
+        assertEquals(5, full.size());
+    }
+
+    /**
+     * keySet.add will not add the element if it already exists in the set
+     */
+    public void testAdd2() {
+        Set full = populatedSet(3);
+        assertFalse(full.add(one));
+        assertEquals(3, full.size());
+    }
+
+    /**
+     * keySet.add adds the element when it does not exist in the set
+     */
+    public void testAdd3() {
+        Set full = populatedSet(3);
+        assertTrue(full.add(three));
+        assertTrue(full.contains(three));
+        assertFalse(full.add(three));
+        assertTrue(full.contains(three));
+    }
+
+    /**
+     * keySet.add throws UnsupportedOperationException if no default
+     * mapped value
+     */
+    public void testAdd4() {
+        Set full = map5().keySet();
+        try {
+            full.add(three);
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+    }
+
+    /**
+     * keySet.add throws NullPointerException if the specified key is
+     * null
+     */
+    public void testAdd5() {
+        Set full = populatedSet(3);
+        try {
+            full.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * KeySetView.getMappedValue returns the map's mapped value
+     */
+    public void testGetMappedValue() {
+        ConcurrentHashMap map = map5();
+        assertNull(map.keySet().getMappedValue());
+        try {
+            map.keySet(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+        ConcurrentHashMap.KeySetView set = map.keySet(one);
+        assertFalse(set.add(one));
+        assertTrue(set.add(six));
+        assertTrue(set.add(seven));
+        assertTrue(set.getMappedValue() == one);
+        assertTrue(map.get(one) != one);
+        assertTrue(map.get(six) == one);
+        assertTrue(map.get(seven) == one);
+    }
+
+    void checkSpliteratorCharacteristics(Spliterator<?> sp,
+                                         int requiredCharacteristics) {
+        assertEquals(requiredCharacteristics,
+                     requiredCharacteristics & sp.characteristics());
+    }
+
+    /**
+     * KeySetView.spliterator returns spliterator over the elements in this set
+     */
+    public void testKeySetSpliterator() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap map = map5();
+        Set set = map.keySet();
+        Spliterator<Integer> sp = set.spliterator();
+        checkSpliteratorCharacteristics(sp, CONCURRENT | DISTINCT | NONNULL);
+        assertEquals(sp.estimateSize(), map.size());
+        Spliterator<Integer> sp2 = sp.trySplit();
+        sp.forEachRemaining((Integer x) -> adder.add(x.longValue()));
+        long v = adder.sumThenReset();
+        sp2.forEachRemaining((Integer x) -> adder.add(x.longValue()));
+        long v2 = adder.sum();
+        assertEquals(v + v2, 15);
+    }
+
+    /**
+     * keyset.clear removes all elements from the set
+     */
+    public void testClear() {
+        Set full = populatedSet(3);
+        full.clear();
+        assertEquals(0, full.size());
+    }
+
+    /**
+     * keyset.contains returns true for added elements
+     */
+    public void testContains() {
+        Set full = populatedSet(3);
+        assertTrue(full.contains(one));
+        assertFalse(full.contains(five));
+    }
+
+    /**
+     * KeySets with equal elements are equal
+     */
+    public void testEquals() {
+        Set a = populatedSet(3);
+        Set b = populatedSet(3);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertEquals(a.hashCode(), b.hashCode());
+        a.add(m1);
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        b.add(m1);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertEquals(a.hashCode(), b.hashCode());
+    }
+
+    /**
+     * KeySet.containsAll returns true for collections with subset of elements
+     */
+    public void testContainsAll() {
+        Collection full = populatedSet(3);
+        assertTrue(full.containsAll(Arrays.asList()));
+        assertTrue(full.containsAll(Arrays.asList(one)));
+        assertTrue(full.containsAll(Arrays.asList(one, two)));
+        assertFalse(full.containsAll(Arrays.asList(one, two, six)));
+        assertFalse(full.containsAll(Arrays.asList(six)));
+    }
+
+    /**
+     * KeySet.isEmpty is true when empty, else false
+     */
+    public void testIsEmpty() {
+        assertTrue(populatedSet(0).isEmpty());
+        assertFalse(populatedSet(3).isEmpty());
+    }
+
+    /**
+     * KeySet.iterator() returns an iterator containing the elements of the
+     * set
+     */
+    public void testIterator() {
+        Collection empty = ConcurrentHashMap.newKeySet();
+        int size = 20;
+        assertFalse(empty.iterator().hasNext());
+        try {
+            empty.iterator().next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+
+        Integer[] elements = new Integer[size];
+        for (int i = 0; i < size; i++)
+            elements[i] = i;
+        Collections.shuffle(Arrays.asList(elements));
+        Collection<Integer> full = populatedSet(elements);
+
+        Iterator it = full.iterator();
+        for (int j = 0; j < size; j++) {
+            assertTrue(it.hasNext());
+            it.next();
+        }
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collections has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(ConcurrentHashMap.newKeySet().iterator());
+        assertIteratorExhausted(new ConcurrentHashMap().entrySet().iterator());
+        assertIteratorExhausted(new ConcurrentHashMap().values().iterator());
+        assertIteratorExhausted(new ConcurrentHashMap().keySet().iterator());
+    }
+
+    /**
+     * KeySet.iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        Set q = populatedSet(3);
+        Iterator it = q.iterator();
+        Object removed = it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertFalse(it.next().equals(removed));
+        assertFalse(it.next().equals(removed));
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * KeySet.toString holds toString of elements
+     */
+    public void testToString() {
+        assertEquals("[]", ConcurrentHashMap.newKeySet().toString());
+        Set full = populatedSet(3);
+        String s = full.toString();
+        for (int i = 0; i < 3; ++i)
+            assertTrue(s.contains(String.valueOf(i)));
+    }
+
+    /**
+     * KeySet.removeAll removes all elements from the given collection
+     */
+    public void testRemoveAll() {
+        Set full = populatedSet(3);
+        assertTrue(full.removeAll(Arrays.asList(one, two)));
+        assertEquals(1, full.size());
+        assertFalse(full.removeAll(Arrays.asList(one, two)));
+        assertEquals(1, full.size());
+    }
+
+    /**
+     * KeySet.remove removes an element
+     */
+    public void testRemove() {
+        Set full = populatedSet(3);
+        full.remove(one);
+        assertFalse(full.contains(one));
+        assertEquals(2, full.size());
+    }
+
+    /**
+     * keySet.size returns the number of elements
+     */
+    public void testSize() {
+        Set empty = ConcurrentHashMap.newKeySet();
+        Set full = populatedSet(3);
+        assertEquals(3, full.size());
+        assertEquals(0, empty.size());
+    }
+
+    /**
+     * KeySet.toArray() returns an Object array containing all elements from
+     * the set
+     */
+    public void testToArray() {
+        Object[] a = ConcurrentHashMap.newKeySet().toArray();
+        assertTrue(Arrays.equals(new Object[0], a));
+        assertSame(Object[].class, a.getClass());
+        int size = 20;
+        Integer[] elements = new Integer[size];
+        for (int i = 0; i < size; i++)
+            elements[i] = i;
+        Collections.shuffle(Arrays.asList(elements));
+        Collection<Integer> full = populatedSet(elements);
+
+        assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray())));
+        assertTrue(full.containsAll(Arrays.asList(full.toArray())));
+        assertSame(Object[].class, full.toArray().getClass());
+    }
+
+    /**
+     * toArray(Integer array) returns an Integer array containing all
+     * elements from the set
+     */
+    public void testToArray2() {
+        Collection empty = ConcurrentHashMap.newKeySet();
+        Integer[] a;
+        int size = 20;
+
+        a = new Integer[0];
+        assertSame(a, empty.toArray(a));
+
+        a = new Integer[size / 2];
+        Arrays.fill(a, 42);
+        assertSame(a, empty.toArray(a));
+        assertNull(a[0]);
+        for (int i = 1; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+
+        Integer[] elements = new Integer[size];
+        for (int i = 0; i < size; i++)
+            elements[i] = i;
+        Collections.shuffle(Arrays.asList(elements));
+        Collection<Integer> full = populatedSet(elements);
+
+        Arrays.fill(a, 42);
+        assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray(a))));
+        for (int i = 0; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+        assertSame(Integer[].class, full.toArray(a).getClass());
+
+        a = new Integer[size];
+        Arrays.fill(a, 42);
+        assertSame(a, full.toArray(a));
+        assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray(a))));
+    }
+
+    /**
+     * A deserialized serialized set is equal
+     */
+    public void testSerialization() throws Exception {
+        int size = 20;
+        Set x = populatedSet(size);
+        Set y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    static final int SIZE = 10000;
+    static ConcurrentHashMap<Long, Long> longMap;
+
+    static ConcurrentHashMap<Long, Long> longMap() {
+        if (longMap == null) {
+            longMap = new ConcurrentHashMap<Long, Long>(SIZE);
+            for (int i = 0; i < SIZE; ++i)
+                longMap.put(Long.valueOf(i), Long.valueOf(2 *i));
+        }
+        return longMap;
+    }
+
+    // explicit function class to avoid type inference problems
+    static class AddKeys implements BiFunction<Map.Entry<Long,Long>, Map.Entry<Long,Long>, Map.Entry<Long,Long>> {
+        public Map.Entry<Long,Long> apply(Map.Entry<Long,Long> x, Map.Entry<Long,Long> y) {
+            return new AbstractMap.SimpleEntry<Long,Long>
+             (Long.valueOf(x.getKey().longValue() + y.getKey().longValue()),
+              Long.valueOf(1L));
+        }
+    }
+
+    /**
+     * forEachKeySequentially traverses all keys
+     */
+    public void testForEachKeySequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachKey(Long.MAX_VALUE, (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachValueSequentially traverses all values
+     */
+    public void testForEachValueSequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachValue(Long.MAX_VALUE, (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), SIZE * (SIZE - 1));
+    }
+
+    /**
+     * forEachSequentially traverses all mappings
+     */
+    public void testForEachSequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEach(Long.MAX_VALUE, (Long x, Long y) -> adder.add(x.longValue() + y.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachEntrySequentially traverses all entries
+     */
+    public void testForEachEntrySequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachEntry(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> adder.add(e.getKey().longValue() + e.getValue().longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachKeyInParallel traverses all keys
+     */
+    public void testForEachKeyInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachKey(1L, (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachValueInParallel traverses all values
+     */
+    public void testForEachValueInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachValue(1L, (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), SIZE * (SIZE - 1));
+    }
+
+    /**
+     * forEachInParallel traverses all mappings
+     */
+    public void testForEachInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEach(1L, (Long x, Long y) -> adder.add(x.longValue() + y.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachEntryInParallel traverses all entries
+     */
+    public void testForEachEntryInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachEntry(1L, (Map.Entry<Long,Long> e) -> adder.add(e.getKey().longValue() + e.getValue().longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachKeySequentially traverses the given
+     * transformations of all keys
+     */
+    public void testMappedForEachKeySequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachKey(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                 (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachValueSequentially traverses the given
+     * transformations of all values
+     */
+    public void testMappedForEachValueSequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachValue(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                   (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1));
+    }
+
+    /**
+     * Mapped forEachSequentially traverses the given
+     * transformations of all mappings
+     */
+    public void testMappedForEachSequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEach(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
+                              (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachEntrySequentially traverses the given
+     * transformations of all entries
+     */
+    public void testMappedForEachEntrySequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachEntry(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> Long.valueOf(e.getKey().longValue() + e.getValue().longValue()),
+                                   (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachKeyInParallel traverses the given
+     * transformations of all keys
+     */
+    public void testMappedForEachKeyInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachKey(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
+                               (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachValueInParallel traverses the given
+     * transformations of all values
+     */
+    public void testMappedForEachValueInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachValue(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                 (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1));
+    }
+
+    /**
+     * Mapped forEachInParallel traverses the given
+     * transformations of all mappings
+     */
+    public void testMappedForEachInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEach(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
+                            (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachEntryInParallel traverses the given
+     * transformations of all entries
+     */
+    public void testMappedForEachEntryInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachEntry(1L, (Map.Entry<Long,Long> e) -> Long.valueOf(e.getKey().longValue() + e.getValue().longValue()),
+                                 (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysSequentially accumulates across all keys,
+     */
+    public void testReduceKeysSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduceKeys(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceValuesSequentially accumulates across all values
+     */
+    public void testReduceValuesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduceKeys(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceEntriesSequentially accumulates across all entries
+     */
+    public void testReduceEntriesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Map.Entry<Long,Long> r;
+        r = m.reduceEntries(Long.MAX_VALUE, new AddKeys());
+        assertEquals(r.getKey().longValue(), (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysInParallel accumulates across all keys
+     */
+    public void testReduceKeysInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduceKeys(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceValuesInParallel accumulates across all values
+     */
+    public void testReduceValuesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduceValues(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceEntriesInParallel accumulate across all entries
+     */
+    public void testReduceEntriesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Map.Entry<Long,Long> r;
+        r = m.reduceEntries(1L, new AddKeys());
+        assertEquals(r.getKey().longValue(), (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped reduceKeysSequentially accumulates mapped keys
+     */
+    public void testMapReduceKeysSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduceKeys(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                     (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)4 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped reduceValuesSequentially accumulates mapped values
+     */
+    public void testMapReduceValuesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduceValues(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                       (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)4 * SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceSequentially accumulates across all transformed mappings
+     */
+    public void testMappedReduceSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduce(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
+                                 (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+
+        assertEquals((long)r, (long)3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped reduceKeysInParallel, accumulates mapped keys
+     */
+    public void testMapReduceKeysInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduceKeys(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                   (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)4 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped reduceValuesInParallel accumulates mapped values
+     */
+    public void testMapReduceValuesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduceValues(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                     (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)4 * SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceInParallel accumulate across all transformed mappings
+     */
+    public void testMappedReduceInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduce(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
+                               (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToLongSequentially accumulates mapped keys
+     */
+    public void testReduceKeysToLongSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        long lr = m.reduceKeysToLong(Long.MAX_VALUE, (Long x) -> x.longValue(), 0L, Long::sum);
+        assertEquals(lr, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToIntSequentially accumulates mapped keys
+     */
+    public void testReduceKeysToIntSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        int ir = m.reduceKeysToInt(Long.MAX_VALUE, (Long x) -> x.intValue(), 0, Integer::sum);
+        assertEquals(ir, SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToDoubleSequentially accumulates mapped keys
+     */
+    public void testReduceKeysToDoubleSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        double dr = m.reduceKeysToDouble(Long.MAX_VALUE, (Long x) -> x.doubleValue(), 0.0, Double::sum);
+        assertEquals(dr, (double)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceValuesToLongSequentially accumulates mapped values
+     */
+    public void testReduceValuesToLongSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        long lr = m.reduceValuesToLong(Long.MAX_VALUE, (Long x) -> x.longValue(), 0L, Long::sum);
+        assertEquals(lr, (long)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceValuesToIntSequentially accumulates mapped values
+     */
+    public void testReduceValuesToIntSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        int ir = m.reduceValuesToInt(Long.MAX_VALUE, (Long x) -> x.intValue(), 0, Integer::sum);
+        assertEquals(ir, SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceValuesToDoubleSequentially accumulates mapped values
+     */
+    public void testReduceValuesToDoubleSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        double dr = m.reduceValuesToDouble(Long.MAX_VALUE, (Long x) -> x.doubleValue(), 0.0, Double::sum);
+        assertEquals(dr, (double)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceKeysToLongInParallel accumulates mapped keys
+     */
+    public void testReduceKeysToLongInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        long lr = m.reduceKeysToLong(1L, (Long x) -> x.longValue(), 0L, Long::sum);
+        assertEquals(lr, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToIntInParallel accumulates mapped keys
+     */
+    public void testReduceKeysToIntInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        int ir = m.reduceKeysToInt(1L, (Long x) -> x.intValue(), 0, Integer::sum);
+        assertEquals(ir, SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToDoubleInParallel accumulates mapped values
+     */
+    public void testReduceKeysToDoubleInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        double dr = m.reduceKeysToDouble(1L, (Long x) -> x.doubleValue(), 0.0, Double::sum);
+        assertEquals(dr, (double)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceValuesToLongInParallel accumulates mapped values
+     */
+    public void testReduceValuesToLongInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        long lr = m.reduceValuesToLong(1L, (Long x) -> x.longValue(), 0L, Long::sum);
+        assertEquals(lr, (long)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceValuesToIntInParallel accumulates mapped values
+     */
+    public void testReduceValuesToIntInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        int ir = m.reduceValuesToInt(1L, (Long x) -> x.intValue(), 0, Integer::sum);
+        assertEquals(ir, SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceValuesToDoubleInParallel accumulates mapped values
+     */
+    public void testReduceValuesToDoubleInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        double dr = m.reduceValuesToDouble(1L, (Long x) -> x.doubleValue(), 0.0, Double::sum);
+        assertEquals(dr, (double)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * searchKeysSequentially returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchKeysSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchKeys(Long.MAX_VALUE, (Long x) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchKeys(Long.MAX_VALUE, (Long x) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchValuesSequentially returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchValuesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchValues(Long.MAX_VALUE,
+            (Long x) -> (x.longValue() == (long)(SIZE/2)) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchValues(Long.MAX_VALUE,
+            (Long x) -> (x.longValue() < 0L) ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchSequentially returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.search(Long.MAX_VALUE, (Long x, Long y) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.search(Long.MAX_VALUE, (Long x, Long y) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchEntriesSequentially returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchEntriesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchEntries(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> e.getKey().longValue() == (long)(SIZE/2) ? e.getKey() : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchEntries(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> e.getKey().longValue() < 0L ? e.getKey() : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchKeysInParallel returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchKeysInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchKeys(1L, (Long x) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchKeys(1L, (Long x) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchValuesInParallel returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchValuesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchValues(1L, (Long x) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchValues(1L, (Long x) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchInParallel returns a non-null result of search function,
+     * or null if none
+     */
+    public void testSearchInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.search(1L, (Long x, Long y) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.search(1L, (Long x, Long y) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchEntriesInParallel returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchEntriesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchEntries(1L, (Map.Entry<Long,Long> e) -> e.getKey().longValue() == (long)(SIZE/2) ? e.getKey() : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchEntries(1L, (Map.Entry<Long,Long> e) -> e.getKey().longValue() < 0L ? e.getKey() : null);
+        assertNull(r);
+    }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java
index 4650f41..f427127 100644
--- a/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentHashMapTest.java
@@ -30,7 +30,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ConcurrentHashMapTest.class);
     // }
 
     /**
@@ -50,7 +50,9 @@
     }
 
     /** Re-implement Integer.compare for old java versions */
-    static int compare(int x, int y) { return x < y ? -1 : x > y ? 1 : 0; }
+    static int compare(int x, int y) {
+        return (x < y) ? -1 : (x > y) ? 1 : 0;
+    }
 
     // classes for testing Comparable fallbacks
     static class BI implements Comparable<BI> {
@@ -538,7 +540,7 @@
     /**
      * Constructor (initialCapacity, loadFactor) throws
      * IllegalArgumentException if either argument is negative
-      */
+     */
     public void testConstructor2() {
         try {
             new ConcurrentHashMap(-1, .75f);
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java
index c445957..6625e7e 100644
--- a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedDequeTest.java
@@ -29,7 +29,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ConcurrentLinkedDequeTest.class);
     // }
 
     /**
@@ -69,8 +69,7 @@
      */
     public void testConstructor4() {
         try {
-            Integer[] ints = new Integer[SIZE];
-            new ConcurrentLinkedDeque(Arrays.asList(ints));
+            new ConcurrentLinkedDeque(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -79,10 +78,10 @@
      * Initializing from Collection with some null elements throws NPE
      */
     public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             new ConcurrentLinkedDeque(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -120,7 +119,7 @@
     public void testSize() {
         ConcurrentLinkedDeque q = populatedDeque(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.remove();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -133,8 +132,8 @@
      * push(null) throws NPE
      */
     public void testPushNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
             q.push(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -168,8 +167,8 @@
      * offer(null) throws NPE
      */
     public void testOfferNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
             q.offer(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -179,8 +178,8 @@
      * offerFirst(null) throws NPE
      */
     public void testOfferFirstNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
             q.offerFirst(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -190,8 +189,8 @@
      * offerLast(null) throws NPE
      */
     public void testOfferLastNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
             q.offerLast(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -234,8 +233,8 @@
      * add(null) throws NPE
      */
     public void testAddNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
             q.add(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -245,8 +244,8 @@
      * addFirst(null) throws NPE
      */
     public void testAddFirstNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
             q.addFirst(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -256,8 +255,8 @@
      * addLast(null) throws NPE
      */
     public void testAddLastNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
             q.addLast(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -300,8 +299,8 @@
      * addAll(null) throws NPE
      */
     public void testAddAll1() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
             q.addAll(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -311,8 +310,8 @@
      * addAll(this) throws IAE
      */
     public void testAddAllSelf() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
         try {
-            ConcurrentLinkedDeque q = populatedDeque(SIZE);
             q.addAll(q);
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -322,10 +321,9 @@
      * addAll of a collection with null elements throws NPE
      */
     public void testAddAll2() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
-            Integer[] ints = new Integer[SIZE];
-            q.addAll(Arrays.asList(ints));
+            q.addAll(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -335,11 +333,11 @@
      * possibly adding some elements
      */
     public void testAddAll3() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -376,7 +374,7 @@
      */
     public void testPollLast() {
         ConcurrentLinkedDeque q = populatedDeque(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.pollLast());
         }
         assertNull(q.pollLast());
@@ -445,14 +443,14 @@
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertTrue(q.contains(i-1));
+            assertTrue(q.contains(i - 1));
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertFalse(q.remove(i+1));
-            assertFalse(q.contains(i+1));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
         }
         assertTrue(q.isEmpty());
     }
@@ -476,7 +474,7 @@
      */
     public void testPeekLast() {
         ConcurrentLinkedDeque q = populatedDeque(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.peekLast());
             assertEquals(i, q.pollLast());
             assertTrue(q.peekLast() == null ||
@@ -505,7 +503,7 @@
      */
     public void testLastElement() {
         ConcurrentLinkedDeque q = populatedDeque(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.getLast());
             assertEquals(i, q.pollLast());
         }
@@ -556,7 +554,7 @@
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.removeFirstOccurrence(new Integer(i)));
-            assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+            assertFalse(q.removeFirstOccurrence(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
@@ -571,7 +569,7 @@
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.removeLastOccurrence(new Integer(i)));
-            assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+            assertFalse(q.removeLastOccurrence(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
@@ -630,7 +628,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.remove();
         }
     }
@@ -643,7 +641,7 @@
             ConcurrentLinkedDeque q = populatedDeque(SIZE);
             ConcurrentLinkedDeque p = populatedDeque(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.remove());
                 assertFalse(q.contains(x));
@@ -759,18 +757,18 @@
         final Random rng = new Random();
         for (int iters = 0; iters < 100; ++iters) {
             int max = rng.nextInt(5) + 2;
-            int split = rng.nextInt(max-1) + 1;
+            int split = rng.nextInt(max - 1) + 1;
             for (int j = 1; j <= max; ++j)
                 q.add(new Integer(j));
             Iterator it = q.iterator();
             for (int j = 1; j <= split; ++j)
                 assertEquals(it.next(), new Integer(j));
             it.remove();
-            assertEquals(it.next(), new Integer(split+1));
+            assertEquals(it.next(), new Integer(split + 1));
             for (int j = 1; j <= split; ++j)
                 q.remove(new Integer(j));
             it = q.iterator();
-            for (int j = split+1; j <= max; ++j) {
+            for (int j = split + 1; j <= max; ++j) {
                 assertEquals(it.next(), new Integer(j));
                 it.remove();
             }
@@ -827,18 +825,18 @@
         final Random rng = new Random();
         for (int iters = 0; iters < 100; ++iters) {
             int max = rng.nextInt(5) + 2;
-            int split = rng.nextInt(max-1) + 1;
+            int split = rng.nextInt(max - 1) + 1;
             for (int j = max; j >= 1; --j)
                 q.add(new Integer(j));
             Iterator it = q.descendingIterator();
             for (int j = 1; j <= split; ++j)
                 assertEquals(it.next(), new Integer(j));
             it.remove();
-            assertEquals(it.next(), new Integer(split+1));
+            assertEquals(it.next(), new Integer(split + 1));
             for (int j = 1; j <= split; ++j)
                 q.remove(new Integer(j));
             it = q.descendingIterator();
-            for (int j = split+1; j <= max; ++j) {
+            for (int j = split + 1; j <= max; ++j) {
                 assertEquals(it.next(), new Integer(j));
                 it.remove();
             }
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java
index d3f5b1f..70519a4 100644
--- a/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentLinkedQueueTest.java
@@ -27,7 +27,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ConcurrentLinkedQueueTest.class);
     // }
 
     /**
@@ -66,8 +66,7 @@
      */
     public void testConstructor4() {
         try {
-            Integer[] ints = new Integer[SIZE];
-            new ConcurrentLinkedQueue(Arrays.asList(ints));
+            new ConcurrentLinkedQueue(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -76,10 +75,10 @@
      * Initializing from Collection with some null elements throws NPE
      */
     public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             new ConcurrentLinkedQueue(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -117,7 +116,7 @@
     public void testSize() {
         ConcurrentLinkedQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.remove();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -130,8 +129,8 @@
      * offer(null) throws NPE
      */
     public void testOfferNull() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
         try {
-            ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
             q.offer(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -141,8 +140,8 @@
      * add(null) throws NPE
      */
     public void testAddNull() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
         try {
-            ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
             q.add(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -172,8 +171,8 @@
      * addAll(null) throws NPE
      */
     public void testAddAll1() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
         try {
-            ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
             q.addAll(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -183,8 +182,8 @@
      * addAll(this) throws IAE
      */
     public void testAddAllSelf() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
         try {
-            ConcurrentLinkedQueue q = populatedQueue(SIZE);
             q.addAll(q);
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -194,10 +193,9 @@
      * addAll of a collection with null elements throws NPE
      */
     public void testAddAll2() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
         try {
-            ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
-            Integer[] ints = new Integer[SIZE];
-            q.addAll(Arrays.asList(ints));
+            q.addAll(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -207,11 +205,11 @@
      * possibly adding some elements
      */
     public void testAddAll3() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -295,14 +293,14 @@
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertTrue(q.contains(i-1));
+            assertTrue(q.contains(i - 1));
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertFalse(q.remove(i+1));
-            assertFalse(q.contains(i+1));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
         }
         assertTrue(q.isEmpty());
     }
@@ -361,7 +359,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.remove();
         }
     }
@@ -374,7 +372,7 @@
             ConcurrentLinkedQueue q = populatedQueue(SIZE);
             ConcurrentLinkedQueue p = populatedQueue(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.remove());
                 assertFalse(q.contains(x));
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java
index 0aadd23..f53a446 100644
--- a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListMapTest.java
@@ -30,7 +30,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ConcurrentSkipListMapTest.class);
     // }
 
     /**
@@ -1278,7 +1278,7 @@
     }
 
     static boolean eq(Integer i, int j) {
-        return i == null ? j == -1 : i == j;
+        return (i == null) ? j == -1 : i == j;
     }
 
 }
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java
index 41f8835..959d703 100644
--- a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSetTest.java
@@ -29,7 +29,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ConcurrentSkipListSetTest.class);
     // }
 
     static class MyReverseComparator implements Comparator {
@@ -46,7 +46,7 @@
         ConcurrentSkipListSet<Integer> q =
             new ConcurrentSkipListSet<Integer>();
         assertTrue(q.isEmpty());
-        for (int i = n-1; i >= 0; i -= 2)
+        for (int i = n - 1; i >= 0; i -= 2)
             assertTrue(q.add(new Integer(i)));
         for (int i = (n & 1); i < n; i += 2)
             assertTrue(q.add(new Integer(i)));
@@ -92,8 +92,7 @@
      */
     public void testConstructor4() {
         try {
-            Integer[] ints = new Integer[SIZE];
-            new ConcurrentSkipListSet(Arrays.asList(ints));
+            new ConcurrentSkipListSet(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -102,10 +101,10 @@
      * Initializing from Collection with some null elements throws NPE
      */
     public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             new ConcurrentSkipListSet(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -134,7 +133,7 @@
         for (int i = 0; i < SIZE; ++i)
             ints[i] = new Integer(i);
         q.addAll(Arrays.asList(ints));
-        for (int i = SIZE-1; i >= 0; --i)
+        for (int i = SIZE - 1; i >= 0; --i)
             assertEquals(ints[i], q.pollFirst());
     }
 
@@ -158,7 +157,7 @@
     public void testSize() {
         ConcurrentSkipListSet q = populatedSet(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.pollFirst();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -238,7 +237,7 @@
     public void testAddAll3() {
         ConcurrentSkipListSet q = new ConcurrentSkipListSet();
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         try {
             q.addAll(Arrays.asList(ints));
@@ -253,7 +252,7 @@
         Integer[] empty = new Integer[0];
         Integer[] ints = new Integer[SIZE];
         for (int i = 0; i < SIZE; ++i)
-            ints[i] = new Integer(SIZE-1-i);
+            ints[i] = new Integer(SIZE - 1 - i);
         ConcurrentSkipListSet q = new ConcurrentSkipListSet();
         assertFalse(q.addAll(Arrays.asList(empty)));
         assertTrue(q.addAll(Arrays.asList(ints)));
@@ -277,7 +276,7 @@
      */
     public void testPollLast() {
         ConcurrentSkipListSet q = populatedSet(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.pollLast());
         }
         assertNull(q.pollFirst());
@@ -292,14 +291,14 @@
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertTrue(q.contains(i-1));
+            assertTrue(q.contains(i - 1));
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertFalse(q.remove(i+1));
-            assertFalse(q.contains(i+1));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
         }
         assertTrue(q.isEmpty());
     }
@@ -358,7 +357,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.pollFirst();
         }
     }
@@ -371,7 +370,7 @@
             ConcurrentSkipListSet q = populatedSet(SIZE);
             ConcurrentSkipListSet p = populatedSet(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.pollFirst());
                 assertFalse(q.contains(x));
@@ -980,7 +979,7 @@
     }
 
     static boolean eq(Integer i, int j) {
-        return i == null ? j == -1 : i == j;
+        return (i == null) ? j == -1 : i == j;
     }
 
 }
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java
index 5315bcb..a6510f5 100644
--- a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubMapTest.java
@@ -28,7 +28,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ConcurrentSkipListSubMapTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java
index f1c4aae..220a092 100644
--- a/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ConcurrentSkipListSubSetTest.java
@@ -24,7 +24,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ConcurrentSkipListSubSetTest.class);
     // }
 
     static class MyReverseComparator implements Comparator {
@@ -42,7 +42,7 @@
             new ConcurrentSkipListSet<Integer>();
         assertTrue(q.isEmpty());
 
-        for (int i = n-1; i >= 0; i -= 2)
+        for (int i = n - 1; i >= 0; i -= 2)
             assertTrue(q.add(new Integer(i)));
         for (int i = (n & 1); i < n; i += 2)
             assertTrue(q.add(new Integer(i)));
@@ -127,7 +127,7 @@
     public void testSize() {
         NavigableSet q = populatedSet(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.pollFirst();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -206,8 +206,8 @@
     public void testAddAll3() {
         NavigableSet q = set0();
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
-            ints[i] = new Integer(i+SIZE);
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i + SIZE);
         try {
             q.addAll(Arrays.asList(ints));
             shouldThrow();
@@ -221,7 +221,7 @@
         Integer[] empty = new Integer[0];
         Integer[] ints = new Integer[SIZE];
         for (int i = 0; i < SIZE; ++i)
-            ints[i] = new Integer(SIZE-1- i);
+            ints[i] = new Integer(SIZE - 1 - i);
         NavigableSet q = set0();
         assertFalse(q.addAll(Arrays.asList(empty)));
         assertTrue(q.addAll(Arrays.asList(ints)));
@@ -249,14 +249,14 @@
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertTrue(q.contains(i-1));
+            assertTrue(q.contains(i - 1));
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertFalse(q.remove(i+1));
-            assertFalse(q.contains(i+1));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
         }
         assertTrue(q.isEmpty());
     }
@@ -315,7 +315,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.pollFirst();
         }
     }
@@ -328,7 +328,7 @@
             NavigableSet q = populatedSet(SIZE);
             NavigableSet p = populatedSet(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.pollFirst());
                 assertFalse(q.contains(x));
@@ -623,7 +623,7 @@
     public void testDescendingSize() {
         NavigableSet q = populatedSet(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.pollFirst();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -702,8 +702,8 @@
     public void testDescendingAddAll3() {
         NavigableSet q = dset0();
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
-            ints[i] = new Integer(i+SIZE);
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i + SIZE);
         try {
             q.addAll(Arrays.asList(ints));
             shouldThrow();
@@ -717,7 +717,7 @@
         Integer[] empty = new Integer[0];
         Integer[] ints = new Integer[SIZE];
         for (int i = 0; i < SIZE; ++i)
-            ints[i] = new Integer(SIZE-1- i);
+            ints[i] = new Integer(SIZE - 1 - i);
         NavigableSet q = dset0();
         assertFalse(q.addAll(Arrays.asList(empty)));
         assertTrue(q.addAll(Arrays.asList(ints)));
@@ -746,7 +746,7 @@
         }
         for (int i = 0; i < SIZE; i += 2 ) {
             assertTrue(q.remove(new Integer(i)));
-            assertFalse(q.remove(new Integer(i+1)));
+            assertFalse(q.remove(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
@@ -805,7 +805,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.pollFirst();
         }
     }
@@ -818,7 +818,7 @@
             NavigableSet q = populatedSet(SIZE);
             NavigableSet p = populatedSet(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.pollFirst());
                 assertFalse(q.contains(x));
diff --git a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java
index 658268a..8a37d03 100644
--- a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java
+++ b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArrayListTest.java
@@ -31,7 +31,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(CopyOnWriteArrayListTest.class);
     // }
 
     static CopyOnWriteArrayList<Integer> populatedArray(int n) {
@@ -67,7 +67,7 @@
      */
     public void testConstructor2() {
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         CopyOnWriteArrayList a = new CopyOnWriteArrayList(ints);
         for (int i = 0; i < SIZE; ++i)
@@ -79,7 +79,7 @@
      */
     public void testConstructor3() {
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         CopyOnWriteArrayList a = new CopyOnWriteArrayList(Arrays.asList(ints));
         for (int i = 0; i < SIZE; ++i)
@@ -181,18 +181,26 @@
         CopyOnWriteArrayList b = populatedArray(3);
         assertTrue(a.equals(b));
         assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
         assertEquals(a.hashCode(), b.hashCode());
         a.add(m1);
         assertFalse(a.equals(b));
         assertFalse(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertFalse(b.containsAll(a));
         b.add(m1);
         assertTrue(a.equals(b));
         assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
         assertEquals(a.hashCode(), b.hashCode());
+
+        assertFalse(a.equals(null));
     }
 
     /**
-     * containsAll returns true for collection with subset of elements
+     * containsAll returns true for collections with subset of elements
      */
     public void testContainsAll() {
         CopyOnWriteArrayList full = populatedArray(3);
@@ -201,6 +209,11 @@
         assertTrue(full.containsAll(Arrays.asList(one, two)));
         assertFalse(full.containsAll(Arrays.asList(one, two, six)));
         assertFalse(full.containsAll(Arrays.asList(six)));
+
+        try {
+            full.containsAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -342,7 +355,7 @@
         ListIterator i = full.listIterator(1);
         int j;
         for (j = 0; i.hasNext(); j++)
-            assertEquals(j+1, i.next());
+            assertEquals(j + 1, i.next());
         assertEquals(2, j);
     }
 
@@ -441,7 +454,7 @@
         a = new Integer[0];
         assertSame(a, empty.toArray(a));
 
-        a = new Integer[SIZE/2];
+        a = new Integer[SIZE / 2];
         Arrays.fill(a, 42);
         assertSame(a, empty.toArray(a));
         assertNull(a[0]);
@@ -465,7 +478,7 @@
         assertSame(a, full.toArray(a));
         assertTrue(Arrays.equals(elements, a));
 
-        a = new Integer[2*SIZE];
+        a = new Integer[2 * SIZE];
         Arrays.fill(a, 42);
         assertSame(a, full.toArray(a));
         assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE)));
diff --git a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java
index 2810802..a486c6a 100644
--- a/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java
+++ b/jsr166-tests/src/test/java/jsr166/CopyOnWriteArraySetTest.java
@@ -28,7 +28,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(CopyOnWriteArraySetTest.class);
     // }
 
     static CopyOnWriteArraySet<Integer> populatedSet(int n) {
@@ -64,7 +64,7 @@
      */
     public void testConstructor3() {
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         CopyOnWriteArraySet a = new CopyOnWriteArraySet(Arrays.asList(ints));
         for (int i = 0; i < SIZE; ++i)
@@ -139,14 +139,46 @@
         CopyOnWriteArraySet b = populatedSet(3);
         assertTrue(a.equals(b));
         assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
         assertEquals(a.hashCode(), b.hashCode());
+        assertEquals(a.size(), b.size());
+
         a.add(m1);
         assertFalse(a.equals(b));
         assertFalse(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertFalse(b.containsAll(a));
         b.add(m1);
         assertTrue(a.equals(b));
         assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
         assertEquals(a.hashCode(), b.hashCode());
+
+        Object x = a.iterator().next();
+        a.remove(x);
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        assertFalse(a.containsAll(b));
+        assertTrue(b.containsAll(a));
+        a.add(x);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
+        assertEquals(a.hashCode(), b.hashCode());
+        assertEquals(a.size(), b.size());
+
+        CopyOnWriteArraySet empty1 = new CopyOnWriteArraySet(Arrays.asList());
+        CopyOnWriteArraySet empty2 = new CopyOnWriteArraySet(Arrays.asList());
+        assertTrue(empty1.equals(empty1));
+        assertTrue(empty1.equals(empty2));
+
+        assertFalse(empty1.equals(a));
+        assertFalse(a.equals(empty1));
+
+        assertFalse(a.equals(null));
     }
 
     /**
@@ -154,11 +186,24 @@
      */
     public void testContainsAll() {
         Collection full = populatedSet(3);
+        assertTrue(full.containsAll(full));
         assertTrue(full.containsAll(Arrays.asList()));
         assertTrue(full.containsAll(Arrays.asList(one)));
         assertTrue(full.containsAll(Arrays.asList(one, two)));
         assertFalse(full.containsAll(Arrays.asList(one, two, six)));
         assertFalse(full.containsAll(Arrays.asList(six)));
+
+        CopyOnWriteArraySet empty1 = new CopyOnWriteArraySet(Arrays.asList());
+        CopyOnWriteArraySet empty2 = new CopyOnWriteArraySet(Arrays.asList());
+        assertTrue(empty1.containsAll(empty2));
+        assertTrue(empty1.containsAll(empty1));
+        assertFalse(empty1.containsAll(full));
+        assertTrue(full.containsAll(empty1));
+
+        try {
+            full.containsAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -289,7 +334,7 @@
         a = new Integer[0];
         assertSame(a, empty.toArray(a));
 
-        a = new Integer[SIZE/2];
+        a = new Integer[SIZE / 2];
         Arrays.fill(a, 42);
         assertSame(a, empty.toArray(a));
         assertNull(a[0]);
@@ -313,7 +358,7 @@
         assertSame(a, full.toArray(a));
         assertTrue(Arrays.equals(elements, a));
 
-        a = new Integer[2*SIZE];
+        a = new Integer[2 * SIZE];
         Arrays.fill(a, 42);
         assertSame(a, full.toArray(a));
         assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE)));
@@ -327,10 +372,10 @@
      * not store the objects inside the set
      */
     public void testToArray_ArrayStoreException() {
+        CopyOnWriteArraySet c = new CopyOnWriteArraySet();
+        c.add("zfasdfsdf");
+        c.add("asdadasd");
         try {
-            CopyOnWriteArraySet c = new CopyOnWriteArraySet();
-            c.add("zfasdfsdf");
-            c.add("asdadasd");
             c.toArray(new Long[5]);
             shouldThrow();
         } catch (ArrayStoreException success) {}
diff --git a/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java b/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java
index da1ebb4..e764c9e 100644
--- a/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java
+++ b/jsr166-tests/src/test/java/jsr166/CountDownLatchTest.java
@@ -23,7 +23,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(CountDownLatchTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java b/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java
index 80d7b3b..8a38eff 100644
--- a/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java
+++ b/jsr166-tests/src/test/java/jsr166/CountedCompleterTest.java
@@ -31,7 +31,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(CountedCompleterTest.class);
     // }
 
     // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
@@ -53,7 +53,7 @@
     }
 
     private void testInvokeOnPool(ForkJoinPool pool, ForkJoinTask a) {
-        try {
+        try (PoolCleaner cleaner = cleaner(pool)) {
             assertFalse(a.isDone());
             assertFalse(a.isCompletedNormally());
             assertFalse(a.isCompletedAbnormally());
@@ -69,8 +69,6 @@
             assertFalse(a.isCancelled());
             assertNull(a.getException());
             assertNull(a.getRawResult());
-        } finally {
-            joinPool(pool);
         }
     }
 
@@ -99,17 +97,17 @@
 
         {
             Thread.currentThread().interrupt();
-            long t0 = System.nanoTime();
+            long startTime = System.nanoTime();
             assertNull(a.join());
-            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
             Thread.interrupted();
         }
 
         {
             Thread.currentThread().interrupt();
-            long t0 = System.nanoTime();
+            long startTime = System.nanoTime();
             a.quietlyJoin();        // should be no-op
-            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
             Thread.interrupted();
         }
 
@@ -142,9 +140,9 @@
         Thread.interrupted();
 
         {
-            long t0 = System.nanoTime();
+            long startTime = System.nanoTime();
             a.quietlyJoin();        // should be no-op
-            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
         }
 
         try {
@@ -180,9 +178,9 @@
         Thread.interrupted();
 
         {
-            long t0 = System.nanoTime();
+            long startTime = System.nanoTime();
             a.quietlyJoin();        // should be no-op
-            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
         }
 
         try {
@@ -284,6 +282,9 @@
     final class NoopCC extends CheckedCC {
         NoopCC() { super(); }
         NoopCC(CountedCompleter p) { super(p); }
+        NoopCC(CountedCompleter p, int initialPendingCount) {
+            super(p, initialPendingCount);
+        }
         protected void realCompute() {}
     }
 
@@ -302,6 +303,7 @@
     void testComplete(NoopCC cc, Object x, int pendingCount) {
         cc.setPendingCount(pendingCount);
         cc.checkCompletes(x);
+        assertEquals(pendingCount, cc.getPendingCount());
     }
 
     /**
@@ -315,14 +317,20 @@
     }
 
     /**
-     * completeExceptionally(null) throws NullPointerException
+     * completeExceptionally(null) surprisingly has the same effect as
+     * completeExceptionally(new RuntimeException())
      */
     public void testCompleteExceptionally_null() {
+        NoopCC a = new NoopCC();
+        a.completeExceptionally(null);
         try {
-            new NoopCC()
-                .checkCompletesExceptionally(null);
+            a.invoke();
             shouldThrow();
-        } catch (NullPointerException success) {}
+        } catch (RuntimeException success) {
+            assertSame(success.getClass(), RuntimeException.class);
+            assertNull(success.getCause());
+            a.checkCompletedExceptionally(success);
+        }
     }
 
     /**
@@ -331,10 +339,15 @@
     public void testSetPendingCount() {
         NoopCC a = new NoopCC();
         assertEquals(0, a.getPendingCount());
-        a.setPendingCount(1);
-        assertEquals(1, a.getPendingCount());
-        a.setPendingCount(27);
-        assertEquals(27, a.getPendingCount());
+        int[] vals = {
+             -1, 0, 1,
+             Integer.MIN_VALUE,
+             Integer.MAX_VALUE,
+        };
+        for (int val : vals) {
+            a.setPendingCount(val);
+            assertEquals(val, a.getPendingCount());
+        }
     }
 
     /**
@@ -347,21 +360,26 @@
         assertEquals(1, a.getPendingCount());
         a.addToPendingCount(27);
         assertEquals(28, a.getPendingCount());
+        a.addToPendingCount(-28);
+        assertEquals(0, a.getPendingCount());
     }
 
     /**
      * decrementPendingCountUnlessZero decrements reported pending
      * count unless zero
      */
-    public void testDecrementPendingCount() {
-        NoopCC a = new NoopCC();
-        assertEquals(0, a.getPendingCount());
-        a.addToPendingCount(1);
+    public void testDecrementPendingCountUnlessZero() {
+        NoopCC a = new NoopCC(null, 2);
+        assertEquals(2, a.getPendingCount());
+        assertEquals(2, a.decrementPendingCountUnlessZero());
         assertEquals(1, a.getPendingCount());
-        a.decrementPendingCountUnlessZero();
+        assertEquals(1, a.decrementPendingCountUnlessZero());
         assertEquals(0, a.getPendingCount());
-        a.decrementPendingCountUnlessZero();
+        assertEquals(0, a.decrementPendingCountUnlessZero());
         assertEquals(0, a.getPendingCount());
+        a.setPendingCount(-1);
+        assertEquals(-1, a.decrementPendingCountUnlessZero());
+        assertEquals(-2, a.getPendingCount());
     }
 
     /**
@@ -485,7 +503,7 @@
     }
 
     /**
-     * quietlyCompleteRoot completes root task
+     * quietlyCompleteRoot completes root task and only root task
      */
     public void testQuietlyCompleteRoot() {
         NoopCC a = new NoopCC();
diff --git a/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java b/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java
index a9d8c54..37adcb1 100644
--- a/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java
+++ b/jsr166-tests/src/test/java/jsr166/CyclicBarrierTest.java
@@ -27,7 +27,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(CyclicBarrierTest.class);
     // }
 
     private volatile int countAction;
diff --git a/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java b/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java
index 7619b48..e42ac2d 100644
--- a/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/DelayQueueTest.java
@@ -25,25 +25,26 @@
 
 import junit.framework.Test;
 
-// android-changed: Extend BlockingQueueTest directly.
-public class DelayQueueTest extends BlockingQueueTest {
+public class DelayQueueTest extends JSR166TestCase {
 
     // android-changed: Extend BlockingQueueTest directly instead of creating
     // an inner class and its associated suite.
     //
     // public static class Generic extends BlockingQueueTest {
-    //    protected BlockingQueue emptyCollection() {
+    //     protected BlockingQueue emptyCollection() {
     //         return new DelayQueue();
     //     }
     //     protected PDelay makeElement(int i) {
     //         return new PDelay(i);
     //     }
     // }
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
     //
     // public static void main(String[] args) {
     //     main(suite(), args);
     // }
-    //
     // public static Test suite() {
     //     return newTestSuite(DelayQueueTest.class,
     //                         new Generic().testSuite());
@@ -138,7 +139,7 @@
     private DelayQueue<PDelay> populatedQueue(int n) {
         DelayQueue<PDelay> q = new DelayQueue<PDelay>();
         assertTrue(q.isEmpty());
-        for (int i = n-1; i >= 0; i -= 2)
+        for (int i = n - 1; i >= 0; i -= 2)
             assertTrue(q.offer(new PDelay(i)));
         for (int i = (n & 1); i < n; i += 2)
             assertTrue(q.offer(new PDelay(i)));
@@ -170,8 +171,7 @@
      */
     public void testConstructor4() {
         try {
-            PDelay[] ints = new PDelay[SIZE];
-            new DelayQueue(Arrays.asList(ints));
+            new DelayQueue(Arrays.asList(new PDelay[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -180,11 +180,11 @@
      * Initializing from Collection with some null elements throws NPE
      */
     public void testConstructor5() {
+        PDelay[] a = new PDelay[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            a[i] = new PDelay(i);
         try {
-            PDelay[] ints = new PDelay[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new PDelay(i);
-            new DelayQueue(Arrays.asList(ints));
+            new DelayQueue(Arrays.asList(a));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -223,7 +223,7 @@
         BlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             assertTrue(q.remove() instanceof PDelay);
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -257,8 +257,8 @@
      * addAll(this) throws IAE
      */
     public void testAddAllSelf() {
+        DelayQueue q = populatedQueue(SIZE);
         try {
-            DelayQueue q = populatedQueue(SIZE);
             q.addAll(q);
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -269,12 +269,12 @@
      * possibly adding some elements
      */
     public void testAddAll3() {
+        DelayQueue q = new DelayQueue();
+        PDelay[] a = new PDelay[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            a[i] = new PDelay(i);
         try {
-            DelayQueue q = new DelayQueue();
-            PDelay[] ints = new PDelay[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new PDelay(i);
-            q.addAll(Arrays.asList(ints));
+            q.addAll(Arrays.asList(a));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -285,7 +285,7 @@
     public void testAddAll5() {
         PDelay[] empty = new PDelay[0];
         PDelay[] ints = new PDelay[SIZE];
-        for (int i = SIZE-1; i >= 0; --i)
+        for (int i = SIZE - 1; i >= 0; --i)
             ints[i] = new PDelay(i);
         DelayQueue q = new DelayQueue();
         assertFalse(q.addAll(Arrays.asList(empty)));
@@ -427,11 +427,13 @@
      */
     public void testInterruptedTimedPoll() throws InterruptedException {
         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        final DelayQueue q = populatedQueue(SIZE);
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                DelayQueue q = populatedQueue(SIZE);
+                long startTime = System.nanoTime();
                 for (int i = 0; i < SIZE; ++i) {
-                    assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, MILLISECONDS)));
+                    assertEquals(new PDelay(i),
+                                 ((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS)));
                 }
 
                 Thread.currentThread().interrupt();
@@ -447,12 +449,14 @@
                     shouldThrow();
                 } catch (InterruptedException success) {}
                 assertFalse(Thread.interrupted());
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
         await(pleaseInterrupt);
         assertThreadStaysAlive(t);
         t.interrupt();
         awaitTermination(t);
+        checkEmpty(q);
     }
 
     /**
@@ -557,7 +561,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.remove();
         }
     }
@@ -570,7 +574,7 @@
             DelayQueue q = populatedQueue(SIZE);
             DelayQueue p = populatedQueue(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 PDelay x = (PDelay)(p.remove());
                 assertFalse(q.contains(x));
@@ -668,22 +672,22 @@
     public void testPollInExecutor() {
         final DelayQueue q = new DelayQueue();
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertNull(q.poll());
-                threadsStarted.await();
-                assertNotNull(q.poll(LONG_DELAY_MS, MILLISECONDS));
-                checkEmpty(q);
-            }});
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertNotNull(q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                q.put(new PDelay(1));
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(new PDelay(1));
+                }});
+        }
     }
 
     /**
@@ -768,7 +772,7 @@
         final DelayQueue q = populatedQueue(SIZE);
         Thread t = new Thread(new CheckedRunnable() {
             public void realRun() {
-                q.put(new PDelay(SIZE+1));
+                q.put(new PDelay(SIZE + 1));
             }});
 
         t.start();
@@ -788,7 +792,7 @@
             ArrayList l = new ArrayList();
             q.drainTo(l, i);
             int k = (i < SIZE) ? i : SIZE;
-            assertEquals(SIZE-k, q.size());
+            assertEquals(SIZE - k, q.size());
             assertEquals(k, l.size());
         }
     }
diff --git a/jsr166-tests/src/test/java/jsr166/DoubleAccumulatorTest.java b/jsr166-tests/src/test/java/jsr166/DoubleAccumulatorTest.java
new file mode 100644
index 0000000..e061f9a
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/DoubleAccumulatorTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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 jsr166;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.atomic.DoubleAccumulator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class DoubleAccumulatorTest extends JSR166TestCase {
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(DoubleAccumulatorTest.class);
+    // }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0.0, ai.get());
+    }
+
+    /**
+     * accumulate accumulates given value to current, and get returns current value
+     */
+    public void testAccumulateAndGet() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        ai.accumulate(2.0);
+        assertEquals(2.0, ai.get());
+        ai.accumulate(-4.0);
+        assertEquals(2.0, ai.get());
+        ai.accumulate(4.0);
+        assertEquals(4.0, ai.get());
+    }
+
+    /**
+     * reset() causes subsequent get() to return zero
+     */
+    public void testReset() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        ai.accumulate(2.0);
+        assertEquals(2.0, ai.get());
+        ai.reset();
+        assertEquals(0.0, ai.get());
+    }
+
+    /**
+     * getThenReset() returns current value; subsequent get() returns zero
+     */
+    public void testGetThenReset() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        ai.accumulate(2.0);
+        assertEquals(2.0, ai.get());
+        assertEquals(2.0, ai.getThenReset());
+        assertEquals(0.0, ai.get());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals("0.0", ai.toString());
+        ai.accumulate(1.0);
+        assertEquals(Double.toString(1.0), ai.toString());
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0, ai.intValue());
+        ai.accumulate(1.0);
+        assertEquals(1, ai.intValue());
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0, ai.longValue());
+        ai.accumulate(1.0);
+        assertEquals(1, ai.longValue());
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0.0f, ai.floatValue());
+        ai.accumulate(1.0);
+        assertEquals(1.0f, ai.floatValue());
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0.0, ai.doubleValue());
+        ai.accumulate(1.0);
+        assertEquals(1.0, ai.doubleValue());
+    }
+
+    /**
+     * accumulates by multiple threads produce correct result
+     */
+    public void testAccumulateAndGetMT() {
+        final int incs = 1000000;
+        final int nthreads = 4;
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        DoubleAccumulator a = new DoubleAccumulator(Double::max, 0.0);
+        Phaser phaser = new Phaser(nthreads + 1);
+        for (int i = 0; i < nthreads; ++i)
+            pool.execute(new AccTask(a, phaser, incs));
+        phaser.arriveAndAwaitAdvance();
+        phaser.arriveAndAwaitAdvance();
+        double expected = incs - 1;
+        double result = a.get();
+        assertEquals(expected, result);
+        pool.shutdown();
+    }
+
+    static final class AccTask implements Runnable {
+        final DoubleAccumulator acc;
+        final Phaser phaser;
+        final int incs;
+        volatile double result;
+        AccTask(DoubleAccumulator acc, Phaser phaser, int incs) {
+            this.acc = acc;
+            this.phaser = phaser;
+            this.incs = incs;
+        }
+
+        public void run() {
+            phaser.arriveAndAwaitAdvance();
+            DoubleAccumulator a = acc;
+            for (int i = 0; i < incs; ++i)
+                a.accumulate(i);
+            result = a.get();
+            phaser.arrive();
+        }
+    }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/DoubleAdderTest.java b/jsr166-tests/src/test/java/jsr166/DoubleAdderTest.java
new file mode 100644
index 0000000..d02e2a1
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/DoubleAdderTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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 jsr166;
+
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.DoubleAdder;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class DoubleAdderTest extends JSR166TestCase {
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(DoubleAdderTest.class);
+    // }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0.0, ai.sum());
+    }
+
+    /**
+     * add adds given value to current, and sum returns current value
+     */
+    public void testAddAndSum() {
+        DoubleAdder ai = new DoubleAdder();
+        ai.add(2.0);
+        assertEquals(2.0, ai.sum());
+        ai.add(-4.0);
+        assertEquals(-2.0, ai.sum());
+    }
+
+    /**
+     * reset() causes subsequent sum() to return zero
+     */
+    public void testReset() {
+        DoubleAdder ai = new DoubleAdder();
+        ai.add(2.0);
+        assertEquals(2.0, ai.sum());
+        ai.reset();
+        assertEquals(0.0, ai.sum());
+    }
+
+    /**
+     * sumThenReset() returns sum; subsequent sum() returns zero
+     */
+    public void testSumThenReset() {
+        DoubleAdder ai = new DoubleAdder();
+        ai.add(2.0);
+        assertEquals(2.0, ai.sum());
+        assertEquals(2.0, ai.sumThenReset());
+        assertEquals(0.0, ai.sum());
+    }
+
+    /**
+     * a deserialized serialized adder holds same value
+     */
+    public void testSerialization() throws Exception {
+        DoubleAdder x = new DoubleAdder();
+        DoubleAdder y = serialClone(x);
+        assertNotSame(x, y);
+        x.add(-22.0);
+        DoubleAdder z = serialClone(x);
+        assertEquals(-22.0, x.sum());
+        assertEquals(0.0, y.sum());
+        assertEquals(-22.0, z.sum());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(Double.toString(0.0), ai.toString());
+        ai.add(1.0);
+        assertEquals(Double.toString(1.0), ai.toString());
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0, ai.intValue());
+        ai.add(1.0);
+        assertEquals(1, ai.intValue());
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0, ai.longValue());
+        ai.add(1.0);
+        assertEquals(1, ai.longValue());
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0.0f, ai.floatValue());
+        ai.add(1.0);
+        assertEquals(1.0f, ai.floatValue());
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0.0, ai.doubleValue());
+        ai.add(1.0);
+        assertEquals(1.0, ai.doubleValue());
+    }
+
+    /**
+     * adds by multiple threads produce correct sum
+     */
+    public void testAddAndSumMT() throws Throwable {
+        final int incs = 1000000;
+        final int nthreads = 4;
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        DoubleAdder a = new DoubleAdder();
+        CyclicBarrier barrier = new CyclicBarrier(nthreads + 1);
+        for (int i = 0; i < nthreads; ++i)
+            pool.execute(new AdderTask(a, barrier, incs));
+        barrier.await();
+        barrier.await();
+        double total = (long)nthreads * incs;
+        double sum = a.sum();
+        assertEquals(sum, total);
+        pool.shutdown();
+    }
+
+    static final class AdderTask implements Runnable {
+        final DoubleAdder adder;
+        final CyclicBarrier barrier;
+        final int incs;
+        volatile double result;
+        AdderTask(DoubleAdder adder, CyclicBarrier barrier, int incs) {
+            this.adder = adder;
+            this.barrier = barrier;
+            this.incs = incs;
+        }
+
+        public void run() {
+            try {
+                barrier.await();
+                DoubleAdder a = adder;
+                for (int i = 0; i < incs; ++i)
+                    a.add(1.0);
+                result = a.sum();
+                barrier.await();
+            } catch (Throwable t) { throw new Error(t); }
+        }
+    }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/EntryTest.java b/jsr166-tests/src/test/java/jsr166/EntryTest.java
index d141a84..72740e3 100644
--- a/jsr166-tests/src/test/java/jsr166/EntryTest.java
+++ b/jsr166-tests/src/test/java/jsr166/EntryTest.java
@@ -20,7 +20,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(EntryTest.class);
     // }
 
     static final String k1 = "1";
diff --git a/jsr166-tests/src/test/java/jsr166/ExchangerTest.java b/jsr166-tests/src/test/java/jsr166/ExchangerTest.java
index 172fccd..b111980 100644
--- a/jsr166-tests/src/test/java/jsr166/ExchangerTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ExchangerTest.java
@@ -26,7 +26,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ExchangerTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java b/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java
index e988cc6..0f58e78 100644
--- a/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ExecutorCompletionServiceTest.java
@@ -33,7 +33,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ExecutorCompletionServiceTest.class);
     // }
 
     /**
@@ -61,15 +61,14 @@
      * Submitting a null callable throws NPE
      */
     public void testSubmitNPE() {
-        ExecutorService e = Executors.newCachedThreadPool();
-        ExecutorCompletionService ecs = new ExecutorCompletionService(e);
-        try {
+        final ExecutorService e = Executors.newCachedThreadPool();
+        final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Callable c = null;
-            ecs.submit(c);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+            try {
+                ecs.submit(c);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -77,15 +76,14 @@
      * Submitting a null runnable throws NPE
      */
     public void testSubmitNPE2() {
-        ExecutorService e = Executors.newCachedThreadPool();
-        ExecutorCompletionService ecs = new ExecutorCompletionService(e);
-        try {
+        final ExecutorService e = Executors.newCachedThreadPool();
+        final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Runnable r = null;
-            ecs.submit(r, Boolean.TRUE);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+            try {
+                ecs.submit(r, Boolean.TRUE);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -93,15 +91,13 @@
      * A taken submitted task is completed
      */
     public void testTake() throws InterruptedException {
-        ExecutorService e = Executors.newCachedThreadPool();
-        ExecutorCompletionService ecs = new ExecutorCompletionService(e);
-        try {
+        final ExecutorService e = Executors.newCachedThreadPool();
+        final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Callable c = new StringTask();
             ecs.submit(c);
             Future f = ecs.take();
             assertTrue(f.isDone());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -109,15 +105,13 @@
      * Take returns the same future object returned by submit
      */
     public void testTake2() throws InterruptedException {
-        ExecutorService e = Executors.newCachedThreadPool();
-        ExecutorCompletionService ecs = new ExecutorCompletionService(e);
-        try {
+        final ExecutorService e = Executors.newCachedThreadPool();
+        final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Callable c = new StringTask();
             Future f1 = ecs.submit(c);
             Future f2 = ecs.take();
             assertSame(f1, f2);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -125,9 +119,9 @@
      * If poll returns non-null, the returned task is completed
      */
     public void testPoll1() throws Exception {
-        ExecutorService e = Executors.newCachedThreadPool();
-        ExecutorCompletionService ecs = new ExecutorCompletionService(e);
-        try {
+        final ExecutorService e = Executors.newCachedThreadPool();
+        final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
             assertNull(ecs.poll());
             Callable c = new StringTask();
             ecs.submit(c);
@@ -141,8 +135,6 @@
             }
             assertTrue(f.isDone());
             assertSame(TEST_STRING, f.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -150,17 +142,15 @@
      * If timed poll returns non-null, the returned task is completed
      */
     public void testPoll2() throws InterruptedException {
-        ExecutorService e = Executors.newCachedThreadPool();
-        ExecutorCompletionService ecs = new ExecutorCompletionService(e);
-        try {
+        final ExecutorService e = Executors.newCachedThreadPool();
+        final ExecutorCompletionService ecs = new ExecutorCompletionService(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
             assertNull(ecs.poll());
             Callable c = new StringTask();
             ecs.submit(c);
             Future f = ecs.poll(SHORT_DELAY_MS, MILLISECONDS);
             if (f != null)
                 assertTrue(f.isDone());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -174,15 +164,16 @@
             MyCallableFuture(Callable<V> c) { super(c); }
             protected void done() { done.set(true); }
         }
-        ExecutorService e = new ThreadPoolExecutor(
-                                 1, 1, 30L, TimeUnit.SECONDS,
-                                 new ArrayBlockingQueue<Runnable>(1)) {
-            protected <T> RunnableFuture<T> newTaskFor(Callable<T> c) {
-                return new MyCallableFuture<T>(c);
-            }};
+        final ExecutorService e =
+            new ThreadPoolExecutor(1, 1,
+                                   30L, TimeUnit.SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1)) {
+                protected <T> RunnableFuture<T> newTaskFor(Callable<T> c) {
+                    return new MyCallableFuture<T>(c);
+                }};
         ExecutorCompletionService<String> ecs =
             new ExecutorCompletionService<String>(e);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             assertNull(ecs.poll());
             Callable<String> c = new StringTask();
             Future f1 = ecs.submit(c);
@@ -191,8 +182,6 @@
             Future f2 = ecs.take();
             assertSame("submit and take must return same objects", f1, f2);
             assertTrue("completed task must have set done", done.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -206,15 +195,16 @@
             MyRunnableFuture(Runnable t, V r) { super(t, r); }
             protected void done() { done.set(true); }
         }
-        ExecutorService e = new ThreadPoolExecutor(
-                                 1, 1, 30L, TimeUnit.SECONDS,
-                                 new ArrayBlockingQueue<Runnable>(1)) {
-            protected <T> RunnableFuture<T> newTaskFor(Runnable t, T r) {
-                return new MyRunnableFuture<T>(t, r);
-            }};
-        ExecutorCompletionService<String> ecs =
+        final ExecutorService e =
+            new ThreadPoolExecutor(1, 1,
+                                   30L, TimeUnit.SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1)) {
+                protected <T> RunnableFuture<T> newTaskFor(Runnable t, T r) {
+                    return new MyRunnableFuture<T>(t, r);
+                }};
+        final ExecutorCompletionService<String> ecs =
             new ExecutorCompletionService<String>(e);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             assertNull(ecs.poll());
             Runnable r = new NoOpRunnable();
             Future f1 = ecs.submit(r, null);
@@ -223,8 +213,6 @@
             Future f2 = ecs.take();
             assertSame("submit and take must return same objects", f1, f2);
             assertTrue("completed task must have set done", done.get());
-        } finally {
-            joinPool(e);
         }
     }
 
diff --git a/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java b/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java
index ae475f1..d70ae6e 100644
--- a/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ExecutorsTest.java
@@ -36,29 +36,31 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ExecutorsTest.class);
     // }
 
     /**
      * A newCachedThreadPool can execute runnables
      */
     public void testNewCachedThreadPool1() {
-        ExecutorService e = Executors.newCachedThreadPool();
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        joinPool(e);
+        final ExecutorService e = Executors.newCachedThreadPool();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
     }
 
     /**
      * A newCachedThreadPool with given ThreadFactory can execute runnables
      */
     public void testNewCachedThreadPool2() {
-        ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        joinPool(e);
+        final ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory());
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
     }
 
     /**
@@ -75,22 +77,24 @@
      * A new SingleThreadExecutor can execute runnables
      */
     public void testNewSingleThreadExecutor1() {
-        ExecutorService e = Executors.newSingleThreadExecutor();
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        joinPool(e);
+        final ExecutorService e = Executors.newSingleThreadExecutor();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
     }
 
     /**
      * A new SingleThreadExecutor with given ThreadFactory can execute runnables
      */
     public void testNewSingleThreadExecutor2() {
-        ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        joinPool(e);
+        final ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory());
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
     }
 
     /**
@@ -107,13 +111,12 @@
      * A new SingleThreadExecutor cannot be casted to concrete implementation
      */
     public void testCastNewSingleThreadExecutor() {
-        ExecutorService e = Executors.newSingleThreadExecutor();
-        try {
-            ThreadPoolExecutor tpe = (ThreadPoolExecutor)e;
-            shouldThrow();
-        } catch (ClassCastException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = Executors.newSingleThreadExecutor();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                ThreadPoolExecutor tpe = (ThreadPoolExecutor)e;
+                shouldThrow();
+            } catch (ClassCastException success) {}
         }
     }
 
@@ -121,22 +124,24 @@
      * A new newFixedThreadPool can execute runnables
      */
     public void testNewFixedThreadPool1() {
-        ExecutorService e = Executors.newFixedThreadPool(2);
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        joinPool(e);
+        final ExecutorService e = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
     }
 
     /**
      * A new newFixedThreadPool with given ThreadFactory can execute runnables
      */
     public void testNewFixedThreadPool2() {
-        ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        joinPool(e);
+        final ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory());
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
     }
 
     /**
@@ -163,11 +168,12 @@
      * An unconfigurable newFixedThreadPool can execute runnables
      */
     public void testUnconfigurableExecutorService() {
-        ExecutorService e = Executors.unconfigurableExecutorService(Executors.newFixedThreadPool(2));
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        e.execute(new NoOpRunnable());
-        joinPool(e);
+        final ExecutorService e = Executors.unconfigurableExecutorService(Executors.newFixedThreadPool(2));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
     }
 
     /**
@@ -194,8 +200,8 @@
      * a newSingleThreadScheduledExecutor successfully runs delayed task
      */
     public void testNewSingleThreadScheduledExecutor() throws Exception {
-        ScheduledExecutorService p = Executors.newSingleThreadScheduledExecutor();
-        try {
+        final ScheduledExecutorService p = Executors.newSingleThreadScheduledExecutor();
+        try (PoolCleaner cleaner = cleaner(p)) {
             final CountDownLatch proceed = new CountDownLatch(1);
             final Runnable task = new CheckedRunnable() {
                 public void realRun() {
@@ -211,8 +217,6 @@
             assertTrue(f.isDone());
             assertFalse(f.isCancelled());
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -220,8 +224,8 @@
      * a newScheduledThreadPool successfully runs delayed task
      */
     public void testNewScheduledThreadPool() throws Exception {
-        ScheduledExecutorService p = Executors.newScheduledThreadPool(2);
-        try {
+        final ScheduledExecutorService p = Executors.newScheduledThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(p)) {
             final CountDownLatch proceed = new CountDownLatch(1);
             final Runnable task = new CheckedRunnable() {
                 public void realRun() {
@@ -237,8 +241,6 @@
             assertTrue(f.isDone());
             assertFalse(f.isCancelled());
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -246,10 +248,10 @@
      * an unconfigurable newScheduledThreadPool successfully runs delayed task
      */
     public void testUnconfigurableScheduledExecutorService() throws Exception {
-        ScheduledExecutorService p =
+        final ScheduledExecutorService p =
             Executors.unconfigurableScheduledExecutorService
             (Executors.newScheduledThreadPool(2));
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             final CountDownLatch proceed = new CountDownLatch(1);
             final Runnable task = new CheckedRunnable() {
                 public void realRun() {
@@ -265,8 +267,6 @@
             assertTrue(f.isDone());
             assertFalse(f.isCancelled());
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -327,16 +327,10 @@
                 done.countDown();
             }};
         ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
-
-        e.execute(r);
-        await(done);
-
-        try {
-            e.shutdown();
-        } catch (SecurityException ok) {
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(r);
+            await(done);
         }
-
-        joinPool(e);
     }
 
     /**
@@ -366,14 +360,14 @@
                         String name = current.getName();
                         assertTrue(name.endsWith("thread-1"));
                         assertSame(thisccl, current.getContextClassLoader());
-                        // assertEquals(thisacc, AccessController.getContext());
+                        //assertEquals(thisacc, AccessController.getContext());
                         done.countDown();
                     }};
                 ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
-                e.execute(r);
-                await(done);
-                e.shutdown();
-                joinPool(e);
+                try (PoolCleaner cleaner = cleaner(e)) {
+                    e.execute(r);
+                    await(done);
+                }
             }};
 
         runWithPermissions(r,
diff --git a/jsr166-tests/src/test/java/jsr166/ForkJoinPool8Test.java b/jsr166-tests/src/test/java/jsr166/ForkJoinPool8Test.java
new file mode 100644
index 0000000..f9f9239
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ForkJoinPool8Test.java
@@ -0,0 +1,1592 @@
+/*
+ * 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 jsr166;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.HashSet;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ForkJoinPool8Test extends JSR166TestCase {
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(ForkJoinPool8Test.class);
+    // }
+
+    /**
+     * Common pool exists and has expected parallelism.
+     */
+    public void testCommonPoolParallelism() {
+        assertEquals(ForkJoinPool.getCommonPoolParallelism(),
+                     ForkJoinPool.commonPool().getParallelism());
+    }
+
+    /**
+     * Common pool cannot be shut down
+     */
+    public void testCommonPoolShutDown() {
+        assertFalse(ForkJoinPool.commonPool().isShutdown());
+        assertFalse(ForkJoinPool.commonPool().isTerminating());
+        assertFalse(ForkJoinPool.commonPool().isTerminated());
+        ForkJoinPool.commonPool().shutdown();
+        assertFalse(ForkJoinPool.commonPool().isShutdown());
+        assertFalse(ForkJoinPool.commonPool().isTerminating());
+        assertFalse(ForkJoinPool.commonPool().isTerminated());
+        ForkJoinPool.commonPool().shutdownNow();
+        assertFalse(ForkJoinPool.commonPool().isShutdown());
+        assertFalse(ForkJoinPool.commonPool().isTerminating());
+        assertFalse(ForkJoinPool.commonPool().isTerminated());
+    }
+
+    /*
+     * All of the following test methods are adaptations of those for
+     * RecursiveAction and CountedCompleter, but with all actions
+     * executed in the common pool, generally implicitly via
+     * checkInvoke.
+     */
+
+    private void checkInvoke(ForkJoinTask a) {
+        checkNotDone(a);
+        assertNull(a.invoke());
+        checkCompletedNormally(a);
+    }
+
+    void checkNotDone(ForkJoinTask a) {
+        assertFalse(a.isDone());
+        assertFalse(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertFalse(a.isCancelled());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+
+        if (! ForkJoinTask.inForkJoinPool()) {
+            Thread.currentThread().interrupt();
+            try {
+                a.get();
+                shouldThrow();
+            } catch (InterruptedException success) {
+            } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+            Thread.currentThread().interrupt();
+            try {
+                a.get(5L, SECONDS);
+                shouldThrow();
+            } catch (InterruptedException success) {
+            } catch (Throwable fail) { threadUnexpectedException(fail); }
+        }
+
+        try {
+            a.get(0L, SECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedNormally(ForkJoinTask a) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertTrue(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+        assertNull(a.join());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        try {
+            assertNull(a.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertNull(a.get(5L, SECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCancelled(ForkJoinTask a) {
+        assertTrue(a.isDone());
+        assertTrue(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertTrue(a.getException() instanceof CancellationException);
+        assertNull(a.getRawResult());
+
+        try {
+            a.join();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertSame(t.getClass(), a.getException().getClass());
+        assertNull(a.getRawResult());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+
+        try {
+            a.join();
+            shouldThrow();
+        } catch (Throwable expected) {
+            assertSame(expected.getClass(), t.getClass());
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    public static final class FJException extends RuntimeException {
+        public FJException() { super(); }
+        public FJException(Throwable cause) { super(cause); }
+    }
+
+    // A simple recursive action for testing
+    final class FibAction extends CheckedRecursiveAction {
+        final int number;
+        int result;
+        FibAction(int n) { number = n; }
+        protected void realCompute() {
+            int n = number;
+            if (n <= 1)
+                result = n;
+            else {
+                FibAction f1 = new FibAction(n - 1);
+                FibAction f2 = new FibAction(n - 2);
+                invokeAll(f1, f2);
+                result = f1.result + f2.result;
+            }
+        }
+    }
+
+    // A recursive action failing in base case
+    static final class FailingFibAction extends RecursiveAction {
+        final int number;
+        int result;
+        FailingFibAction(int n) { number = n; }
+        public void compute() {
+            int n = number;
+            if (n <= 1)
+                throw new FJException();
+            else {
+                FailingFibAction f1 = new FailingFibAction(n - 1);
+                FailingFibAction f2 = new FailingFibAction(n - 2);
+                invokeAll(f1, f2);
+                result = f1.result + f2.result;
+            }
+        }
+    }
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks. getRawResult of a RecursiveAction returns null;
+     */
+    public void testInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertNull(f.invoke());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                f.quietlyInvoke();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join/quietlyJoin of a forked task succeeds in the presence of interrupts
+     */
+    public void testJoinIgnoresInterrupts() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                final Thread myself = Thread.currentThread();
+
+                // test join()
+                assertSame(f, f.fork());
+                myself.interrupt();
+                assertTrue(myself.isInterrupted());
+                assertNull(f.join());
+                Thread.interrupted();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+
+                f = new FibAction(8);
+                f.cancel(true);
+                assertSame(f, f.fork());
+                myself.interrupt();
+                assertTrue(myself.isInterrupted());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    Thread.interrupted();
+                    checkCancelled(f);
+                }
+
+                f = new FibAction(8);
+                f.completeExceptionally(new FJException());
+                assertSame(f, f.fork());
+                myself.interrupt();
+                assertTrue(myself.isInterrupted());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    Thread.interrupted();
+                    checkCompletedAbnormally(f, success);
+                }
+
+                // test quietlyJoin()
+                f = new FibAction(8);
+                assertSame(f, f.fork());
+                myself.interrupt();
+                assertTrue(myself.isInterrupted());
+                f.quietlyJoin();
+                Thread.interrupted();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+
+                f = new FibAction(8);
+                f.cancel(true);
+                assertSame(f, f.fork());
+                myself.interrupt();
+                assertTrue(myself.isInterrupted());
+                f.quietlyJoin();
+                Thread.interrupted();
+                checkCancelled(f);
+
+                f = new FibAction(8);
+                f.completeExceptionally(new FJException());
+                assertSame(f, f.fork());
+                myself.interrupt();
+                assertTrue(myself.isInterrupted());
+                f.quietlyJoin();
+                Thread.interrupted();
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+        a.reinitialize();
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertNull(f.get(5L, SECONDS));
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get with null time unit throws NPE
+     */
+    public void testForkTimedGetNPE() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, SECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, SECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertFalse(inForkJoinPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * A reinitialized normally completed task may be re-invoked
+     */
+    public void testReinitialize() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                checkNotDone(f);
+
+                for (int i = 0; i < 3; i++) {
+                    assertNull(f.invoke());
+                    assertEquals(21, f.result);
+                    checkCompletedNormally(f);
+                    f.reinitialize();
+                    checkNotDone(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * A reinitialized abnormally completed task may be re-invoked
+     */
+    public void testReinitializeAbnormal() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                checkNotDone(f);
+
+                for (int i = 0; i < 3; i++) {
+                    try {
+                        f.invoke();
+                        shouldThrow();
+                    } catch (FJException success) {
+                        checkCompletedAbnormally(f, success);
+                    }
+                    f.reinitialize();
+                    checkNotDone(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                f.completeExceptionally(new FJException());
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task suppresses execution invoking complete
+     */
+    public void testComplete() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                f.complete(null);
+                assertNull(f.invoke());
+                assertEquals(0, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                invokeAll(f, g);
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+                checkCompletedNormally(g);
+                assertEquals(34, g.result);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                invokeAll(f);
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = new FibAction(7);
+                invokeAll(f, g, h);
+                assertTrue(f.isDone());
+                assertTrue(g.isDone());
+                assertTrue(h.isDone());
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+                checkCompletedNormally(g);
+                assertEquals(34, g.result);
+                checkCompletedNormally(g);
+                assertEquals(13, h.result);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollection() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = new FibAction(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertTrue(f.isDone());
+                assertTrue(g.isDone());
+                assertTrue(h.isDone());
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+                checkCompletedNormally(g);
+                assertEquals(34, g.result);
+                checkCompletedNormally(g);
+                assertEquals(13, h.result);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPE() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FailingFibAction g = new FailingFibAction(9);
+                try {
+                    invokeAll(f, g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction g = new FailingFibAction(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FailingFibAction g = new FailingFibAction(9);
+                FibAction h = new FibAction(7);
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollection() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = new FibAction(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                try {
+                    invokeAll(set);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    // CountedCompleter versions
+
+    abstract static class CCF extends CountedCompleter {
+        int number;
+        int rnumber;
+
+        public CCF(CountedCompleter parent, int n) {
+            super(parent, 1);
+            this.number = n;
+        }
+
+        public final void compute() {
+            CountedCompleter p;
+            CCF f = this;
+            int n = number;
+            while (n >= 2) {
+                new RCCF(f, n - 2).fork();
+                f = new LCCF(f, --n);
+            }
+            f.number = n;
+            f.onCompletion(f);
+            if ((p = f.getCompleter()) != null)
+                p.tryComplete();
+            else
+                f.quietlyComplete();
+        }
+    }
+
+    static final class LCCF extends CCF {
+        public LCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            CCF p = (CCF)getCompleter();
+            int n = number + rnumber;
+            if (p != null)
+                p.number = n;
+            else
+                number = n;
+        }
+    }
+    static final class RCCF extends CCF {
+        public RCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            CCF p = (CCF)getCompleter();
+            int n = number + rnumber;
+            if (p != null)
+                p.rnumber = n;
+            else
+                number = n;
+        }
+    }
+
+    // Version of CCF with forced failure in left completions
+    abstract static class FailingCCF extends CountedCompleter {
+        int number;
+        int rnumber;
+
+        public FailingCCF(CountedCompleter parent, int n) {
+            super(parent, 1);
+            this.number = n;
+        }
+
+        public final void compute() {
+            CountedCompleter p;
+            FailingCCF f = this;
+            int n = number;
+            while (n >= 2) {
+                new RFCCF(f, n - 2).fork();
+                f = new LFCCF(f, --n);
+            }
+            f.number = n;
+            f.onCompletion(f);
+            if ((p = f.getCompleter()) != null)
+                p.tryComplete();
+            else
+                f.quietlyComplete();
+        }
+    }
+
+    static final class LFCCF extends FailingCCF {
+        public LFCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            FailingCCF p = (FailingCCF)getCompleter();
+            int n = number + rnumber;
+            if (p != null)
+                p.number = n;
+            else
+                number = n;
+        }
+    }
+    static final class RFCCF extends FailingCCF {
+        public RFCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            completeExceptionally(new FJException());
+        }
+    }
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks; getRawResult returns null.
+     */
+    public void testInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertNull(f.invoke());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                f.quietlyInvoke();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get with null time unit throws NPE
+     */
+    public void testForkTimedGetNPECC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingCCF f = new LFCCF(null, 8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingCCF f = new LFCCF(null, 8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGetCC() throws Exception {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * getPool of non-FJ task returns null
+     */
+    public void testGetPool2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertNull(getPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertFalse(inForkJoinPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * setRawResult(null) succeeds
+     */
+    public void testSetRawResultCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                setRawResult(null);
+                assertNull(getRawResult());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                f.completeExceptionally(new FJException());
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                invokeAll(f, g);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                invokeAll(f);
+                checkCompletedNormally(f);
+                assertEquals(21, f.number);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                CCF h = new LCCF(null, 7);
+                invokeAll(f, g, h);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollectionCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                CCF h = new LCCF(null, 7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPECC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                CCF h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                FailingCCF g = new LFCCF(null, 9);
+                try {
+                    invokeAll(f, g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF g = new LFCCF(null, 9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                FailingCCF g = new LFCCF(null, 9);
+                CCF h = new LCCF(null, 7);
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollectionCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                CCF h = new LCCF(null, 7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                try {
+                    invokeAll(set);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * awaitQuiescence by a worker is equivalent in effect to
+     * ForkJoinTask.helpQuiesce()
+     */
+    public void testAwaitQuiescence1() throws Exception {
+        final ForkJoinPool p = new ForkJoinPool();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            assertTrue(p.isQuiescent());
+            ForkJoinTask a = new CheckedRecursiveAction() {
+                protected void realCompute() {
+                    FibAction f = new FibAction(8);
+                    assertSame(f, f.fork());
+                    assertSame(p, ForkJoinTask.getPool());
+                    boolean quiescent = p.awaitQuiescence(LONG_DELAY_MS, MILLISECONDS);
+                    assertTrue(quiescent);
+                    assertFalse(p.isQuiescent());
+                    while (!f.isDone()) {
+                        assertFalse(p.getAsyncMode());
+                        assertFalse(p.isShutdown());
+                        assertFalse(p.isTerminating());
+                        assertFalse(p.isTerminated());
+                        Thread.yield();
+                    }
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                    assertFalse(p.isQuiescent());
+                    assertEquals(0, ForkJoinTask.getQueuedTaskCount());
+                    assertEquals(21, f.result);
+                }};
+            p.execute(a);
+            while (!a.isDone() || !p.isQuiescent()) {
+                assertFalse(p.getAsyncMode());
+                assertFalse(p.isShutdown());
+                assertFalse(p.isTerminating());
+                assertFalse(p.isTerminated());
+                Thread.yield();
+            }
+            assertEquals(0, p.getQueuedTaskCount());
+            assertFalse(p.getAsyncMode());
+            assertEquals(0, p.getQueuedSubmissionCount());
+            assertFalse(p.hasQueuedSubmissions());
+            while (p.getActiveThreadCount() != 0
+                   && millisElapsedSince(startTime) < LONG_DELAY_MS)
+                Thread.yield();
+            assertFalse(p.isShutdown());
+            assertFalse(p.isTerminating());
+            assertFalse(p.isTerminated());
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * awaitQuiescence returns when pool isQuiescent() or the indicated
+     * timeout elapsed
+     */
+    public void testAwaitQuiescence2() throws Exception {
+        /**
+         * """It is possible to disable or limit the use of threads in the
+         * common pool by setting the parallelism property to zero. However
+         * doing so may cause unjoined tasks to never be executed."""
+         */
+        if ("0".equals(System.getProperty(
+             "java.util.concurrent.ForkJoinPool.common.parallelism")))
+            return;
+        final ForkJoinPool p = new ForkJoinPool();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertTrue(p.isQuiescent());
+            final long startTime = System.nanoTime();
+            ForkJoinTask a = new CheckedRecursiveAction() {
+                protected void realCompute() {
+                    FibAction f = new FibAction(8);
+                    assertSame(f, f.fork());
+                    while (!f.isDone()
+                           && millisElapsedSince(startTime) < LONG_DELAY_MS) {
+                        assertFalse(p.getAsyncMode());
+                        assertFalse(p.isShutdown());
+                        assertFalse(p.isTerminating());
+                        assertFalse(p.isTerminated());
+                        Thread.yield();
+                    }
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                    assertEquals(0, ForkJoinTask.getQueuedTaskCount());
+                    assertEquals(21, f.result);
+                }};
+            p.execute(a);
+            assertTrue(p.awaitQuiescence(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isQuiescent());
+            assertTrue(a.isDone());
+            assertEquals(0, p.getQueuedTaskCount());
+            assertFalse(p.getAsyncMode());
+            assertEquals(0, p.getQueuedSubmissionCount());
+            assertFalse(p.hasQueuedSubmissions());
+            while (p.getActiveThreadCount() != 0
+                   && millisElapsedSince(startTime) < LONG_DELAY_MS)
+                Thread.yield();
+            assertFalse(p.isShutdown());
+            assertFalse(p.isTerminating());
+            assertFalse(p.isTerminated());
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java b/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java
index 09a3511..e3bb428 100644
--- a/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ForkJoinPoolTest.java
@@ -40,7 +40,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ForkJoinPoolTest.class);
     // }
 
     /*
@@ -68,10 +68,12 @@
         }
     }
 
+    static class MyError extends Error {}
+
     // to test handlers
     static class FailingFJWSubclass extends ForkJoinWorkerThread {
         public FailingFJWSubclass(ForkJoinPool p) { super(p) ; }
-        protected void onStart() { super.onStart(); throw new Error(); }
+        protected void onStart() { super.onStart(); throw new MyError(); }
     }
 
     static class FailingThreadFactory
@@ -166,7 +168,7 @@
      */
     public void testDefaultInitialState() {
         ForkJoinPool p = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
                        p.getFactory());
             assertFalse(p.getAsyncMode());
@@ -178,8 +180,6 @@
             assertFalse(p.isShutdown());
             assertFalse(p.isTerminating());
             assertFalse(p.isTerminated());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -208,10 +208,8 @@
      */
     public void testGetParallelism() {
         ForkJoinPool p = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             assertEquals(1, p.getParallelism());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -219,14 +217,26 @@
      * getPoolSize returns number of started workers.
      */
     public void testGetPoolSize() {
-        ForkJoinPool p = new ForkJoinPool(1);
-        try {
+        final CountDownLatch taskStarted = new CountDownLatch(1);
+        final CountDownLatch done = new CountDownLatch(1);
+        final ForkJoinPool p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
             assertEquals(0, p.getActiveThreadCount());
-            Future<String> future = p.submit(new StringTask());
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    taskStarted.countDown();
+                    assertEquals(1, p.getPoolSize());
+                    assertEquals(1, p.getActiveThreadCount());
+                    done.await();
+                }};
+            Future<?> future = p.submit(task);
+            await(taskStarted);
             assertEquals(1, p.getPoolSize());
-        } finally {
-            joinPool(p);
+            assertEquals(1, p.getActiveThreadCount());
+            done.countDown();
         }
+        assertEquals(0, p.getPoolSize());
+        assertEquals(0, p.getActiveThreadCount());
     }
 
     /**
@@ -234,26 +244,28 @@
      */
     public void testAwaitTermination_timesOut() throws InterruptedException {
         ForkJoinPool p = new ForkJoinPool(1);
-        assertFalse(p.isTerminated());
-        assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
-        assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
-        assertFalse(p.awaitTermination(-1L, NANOSECONDS));
-        assertFalse(p.awaitTermination(-1L, MILLISECONDS));
-        assertFalse(p.awaitTermination(0L, NANOSECONDS));
-        assertFalse(p.awaitTermination(0L, MILLISECONDS));
-        long timeoutNanos = 999999L;
-        long startTime = System.nanoTime();
-        assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
-        assertTrue(System.nanoTime() - startTime >= timeoutNanos);
-        assertFalse(p.isTerminated());
-        startTime = System.nanoTime();
-        long timeoutMillis = timeoutMillis();
-        assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
-        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
-        assertFalse(p.isTerminated());
-        p.shutdown();
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isTerminated());
+            assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
+            assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
+            assertFalse(p.awaitTermination(-1L, NANOSECONDS));
+            assertFalse(p.awaitTermination(-1L, MILLISECONDS));
+            assertFalse(p.awaitTermination(0L, NANOSECONDS));
+            assertFalse(p.awaitTermination(0L, MILLISECONDS));
+            long timeoutNanos = 999999L;
+            long startTime = System.nanoTime();
+            assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
+            assertTrue(System.nanoTime() - startTime >= timeoutNanos);
+            assertFalse(p.isTerminated());
+            startTime = System.nanoTime();
+            long timeoutMillis = timeoutMillis();
+            assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            assertFalse(p.isTerminated());
+            p.shutdown();
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+        }
     }
 
     /**
@@ -264,23 +276,23 @@
      */
     public void testSetUncaughtExceptionHandler() throws InterruptedException {
         final CountDownLatch uehInvoked = new CountDownLatch(1);
-        final Thread.UncaughtExceptionHandler eh =
+        final Thread.UncaughtExceptionHandler ueh =
             new Thread.UncaughtExceptionHandler() {
                 public void uncaughtException(Thread t, Throwable e) {
+                    threadAssertTrue(e instanceof MyError);
+                    threadAssertTrue(t instanceof FailingFJWSubclass);
                     uehInvoked.countDown();
                 }};
         ForkJoinPool p = new ForkJoinPool(1, new FailingThreadFactory(),
-                                          eh, false);
-        try {
-            assertSame(eh, p.getUncaughtExceptionHandler());
+                                          ueh, false);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(ueh, p.getUncaughtExceptionHandler());
             try {
                 p.execute(new FibTask(8));
-                assertTrue(uehInvoked.await(MEDIUM_DELAY_MS, MILLISECONDS));
-            } catch (RejectedExecutionException ok) {
+                await(uehInvoked);
+            } finally {
+                p.shutdownNow(); // failure might have prevented processing task
             }
-        } finally {
-            p.shutdownNow(); // failure might have prevented processing task
-            joinPool(p);
         }
     }
 
@@ -292,7 +304,7 @@
      */
     public void testIsQuiescent() throws Exception {
         ForkJoinPool p = new ForkJoinPool(2);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             assertTrue(p.isQuiescent());
             long startTime = System.nanoTime();
             FibTask f = new FibTask(20);
@@ -311,17 +323,18 @@
 
             assertTrue(p.isQuiescent());
             assertFalse(p.getAsyncMode());
-            assertEquals(0, p.getActiveThreadCount());
             assertEquals(0, p.getQueuedTaskCount());
             assertEquals(0, p.getQueuedSubmissionCount());
             assertFalse(p.hasQueuedSubmissions());
+            while (p.getActiveThreadCount() != 0
+                   && millisElapsedSince(startTime) < LONG_DELAY_MS)
+                Thread.yield();
             assertFalse(p.isShutdown());
             assertFalse(p.isTerminating());
             assertFalse(p.isTerminated());
             assertTrue(f.isDone());
             assertEquals(6765, (int) f.get());
-        } finally {
-            joinPool(p);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -330,11 +343,9 @@
      */
     public void testSubmitForkJoinTask() throws Throwable {
         ForkJoinPool p = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             ForkJoinTask<Integer> f = p.submit(new FibTask(8));
             assertEquals(21, (int) f.get());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -343,15 +354,13 @@
      */
     public void testSubmitAfterShutdown() {
         ForkJoinPool p = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             p.shutdown();
             assertTrue(p.isShutdown());
             try {
                 ForkJoinTask<Integer> f = p.submit(new FibTask(8));
                 shouldThrow();
             } catch (RejectedExecutionException success) {}
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -377,16 +386,14 @@
     public void testPollSubmission() {
         final CountDownLatch done = new CountDownLatch(1);
         SubFJP p = new SubFJP();
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             ForkJoinTask a = p.submit(awaiter(done));
             ForkJoinTask b = p.submit(awaiter(done));
             ForkJoinTask c = p.submit(awaiter(done));
             ForkJoinTask r = p.pollSubmission();
             assertTrue(r == a || r == b || r == c);
             assertFalse(r.isDone());
-        } finally {
             done.countDown();
-            joinPool(p);
         }
     }
 
@@ -396,7 +403,7 @@
     public void testDrainTasksTo() {
         final CountDownLatch done = new CountDownLatch(1);
         SubFJP p = new SubFJP();
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             ForkJoinTask a = p.submit(awaiter(done));
             ForkJoinTask b = p.submit(awaiter(done));
             ForkJoinTask c = p.submit(awaiter(done));
@@ -407,9 +414,7 @@
                 assertTrue(r == a || r == b || r == c);
                 assertFalse(r.isDone());
             }
-        } finally {
             done.countDown();
-            joinPool(p);
         }
     }
 
@@ -420,7 +425,7 @@
      */
     public void testExecuteRunnable() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             final AtomicBoolean done = new AtomicBoolean(false);
             Future<?> future = e.submit(new CheckedRunnable() {
                 public void realRun() {
@@ -431,8 +436,6 @@
             assertTrue(done.get());
             assertTrue(future.isDone());
             assertFalse(future.isCancelled());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -441,13 +444,11 @@
      */
     public void testSubmitCallable() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new StringTask());
             assertSame(TEST_STRING, future.get());
             assertTrue(future.isDone());
             assertFalse(future.isCancelled());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -456,13 +457,11 @@
      */
     public void testSubmitRunnable() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<?> future = e.submit(new NoOpRunnable());
             assertNull(future.get());
             assertTrue(future.isDone());
             assertFalse(future.isCancelled());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -471,13 +470,11 @@
      */
     public void testSubmitRunnable2() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
             assertSame(TEST_STRING, future.get());
             assertTrue(future.isDone());
             assertFalse(future.isCancelled());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -490,11 +487,9 @@
         Runnable r = new CheckedRunnable() {
         public void realRun() throws Exception {
             ExecutorService e = new ForkJoinPool(1);
-            try {
+            try (PoolCleaner cleaner = cleaner(e)) {
                 Future future = e.submit(callable);
                 assertSame(TEST_STRING, future.get());
-            } finally {
-                joinPool(e);
             }
         }};
 
@@ -511,11 +506,9 @@
         Runnable r = new CheckedRunnable() {
         public void realRun() throws Exception {
             ExecutorService e = new ForkJoinPool(1);
-            try {
+            try (PoolCleaner cleaner = cleaner(e)) {
                 Future future = e.submit(callable);
                 assertSame(TEST_STRING, future.get());
-            } finally {
-                joinPool(e);
             }
         }};
 
@@ -532,7 +525,7 @@
         Runnable r = new CheckedRunnable() {
         public void realRun() throws Exception {
             ExecutorService e = new ForkJoinPool(1);
-            try {
+            try (PoolCleaner cleaner = cleaner(e)) {
                 Future future = e.submit(callable);
                 try {
                     future.get();
@@ -540,8 +533,6 @@
                 } catch (ExecutionException success) {
                     assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
                 }
-            } finally {
-                joinPool(e);
             }
         }};
 
@@ -553,12 +544,11 @@
      */
     public void testExecuteNullRunnable() {
         ExecutorService e = new ForkJoinPool(1);
-        try {
-            Future<?> future = e.submit((Runnable) null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                Future<?> future = e.submit((Runnable) null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -567,12 +557,11 @@
      */
     public void testSubmitNullCallable() {
         ExecutorService e = new ForkJoinPool(1);
-        try {
-            Future<String> future = e.submit((Callable) null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                Future<String> future = e.submit((Callable) null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -582,13 +571,13 @@
     public void testInterruptedSubmit() throws InterruptedException {
         final CountDownLatch submitted    = new CountDownLatch(1);
         final CountDownLatch quittingTime = new CountDownLatch(1);
-        final ExecutorService p = new ForkJoinPool(1);
         final Callable<Void> awaiter = new CheckedCallable<Void>() {
             public Void realCall() throws InterruptedException {
-                assertTrue(quittingTime.await(MEDIUM_DELAY_MS, MILLISECONDS));
+                assertTrue(quittingTime.await(2*LONG_DELAY_MS, MILLISECONDS));
                 return null;
             }};
-        try {
+        final ExecutorService p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p, quittingTime)) {
             Thread t = new Thread(new CheckedInterruptedRunnable() {
                 public void realRun() throws Exception {
                     Future<Void> future = p.submit(awaiter);
@@ -596,12 +585,9 @@
                     future.get();
                 }});
             t.start();
-            assertTrue(submitted.await(MEDIUM_DELAY_MS, MILLISECONDS));
+            await(submitted);
             t.interrupt();
-            t.join();
-        } finally {
-            quittingTime.countDown();
-            joinPool(p);
+            awaitTermination(t);
         }
     }
 
@@ -611,15 +597,15 @@
      */
     public void testSubmitEE() throws Throwable {
         ForkJoinPool p = new ForkJoinPool(1);
-        try {
-            p.submit(new Callable() {
-                public Object call() { throw new ArithmeticException(); }})
-                .get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof ArithmeticException);
-        } finally {
-            joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.submit(new Callable() {
+                        public Object call() { throw new ArithmeticException(); }})
+                    .get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof ArithmeticException);
+            }
         }
     }
 
@@ -628,12 +614,11 @@
      */
     public void testInvokeAny1() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
-            e.invokeAny(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -642,12 +627,11 @@
      */
     public void testInvokeAny2() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>());
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -656,14 +640,13 @@
      */
     public void testInvokeAny3() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(null);
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -673,16 +656,15 @@
     public void testInvokeAny4() throws Throwable {
         CountDownLatch latch = new CountDownLatch(1);
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -691,15 +673,15 @@
      */
     public void testInvokeAny5() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -708,14 +690,12 @@
      */
     public void testInvokeAny6() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             String result = e.invokeAny(l);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -724,12 +704,11 @@
      */
     public void testInvokeAll1() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
-            e.invokeAll(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -738,12 +717,10 @@
      */
     public void testInvokeAll2() throws InterruptedException {
         ExecutorService e = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Future<String>> r
                 = e.invokeAll(new ArrayList<Callable<String>>());
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -752,15 +729,14 @@
      */
     public void testInvokeAll3() throws InterruptedException {
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -770,17 +746,17 @@
      */
     public void testInvokeAll4() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        List<Future<String>> futures = e.invokeAll(l);
-        assertEquals(1, futures.size());
-        try {
-            futures.get(0).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -789,7 +765,7 @@
      */
     public void testInvokeAll5() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
@@ -797,8 +773,6 @@
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -807,12 +781,11 @@
      */
     public void testTimedInvokeAny1() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
-            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -821,14 +794,13 @@
      */
     public void testTimedInvokeAnyNullTimeUnit() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -837,13 +809,12 @@
      */
     public void testTimedInvokeAny2() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>(),
-                        MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(),
+                            MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -853,16 +824,15 @@
     public void testTimedInvokeAny3() throws Throwable {
         CountDownLatch latch = new CountDownLatch(1);
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -871,15 +841,17 @@
      */
     public void testTimedInvokeAny4() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -888,14 +860,14 @@
      */
     public void testTimedInvokeAny5() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -904,12 +876,11 @@
      */
     public void testTimedInvokeAll1() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        try {
-            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -918,14 +889,13 @@
      */
     public void testTimedInvokeAllNullTimeUnit() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -934,13 +904,11 @@
      */
     public void testTimedInvokeAll2() throws InterruptedException {
         ExecutorService e = new ForkJoinPool(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Future<String>> r
                 = e.invokeAll(new ArrayList<Callable<String>>(),
                               MEDIUM_DELAY_MS, MILLISECONDS);
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -949,15 +917,14 @@
      */
     public void testTimedInvokeAll3() throws InterruptedException {
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -966,18 +933,18 @@
      */
     public void testTimedInvokeAll4() throws Throwable {
         ExecutorService e = new ForkJoinPool(1);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        List<Future<String>> futures
-            = e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-        assertEquals(1, futures.size());
-        try {
-            futures.get(0).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            List<Future<String>> futures
+                = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -985,18 +952,16 @@
      * timed invokeAll(c) returns results of all completed tasks in c
      */
     public void testTimedInvokeAll5() throws Throwable {
-        ExecutorService e = new ForkJoinPool(1);
-        try {
+        ForkJoinPool e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             List<Future<String>> futures
-                = e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
diff --git a/jsr166-tests/src/test/java/jsr166/ForkJoinTask8Test.java b/jsr166-tests/src/test/java/jsr166/ForkJoinTask8Test.java
new file mode 100644
index 0000000..6c03348
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ForkJoinTask8Test.java
@@ -0,0 +1,1205 @@
+/*
+ * 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 jsr166;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ForkJoinTask8Test extends JSR166TestCase {
+
+    /*
+     * Testing notes: This differs from ForkJoinTaskTest mainly by
+     * defining a version of BinaryAsyncAction that uses JDK8 task
+     * tags for control state, thereby testing getForkJoinTaskTag,
+     * setForkJoinTaskTag, and compareAndSetForkJoinTaskTag across
+     * various contexts. Most of the test methods using it are
+     * otherwise identical, but omitting retest of those dealing with
+     * cancellation, which is not represented in this tag scheme.
+     */
+
+    static final short INITIAL_STATE = -1;
+    static final short COMPLETE_STATE = 0;
+    static final short EXCEPTION_STATE = 1;
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(ForkJoinTask8Test.class);
+    // }
+
+    // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
+    static final int mainPoolSize =
+        Math.max(2, Runtime.getRuntime().availableProcessors());
+
+    private static ForkJoinPool mainPool() {
+        return new ForkJoinPool(mainPoolSize);
+    }
+
+    private static ForkJoinPool singletonPool() {
+        return new ForkJoinPool(1);
+    }
+
+    private static ForkJoinPool asyncSingletonPool() {
+        return new ForkJoinPool(1,
+                                ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+                                null, true);
+    }
+
+    // Compute fib naively and efficiently
+    final int[] fib;
+    {
+        int[] fib = new int[10];
+        fib[0] = 0;
+        fib[1] = 1;
+        for (int i = 2; i < fib.length; i++)
+            fib[i] = fib[i - 1] + fib[i - 2];
+        this.fib = fib;
+    }
+
+    private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            assertFalse(a.isDone());
+            assertFalse(a.isCompletedNormally());
+            assertFalse(a.isCompletedAbnormally());
+            assertFalse(a.isCancelled());
+            assertNull(a.getException());
+            assertNull(a.getRawResult());
+
+            assertNull(pool.invoke(a));
+
+            assertTrue(a.isDone());
+            assertTrue(a.isCompletedNormally());
+            assertFalse(a.isCompletedAbnormally());
+            assertFalse(a.isCancelled());
+            assertNull(a.getException());
+            assertNull(a.getRawResult());
+        }
+    }
+
+    void checkNotDone(ForkJoinTask a) {
+        assertFalse(a.isDone());
+        assertFalse(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertFalse(a.isCancelled());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+        if (a instanceof BinaryAsyncAction)
+            assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() == INITIAL_STATE);
+
+        try {
+            a.get(0L, SECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    <T> void checkCompletedNormally(ForkJoinTask<T> a) {
+        checkCompletedNormally(a, null);
+    }
+
+    <T> void checkCompletedNormally(ForkJoinTask<T> a, T expected) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertTrue(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertNull(a.getException());
+        assertSame(expected, a.getRawResult());
+        if (a instanceof BinaryAsyncAction)
+            assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() == COMPLETE_STATE);
+
+        {
+            Thread.currentThread().interrupt();
+            long startTime = System.nanoTime();
+            assertSame(expected, a.join());
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+            Thread.interrupted();
+        }
+
+        {
+            Thread.currentThread().interrupt();
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+            Thread.interrupted();
+        }
+
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        try {
+            assertSame(expected, a.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertSame(expected, a.get(5L, SECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertSame(t.getClass(), a.getException().getClass());
+        assertNull(a.getRawResult());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        if (a instanceof BinaryAsyncAction)
+            assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() != INITIAL_STATE);
+
+        try {
+            Thread.currentThread().interrupt();
+            a.join();
+            shouldThrow();
+        } catch (Throwable expected) {
+            assertSame(t.getClass(), expected.getClass());
+        }
+        Thread.interrupted();
+
+        {
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    public static final class FJException extends RuntimeException {
+        FJException() { super(); }
+    }
+
+    abstract static class BinaryAsyncAction extends ForkJoinTask<Void> {
+
+        private volatile BinaryAsyncAction parent;
+
+        private volatile BinaryAsyncAction sibling;
+
+        protected BinaryAsyncAction() {
+            setForkJoinTaskTag(INITIAL_STATE);
+        }
+
+        public final Void getRawResult() { return null; }
+        protected final void setRawResult(Void mustBeNull) { }
+
+        public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
+            x.parent = y.parent = this;
+            x.sibling = y;
+            y.sibling = x;
+        }
+
+        protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+            if (this.getForkJoinTaskTag() != COMPLETE_STATE ||
+                x.getForkJoinTaskTag() != COMPLETE_STATE ||
+                y.getForkJoinTaskTag() != COMPLETE_STATE) {
+                completeThisExceptionally(new FJException());
+            }
+        }
+
+        protected boolean onException() {
+            return true;
+        }
+
+        public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
+            linkSubtasks(x, y);
+            y.fork();
+            x.fork();
+        }
+
+        private void completeThis() {
+            setForkJoinTaskTag(COMPLETE_STATE);
+            super.complete(null);
+        }
+
+        private void completeThisExceptionally(Throwable ex) {
+            setForkJoinTaskTag(EXCEPTION_STATE);
+            super.completeExceptionally(ex);
+        }
+
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            if (super.cancel(mayInterruptIfRunning)) {
+                completeExceptionally(new FJException());
+                return true;
+            }
+            return false;
+        }
+
+        public final void complete() {
+            BinaryAsyncAction a = this;
+            for (;;) {
+                BinaryAsyncAction s = a.sibling;
+                BinaryAsyncAction p = a.parent;
+                a.sibling = null;
+                a.parent = null;
+                a.completeThis();
+                if (p == null ||
+                    p.compareAndSetForkJoinTaskTag(INITIAL_STATE, COMPLETE_STATE))
+                    break;
+                try {
+                    p.onComplete(a, s);
+                } catch (Throwable rex) {
+                    p.completeExceptionally(rex);
+                    return;
+                }
+                a = p;
+            }
+        }
+
+        public final void completeExceptionally(Throwable ex) {
+            for (BinaryAsyncAction a = this;;) {
+                a.completeThisExceptionally(ex);
+                BinaryAsyncAction s = a.sibling;
+                if (s != null && !s.isDone())
+                    s.completeExceptionally(ex);
+                if ((a = a.parent) == null)
+                    break;
+            }
+        }
+
+        public final BinaryAsyncAction getParent() {
+            return parent;
+        }
+
+        public BinaryAsyncAction getSibling() {
+            return sibling;
+        }
+
+        public void reinitialize() {
+            parent = sibling = null;
+            super.reinitialize();
+        }
+
+    }
+
+    final class AsyncFib extends BinaryAsyncAction {
+        int number;
+        int expectedResult;
+        public AsyncFib(int number) {
+            this.number = number;
+            this.expectedResult = fib[number];
+        }
+
+        public final boolean exec() {
+            try {
+                AsyncFib f = this;
+                int n = f.number;
+                while (n > 1) {
+                    AsyncFib p = f;
+                    AsyncFib r = new AsyncFib(n - 2);
+                    f = new AsyncFib(--n);
+                    p.linkSubtasks(r, f);
+                    r.fork();
+                }
+                f.complete();
+            }
+            catch (Throwable ex) {
+                compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
+            }
+            if (getForkJoinTaskTag() == EXCEPTION_STATE)
+                throw new FJException();
+            return false;
+        }
+
+        protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+            number = ((AsyncFib)x).number + ((AsyncFib)y).number;
+            super.onComplete(x, y);
+        }
+
+        public void checkCompletedNormally() {
+            assertEquals(expectedResult, number);
+            ForkJoinTask8Test.this.checkCompletedNormally(this);
+        }
+    }
+
+    static final class FailingAsyncFib extends BinaryAsyncAction {
+        int number;
+        public FailingAsyncFib(int n) {
+            this.number = n;
+        }
+
+        public final boolean exec() {
+            try {
+                FailingAsyncFib f = this;
+                int n = f.number;
+                while (n > 1) {
+                    FailingAsyncFib p = f;
+                    FailingAsyncFib r = new FailingAsyncFib(n - 2);
+                    f = new FailingAsyncFib(--n);
+                    p.linkSubtasks(r, f);
+                    r.fork();
+                }
+                f.complete();
+            }
+            catch (Throwable ex) {
+                compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
+            }
+            if (getForkJoinTaskTag() == EXCEPTION_STATE)
+                throw new FJException();
+            return false;
+        }
+
+        protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+            completeExceptionally(new FJException());
+        }
+    }
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks; getRawResult returns null.
+     */
+    public void testInvoke() {
+        testInvoke(mainPool());
+    }
+    public void testInvoke_Singleton() {
+        testInvoke(singletonPool());
+    }
+    public void testInvoke(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertNull(f.invoke());
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvoke() {
+        testQuietlyInvoke(mainPool());
+    }
+    public void testQuietlyInvoke_Singleton() {
+        testQuietlyInvoke(singletonPool());
+    }
+    public void testQuietlyInvoke(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.quietlyInvoke();
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoin() {
+        testForkJoin(mainPool());
+    }
+    public void testForkJoin_Singleton() {
+        testForkJoin(singletonPool());
+    }
+    public void testForkJoin(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGet() {
+        testForkGet(mainPool());
+    }
+    public void testForkGet_Singleton() {
+        testForkGet(singletonPool());
+    }
+    public void testForkGet(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGet() {
+        testForkTimedGet(mainPool());
+    }
+    public void testForkTimedGet_Singleton() {
+        testForkTimedGet(singletonPool());
+    }
+    public void testForkTimedGet(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * timed get with null time unit throws NullPointerException
+     */
+    public void testForkTimedGetNullTimeUnit() {
+        testForkTimedGetNullTimeUnit(mainPool());
+    }
+    public void testForkTimedGetNullTimeUnit_Singleton() {
+        testForkTimedGet(singletonPool());
+    }
+    public void testForkTimedGetNullTimeUnit(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoin() {
+        testForkQuietlyJoin(mainPool());
+    }
+    public void testForkQuietlyJoin_Singleton() {
+        testForkQuietlyJoin(singletonPool());
+    }
+    public void testForkQuietlyJoin(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * helpQuiesce returns when tasks are complete.
+     * getQueuedTaskCount returns 0 when quiescent
+     */
+    public void testForkHelpQuiesce() {
+        testForkHelpQuiesce(mainPool());
+    }
+    public void testForkHelpQuiesce_Singleton() {
+        testForkHelpQuiesce(singletonPool());
+    }
+    public void testForkHelpQuiesce(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                helpQuiesce();
+                assertEquals(0, getQueuedTaskCount());
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvoke() {
+        testAbnormalInvoke(mainPool());
+    }
+    public void testAbnormalInvoke_Singleton() {
+        testAbnormalInvoke(singletonPool());
+    }
+    public void testAbnormalInvoke(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvoke() {
+        testAbnormalQuietlyInvoke(mainPool());
+    }
+    public void testAbnormalQuietlyInvoke_Singleton() {
+        testAbnormalQuietlyInvoke(singletonPool());
+    }
+    public void testAbnormalQuietlyInvoke(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoin() {
+        testAbnormalForkJoin(mainPool());
+    }
+    public void testAbnormalForkJoin_Singleton() {
+        testAbnormalForkJoin(singletonPool());
+    }
+    public void testAbnormalForkJoin(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGet() {
+        testAbnormalForkGet(mainPool());
+    }
+    public void testAbnormalForkGet_Singleton() {
+        testAbnormalForkJoin(singletonPool());
+    }
+    public void testAbnormalForkGet(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGet() {
+        testAbnormalForkTimedGet(mainPool());
+    }
+    public void testAbnormalForkTimedGet_Singleton() {
+        testAbnormalForkTimedGet(singletonPool());
+    }
+    public void testAbnormalForkTimedGet(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoin() {
+        testAbnormalForkQuietlyJoin(mainPool());
+    }
+    public void testAbnormalForkQuietlyJoin_Singleton() {
+        testAbnormalForkQuietlyJoin(singletonPool());
+    }
+    public void testAbnormalForkQuietlyJoin(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * getPool of executing task returns its pool
+     */
+    public void testGetPool() {
+        testGetPool(mainPool());
+    }
+    public void testGetPool_Singleton() {
+        testGetPool(singletonPool());
+    }
+    public void testGetPool(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertSame(pool, getPool());
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * getPool of non-FJ task returns null
+     */
+    public void testGetPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertNull(getPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * inForkJoinPool of executing task returns true
+     */
+    public void testInForkJoinPool() {
+        testInForkJoinPool(mainPool());
+    }
+    public void testInForkJoinPool_Singleton() {
+        testInForkJoinPool(singletonPool());
+    }
+    public void testInForkJoinPool(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertTrue(inForkJoinPool());
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertFalse(inForkJoinPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * setRawResult(null) succeeds
+     */
+    public void testSetRawResult() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                setRawResult(null);
+                assertNull(getRawResult());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally() {
+        testCompleteExceptionally(mainPool());
+    }
+    public void testCompleteExceptionally_Singleton() {
+        testCompleteExceptionally(singletonPool());
+    }
+    public void testCompleteExceptionally(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.completeExceptionally(new FJException());
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1() {
+        testInvokeAll1(mainPool());
+    }
+    public void testInvokeAll1_Singleton() {
+        testInvokeAll1(singletonPool());
+    }
+    public void testInvokeAll1(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                invokeAll(f);
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2() {
+        testInvokeAll2(mainPool());
+    }
+    public void testInvokeAll2_Singleton() {
+        testInvokeAll2(singletonPool());
+    }
+    public void testInvokeAll2(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib[] tasks = {
+                    new AsyncFib(8),
+                    new AsyncFib(9),
+                };
+                invokeAll(tasks[0], tasks[1]);
+                for (AsyncFib task : tasks) assertTrue(task.isDone());
+                for (AsyncFib task : tasks) task.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3() {
+        testInvokeAll3(mainPool());
+    }
+    public void testInvokeAll3_Singleton() {
+        testInvokeAll3(singletonPool());
+    }
+    public void testInvokeAll3(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib[] tasks = {
+                    new AsyncFib(8),
+                    new AsyncFib(9),
+                    new AsyncFib(7),
+                };
+                invokeAll(tasks[0], tasks[1], tasks[2]);
+                for (AsyncFib task : tasks) assertTrue(task.isDone());
+                for (AsyncFib task : tasks) task.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollection() {
+        testInvokeAllCollection(mainPool());
+    }
+    public void testInvokeAllCollection_Singleton() {
+        testInvokeAllCollection(singletonPool());
+    }
+    public void testInvokeAllCollection(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib[] tasks = {
+                    new AsyncFib(8),
+                    new AsyncFib(9),
+                    new AsyncFib(7),
+                };
+                invokeAll(Arrays.asList(tasks));
+                for (AsyncFib task : tasks) assertTrue(task.isDone());
+                for (AsyncFib task : tasks) task.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NullPointerException
+     */
+    public void testInvokeAllNullTask() {
+        testInvokeAllNullTask(mainPool());
+    }
+    public void testInvokeAllNullTask_Singleton() {
+        testInvokeAllNullTask(singletonPool());
+    }
+    public void testInvokeAllNullTask(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib nul = null;
+                Runnable[] throwingActions = {
+                    () -> invokeAll(nul),
+                    () -> invokeAll(nul, nul),
+                    () -> invokeAll(new AsyncFib(8), new AsyncFib(9), nul),
+                    () -> invokeAll(new AsyncFib(8), nul, new AsyncFib(9)),
+                    () -> invokeAll(nul, new AsyncFib(8), new AsyncFib(9)),
+                };
+                assertThrows(NullPointerException.class, throwingActions);
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1() {
+        testAbnormalInvokeAll1(mainPool());
+    }
+    public void testAbnormalInvokeAll1_Singleton() {
+        testAbnormalInvokeAll1(singletonPool());
+    }
+    public void testAbnormalInvokeAll1(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2() {
+        testAbnormalInvokeAll2(mainPool());
+    }
+    public void testAbnormalInvokeAll2_Singleton() {
+        testAbnormalInvokeAll2(singletonPool());
+    }
+    public void testAbnormalInvokeAll2(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                ForkJoinTask[] tasks = { f, g };
+                Collections.shuffle(Arrays.asList(tasks));
+                try {
+                    invokeAll(tasks[0], tasks[1]);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3() {
+        testAbnormalInvokeAll3(mainPool());
+    }
+    public void testAbnormalInvokeAll3_Singleton() {
+        testAbnormalInvokeAll3(singletonPool());
+    }
+    public void testAbnormalInvokeAll3(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                Collections.shuffle(Arrays.asList(tasks));
+                try {
+                    invokeAll(tasks[0], tasks[1], tasks[2]);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollection() {
+        testAbnormalInvokeAllCollection(mainPool());
+    }
+    public void testAbnormalInvokeAllCollection_Singleton() {
+        testAbnormalInvokeAllCollection(singletonPool());
+    }
+    public void testAbnormalInvokeAllCollection(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                Collections.shuffle(Arrays.asList(tasks));
+                try {
+                    invokeAll(Arrays.asList(tasks));
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * tryUnfork returns true for most recent unexecuted task,
+     * and suppresses execution
+     */
+    public void testTryUnfork() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertTrue(f.tryUnfork());
+                helpQuiesce();
+                checkNotDone(f);
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * getSurplusQueuedTaskCount returns > 0 when
+     * there are more tasks than threads
+     */
+    public void testGetSurplusQueuedTaskCount() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib h = new AsyncFib(7);
+                assertSame(h, h.fork());
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertTrue(getSurplusQueuedTaskCount() > 0);
+                helpQuiesce();
+                assertEquals(0, getSurplusQueuedTaskCount());
+                f.checkCompletedNormally();
+                g.checkCompletedNormally();
+                h.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns most recent unexecuted task.
+     */
+    public void testPeekNextLocalTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(f, peekNextLocalTask());
+                assertNull(f.join());
+                f.checkCompletedNormally();
+                helpQuiesce();
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns most recent unexecuted task without
+     * executing it
+     */
+    public void testPollNextLocalTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollNextLocalTask());
+                helpQuiesce();
+                checkNotDone(f);
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it
+     */
+    public void testPollTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollTask());
+                helpQuiesce();
+                checkNotDone(f);
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns least recent unexecuted task in async mode
+     */
+    public void testPeekNextLocalTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(g, peekNextLocalTask());
+                assertNull(f.join());
+                helpQuiesce();
+                f.checkCompletedNormally();
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns least recent unexecuted task without
+     * executing it, in async mode
+     */
+    public void testPollNextLocalTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollNextLocalTask());
+                helpQuiesce();
+                f.checkCompletedNormally();
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it, in
+     * async mode
+     */
+    public void testPollTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollTask());
+                helpQuiesce();
+                f.checkCompletedNormally();
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * ForkJoinTask.quietlyComplete returns when task completes
+     * normally without setting a value. The most recent value
+     * established by setRawResult(V) (or null by default) is returned
+     * from invoke.
+     */
+    public void testQuietlyComplete() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+                protected void realCompute() {
+                    AsyncFib f = new AsyncFib(8);
+                    f.quietlyComplete();
+                    assertEquals(8, f.number);
+                    assertTrue(f.isDone());
+                    assertFalse(f.isCancelled());
+                    assertTrue(f.isCompletedNormally());
+                    assertFalse(f.isCompletedAbnormally());
+                    assertNull(f.getException());
+                }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    // jdk9
+
+    /**
+     * pollSubmission returns unexecuted submitted task, if present
+     */
+    public void testPollSubmission() {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ForkJoinTask a = ForkJoinTask.adapt(awaiter(done));
+        final ForkJoinTask b = ForkJoinTask.adapt(awaiter(done));
+        final ForkJoinTask c = ForkJoinTask.adapt(awaiter(done));
+        final ForkJoinPool p = singletonPool();
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Thread external = new Thread(new CheckedRunnable() {
+                public void realRun() {
+                    p.execute(a);
+                    p.execute(b);
+                    p.execute(c);
+                }});
+            RecursiveAction s = new CheckedRecursiveAction() {
+                protected void realCompute() {
+                    external.start();
+                    try {
+                        external.join();
+                    } catch (Exception ex) {
+                        threadUnexpectedException(ex);
+                    }
+                    assertTrue(p.hasQueuedSubmissions());
+                    assertTrue(Thread.currentThread() instanceof ForkJoinWorkerThread);
+                    ForkJoinTask r = ForkJoinTask.pollSubmission();
+                    assertTrue(r == a || r == b || r == c);
+                    assertFalse(r.isDone());
+                }};
+            p.invoke(s);
+        }
+    }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java b/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java
index 3c1fcb7..1616d4f 100644
--- a/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ForkJoinTaskTest.java
@@ -9,7 +9,10 @@
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.SECONDS;
 
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ForkJoinPool;
@@ -30,7 +33,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ForkJoinTaskTest.class);
     // }
 
     // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
@@ -52,7 +55,7 @@
     }
 
     private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
-        try {
+        try (PoolCleaner cleaner = cleaner(pool)) {
             assertFalse(a.isDone());
             assertFalse(a.isCompletedNormally());
             assertFalse(a.isCompletedAbnormally());
@@ -68,8 +71,6 @@
             assertFalse(a.isCancelled());
             assertNull(a.getException());
             assertNull(a.getRawResult());
-        } finally {
-            joinPool(pool);
         }
     }
 
@@ -102,17 +103,17 @@
 
         {
             Thread.currentThread().interrupt();
-            long t0 = System.nanoTime();
+            long startTime = System.nanoTime();
             assertSame(expected, a.join());
-            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
             Thread.interrupted();
         }
 
         {
             Thread.currentThread().interrupt();
-            long t0 = System.nanoTime();
+            long startTime = System.nanoTime();
             a.quietlyJoin();        // should be no-op
-            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
             Thread.interrupted();
         }
 
@@ -145,9 +146,9 @@
         Thread.interrupted();
 
         {
-            long t0 = System.nanoTime();
+            long startTime = System.nanoTime();
             a.quietlyJoin();        // should be no-op
-            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
         }
 
         try {
@@ -183,9 +184,9 @@
         Thread.interrupted();
 
         {
-            long t0 = System.nanoTime();
+            long startTime = System.nanoTime();
             a.quietlyJoin();        // should be no-op
-            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
         }
 
         try {
@@ -222,9 +223,9 @@
             AtomicIntegerFieldUpdater.newUpdater(BinaryAsyncAction.class,
                                                  "controlState");
 
-        private BinaryAsyncAction parent;
+        private volatile BinaryAsyncAction parent;
 
-        private BinaryAsyncAction sibling;
+        private volatile BinaryAsyncAction sibling;
 
         protected BinaryAsyncAction() {
         }
@@ -259,6 +260,14 @@
             super.completeExceptionally(ex);
         }
 
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            if (super.cancel(mayInterruptIfRunning)) {
+                completeExceptionally(new FJException());
+                return true;
+            }
+            return false;
+        }
+
         public final void complete() {
             BinaryAsyncAction a = this;
             for (;;) {
@@ -280,13 +289,12 @@
         }
 
         public final void completeExceptionally(Throwable ex) {
-            BinaryAsyncAction a = this;
-            while (!a.isCompletedAbnormally()) {
+            for (BinaryAsyncAction a = this;;) {
                 a.completeThisExceptionally(ex);
                 BinaryAsyncAction s = a.sibling;
-                if (s != null)
-                    s.cancel(false);
-                if (!a.onException() || (a = a.parent) == null)
+                if (s != null && !s.isDone())
+                    s.completeExceptionally(ex);
+                if ((a = a.parent) == null)
                     break;
             }
         }
@@ -336,15 +344,12 @@
         public final boolean exec() {
             AsyncFib f = this;
             int n = f.number;
-            if (n > 1) {
-                while (n > 1) {
-                    AsyncFib p = f;
-                    AsyncFib r = new AsyncFib(n - 2);
-                    f = new AsyncFib(--n);
-                    p.linkSubtasks(r, f);
-                    r.fork();
-                }
-                f.number = n;
+            while (n > 1) {
+                AsyncFib p = f;
+                AsyncFib r = new AsyncFib(n - 2);
+                f = new AsyncFib(--n);
+                p.linkSubtasks(r, f);
+                r.fork();
             }
             f.complete();
             return false;
@@ -364,15 +369,12 @@
         public final boolean exec() {
             FailingAsyncFib f = this;
             int n = f.number;
-            if (n > 1) {
-                while (n > 1) {
-                    FailingAsyncFib p = f;
-                    FailingAsyncFib r = new FailingAsyncFib(n - 2);
-                    f = new FailingAsyncFib(--n);
-                    p.linkSubtasks(r, f);
-                    r.fork();
-                }
-                f.number = n;
+            while (n > 1) {
+                FailingAsyncFib p = f;
+                FailingAsyncFib r = new FailingAsyncFib(n - 2);
+                f = new FailingAsyncFib(--n);
+                p.linkSubtasks(r, f);
+                r.fork();
             }
             f.complete();
             return false;
@@ -778,6 +780,27 @@
     }
 
     /**
+     * completeExceptionally(null) surprisingly has the same effect as
+     * completeExceptionally(new RuntimeException())
+     */
+    public void testCompleteExceptionally_null() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.completeExceptionally(null);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (RuntimeException success) {
+                    assertSame(success.getClass(), RuntimeException.class);
+                    assertNull(success.getCause());
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
      * invokeAll(t1, t2) invokes all task arguments
      */
     public void testInvokeAll2() {
@@ -877,8 +900,10 @@
             protected void realCompute() {
                 AsyncFib f = new AsyncFib(8);
                 FailingAsyncFib g = new FailingAsyncFib(9);
+                ForkJoinTask[] tasks = { f, g };
+                Collections.shuffle(Arrays.asList(tasks));
                 try {
-                    invokeAll(f, g);
+                    invokeAll(tasks);
                     shouldThrow();
                 } catch (FJException success) {
                     checkCompletedAbnormally(g, success);
@@ -913,8 +938,10 @@
                 AsyncFib f = new AsyncFib(8);
                 FailingAsyncFib g = new FailingAsyncFib(9);
                 AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                Collections.shuffle(Arrays.asList(tasks));
                 try {
-                    invokeAll(f, g, h);
+                    invokeAll(tasks);
                     shouldThrow();
                 } catch (FJException success) {
                     checkCompletedAbnormally(g, success);
@@ -932,12 +959,11 @@
                 FailingAsyncFib f = new FailingAsyncFib(8);
                 AsyncFib g = new AsyncFib(9);
                 AsyncFib h = new AsyncFib(7);
-                HashSet set = new HashSet();
-                set.add(f);
-                set.add(g);
-                set.add(h);
+                ForkJoinTask[] tasks = { f, g, h };
+                List taskList = Arrays.asList(tasks);
+                Collections.shuffle(taskList);
                 try {
-                    invokeAll(set);
+                    invokeAll(taskList);
                     shouldThrow();
                 } catch (FJException success) {
                     checkCompletedAbnormally(f, success);
@@ -1544,8 +1570,10 @@
             protected void realCompute() {
                 AsyncFib f = new AsyncFib(8);
                 FailingAsyncFib g = new FailingAsyncFib(9);
+                ForkJoinTask[] tasks = { f, g };
+                Collections.shuffle(Arrays.asList(tasks));
                 try {
-                    invokeAll(f, g);
+                    invokeAll(tasks);
                     shouldThrow();
                 } catch (FJException success) {
                     checkCompletedAbnormally(g, success);
@@ -1580,8 +1608,10 @@
                 AsyncFib f = new AsyncFib(8);
                 FailingAsyncFib g = new FailingAsyncFib(9);
                 AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                Collections.shuffle(Arrays.asList(tasks));
                 try {
-                    invokeAll(f, g, h);
+                    invokeAll(tasks);
                     shouldThrow();
                 } catch (FJException success) {
                     checkCompletedAbnormally(g, success);
@@ -1599,12 +1629,11 @@
                 FailingAsyncFib f = new FailingAsyncFib(8);
                 AsyncFib g = new AsyncFib(9);
                 AsyncFib h = new AsyncFib(7);
-                HashSet set = new HashSet();
-                set.add(f);
-                set.add(g);
-                set.add(h);
+                ForkJoinTask[] tasks = { f, g, h };
+                List taskList = Arrays.asList(tasks);
+                Collections.shuffle(taskList);
                 try {
-                    invokeAll(set);
+                    invokeAll(taskList);
                     shouldThrow();
                 } catch (FJException success) {
                     checkCompletedAbnormally(f, success);
diff --git a/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java b/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java
index a5d8c46..44d12b3 100644
--- a/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java
+++ b/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java
@@ -38,7 +38,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(FutureTaskTest.class);
     // }
 
     void checkIsDone(Future<?> f) {
@@ -272,8 +272,8 @@
         for (int i = 0; i < 3; i++) {
             assertTrue(task.runAndReset());
             checkNotDone(task);
-            assertEquals(i+1, task.runCount());
-            assertEquals(i+1, task.runAndResetCount());
+            assertEquals(i + 1, task.runCount());
+            assertEquals(i + 1, task.runAndResetCount());
             assertEquals(0, task.setCount());
             assertEquals(0, task.setExceptionCount());
         }
@@ -289,7 +289,7 @@
             for (int i = 0; i < 3; i++) {
                 assertFalse(task.runAndReset());
                 assertEquals(0, task.runCount());
-                assertEquals(i+1, task.runAndResetCount());
+                assertEquals(i + 1, task.runAndResetCount());
                 assertEquals(0, task.setCount());
                 assertEquals(0, task.setExceptionCount());
             }
diff --git a/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
index 46be906..fc1632c 100644
--- a/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
+++ b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
@@ -6,17 +6,21 @@
  * Pat Fisher, Mike Judd.
  */
 
+
 package jsr166;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MINUTES;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
-import java.security.CodeSource;
+import java.lang.reflect.Modifier;
+ import java.security.CodeSource;
 import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.Permissions;
@@ -35,7 +39,10 @@
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.Future;
 import java.util.concurrent.RecursiveAction;
 import java.util.concurrent.RecursiveTask;
@@ -44,12 +51,15 @@
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import junit.framework.AssertionFailedError;
 import junit.framework.Test;
 import junit.framework.TestCase;
+import junit.framework.TestResult;
 import junit.framework.TestSuite;
 
 /**
@@ -62,18 +72,18 @@
  *
  * <ol>
  *
- * <li> All assertions in code running in generated threads must use
+ * <li>All assertions in code running in generated threads must use
  * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link
  * #threadAssertEquals}, or {@link #threadAssertNull}, (not
  * {@code fail}, {@code assertTrue}, etc.) It is OK (but not
  * particularly recommended) for other code to use these forms too.
  * Only the most typically used JUnit assertion methods are defined
- * this way, but enough to live with.</li>
+ * this way, but enough to live with.
  *
- * <li> If you override {@link #setUp} or {@link #tearDown}, make sure
+ * <li>If you override {@link #setUp} or {@link #tearDown}, make sure
  * to invoke {@code super.setUp} and {@code super.tearDown} within
  * them. These methods are used to clear and check for thread
- * assertion failures.</li>
+ * assertion failures.
  *
  * <li>All delays and timeouts must use one of the constants {@code
  * SHORT_DELAY_MS}, {@code SMALL_DELAY_MS}, {@code MEDIUM_DELAY_MS},
@@ -84,51 +94,480 @@
  * is always discriminable as larger than SHORT and smaller than
  * MEDIUM.  And so on. These constants are set to conservative values,
  * but even so, if there is ever any doubt, they can all be increased
- * in one spot to rerun tests on slower platforms.</li>
+ * in one spot to rerun tests on slower platforms.
  *
- * <li> All threads generated must be joined inside each test case
+ * <li>All threads generated must be joined inside each test case
  * method (or {@code fail} to do so) before returning from the
  * method. The {@code joinPool} method can be used to do this when
- * using Executors.</li>
+ * using Executors.
  *
  * </ol>
  *
  * <p><b>Other notes</b>
  * <ul>
  *
- * <li> Usually, there is one testcase method per JSR166 method
+ * <li>Usually, there is one testcase method per JSR166 method
  * covering "normal" operation, and then as many exception-testing
  * methods as there are exceptions the method can throw. Sometimes
  * there are multiple tests per JSR166 method when the different
  * "normal" behaviors differ significantly. And sometimes testcases
- * cover multiple methods when they cannot be tested in
- * isolation.</li>
+ * cover multiple methods when they cannot be tested in isolation.
  *
- * <li> The documentation style for testcases is to provide as javadoc
+ * <li>The documentation style for testcases is to provide as javadoc
  * a simple sentence or two describing the property that the testcase
  * method purports to test. The javadocs do not say anything about how
- * the property is tested. To find out, read the code.</li>
+ * the property is tested. To find out, read the code.
  *
- * <li> These tests are "conformance tests", and do not attempt to
+ * <li>These tests are "conformance tests", and do not attempt to
  * test throughput, latency, scalability or other performance factors
  * (see the separate "jtreg" tests for a set intended to check these
  * for the most central aspects of functionality.) So, most tests use
  * the smallest sensible numbers of threads, collection sizes, etc
- * needed to check basic conformance.</li>
+ * needed to check basic conformance.
  *
  * <li>The test classes currently do not declare inclusion in
  * any particular package to simplify things for people integrating
- * them in TCK test suites.</li>
+ * them in TCK test suites.
  *
- * <li> As a convenience, the {@code main} of this class (JSR166TestCase)
- * runs all JSR166 unit tests.</li>
+ * <li>As a convenience, the {@code main} of this class (JSR166TestCase)
+ * runs all JSR166 unit tests.
  *
  * </ul>
  */
 public class JSR166TestCase extends TestCase {
-    // Delays for timing-dependent tests, in milliseconds.
+    private static final boolean useSecurityManager =
+        Boolean.getBoolean("jsr166.useSecurityManager");
 
-    protected static final boolean expensiveTests = false;
+    protected static final boolean expensiveTests =
+        Boolean.getBoolean("jsr166.expensiveTests");
+
+    /**
+     * If true, also run tests that are not part of the official tck
+     * because they test unspecified implementation details.
+     */
+    protected static final boolean testImplementationDetails =
+        Boolean.getBoolean("jsr166.testImplementationDetails");
+
+    /**
+     * If true, report on stdout all "slow" tests, that is, ones that
+     * take more than profileThreshold milliseconds to execute.
+     */
+    private static final boolean profileTests =
+        Boolean.getBoolean("jsr166.profileTests");
+
+    /**
+     * The number of milliseconds that tests are permitted for
+     * execution without being reported, when profileTests is set.
+     */
+    private static final long profileThreshold =
+        Long.getLong("jsr166.profileThreshold", 100);
+
+    /**
+     * The number of repetitions per test (for tickling rare bugs).
+     */
+    private static final int runsPerTest =
+        Integer.getInteger("jsr166.runsPerTest", 1);
+
+    /**
+     * The number of repetitions of the test suite (for finding leaks?).
+     */
+    private static final int suiteRuns =
+        Integer.getInteger("jsr166.suiteRuns", 1);
+
+    private static float systemPropertyValue(String name, float defaultValue) {
+        String floatString = System.getProperty(name);
+        if (floatString == null)
+            return defaultValue;
+        try {
+            return Float.parseFloat(floatString);
+        } catch (NumberFormatException ex) {
+            throw new IllegalArgumentException(
+                String.format("Bad float value in system property %s=%s",
+                              name, floatString));
+        }
+    }
+
+    /**
+     * The scaling factor to apply to standard delays used in tests.
+     */
+    private static final float delayFactor =
+        systemPropertyValue("jsr166.delay.factor", 1.0f);
+
+    /**
+     * The timeout factor as used in the jtreg test harness.
+     * See: http://openjdk.java.net/jtreg/tag-spec.html
+     */
+    private static final float jtregTestTimeoutFactor
+        = systemPropertyValue("test.timeout.factor", 1.0f);
+
+    public JSR166TestCase() { super(); }
+    public JSR166TestCase(String name) { super(name); }
+
+    /**
+     * A filter for tests to run, matching strings of the form
+     * methodName(className), e.g. "testInvokeAll5(ForkJoinPoolTest)"
+     * Usefully combined with jsr166.runsPerTest.
+     */
+    private static final Pattern methodFilter = methodFilter();
+
+    private static Pattern methodFilter() {
+        String regex = System.getProperty("jsr166.methodFilter");
+        return (regex == null) ? null : Pattern.compile(regex);
+    }
+
+    // Instrumentation to debug very rare, but very annoying hung test runs.
+    static volatile TestCase currentTestCase;
+    // static volatile int currentRun = 0;
+    static {
+        Runnable checkForWedgedTest = new Runnable() { public void run() {
+            // Avoid spurious reports with enormous runsPerTest.
+            // A single test case run should never take more than 1 second.
+            // But let's cap it at the high end too ...
+            final int timeoutMinutes =
+                Math.min(15, Math.max(runsPerTest / 60, 1));
+            for (TestCase lastTestCase = currentTestCase;;) {
+                try { MINUTES.sleep(timeoutMinutes); }
+                catch (InterruptedException unexpected) { break; }
+                if (lastTestCase == currentTestCase) {
+                    System.err.printf(
+                        "Looks like we're stuck running test: %s%n",
+                        lastTestCase);
+//                     System.err.printf(
+//                         "Looks like we're stuck running test: %s (%d/%d)%n",
+//                         lastTestCase, currentRun, runsPerTest);
+//                     System.err.println("availableProcessors=" +
+//                         Runtime.getRuntime().availableProcessors());
+//                     System.err.printf("cpu model = %s%n", cpuModel());
+                    dumpTestThreads();
+                    // one stack dump is probably enough; more would be spam
+                    break;
+                }
+                lastTestCase = currentTestCase;
+            }}};
+        Thread thread = new Thread(checkForWedgedTest, "checkForWedgedTest");
+        thread.setDaemon(true);
+        thread.start();
+    }
+
+//     public static String cpuModel() {
+//         try {
+//             Matcher matcher = Pattern.compile("model name\\s*: (.*)")
+//                 .matcher(new String(
+//                      Files.readAllBytes(Paths.get("/proc/cpuinfo")), "UTF-8"));
+//             matcher.find();
+//             return matcher.group(1);
+//         } catch (Exception ex) { return null; }
+//     }
+
+    public void runBare() throws Throwable {
+        currentTestCase = this;
+        if (methodFilter == null
+            || methodFilter.matcher(toString()).find())
+            super.runBare();
+    }
+
+    protected void runTest() throws Throwable {
+        for (int i = 0; i < runsPerTest; i++) {
+            // currentRun = i;
+            if (profileTests)
+                runTestProfiled();
+            else
+                super.runTest();
+        }
+    }
+
+    protected void runTestProfiled() throws Throwable {
+        for (int i = 0; i < 2; i++) {
+            long startTime = System.nanoTime();
+            super.runTest();
+            long elapsedMillis = millisElapsedSince(startTime);
+            if (elapsedMillis < profileThreshold)
+                break;
+            // Never report first run of any test; treat it as a
+            // warmup run, notably to trigger all needed classloading,
+            if (i > 0)
+                System.out.printf("%n%s: %d%n", toString(), elapsedMillis);
+        }
+    }
+
+    /**
+     * Runs all JSR166 unit tests using junit.textui.TestRunner.
+     */
+    // android-note: Removed because no junit.textui
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+
+    // static class PithyResultPrinter extends junit.textui.ResultPrinter {
+    //     PithyResultPrinter(java.io.PrintStream writer) { super(writer); }
+    //     long runTime;
+    //     public void startTest(Test test) {}
+    //     protected void printHeader(long runTime) {
+    //         this.runTime = runTime; // defer printing for later
+    //     }
+    //     protected void printFooter(TestResult result) {
+    //         if (result.wasSuccessful()) {
+    //             getWriter().println("OK (" + result.runCount() + " tests)"
+    //                 + "  Time: " + elapsedTimeAsString(runTime));
+    //         } else {
+    //             getWriter().println("Time: " + elapsedTimeAsString(runTime));
+    //             super.printFooter(result);
+    //         }
+    //     }
+    // }
+
+    /**
+     * Returns a TestRunner that doesn't bother with unnecessary
+     * fluff, like printing a "." for each test case.
+     */
+    // static junit.textui.TestRunner newPithyTestRunner() {
+    //     junit.textui.TestRunner runner = new junit.textui.TestRunner();
+    //     runner.setPrinter(new PithyResultPrinter(System.out));
+    //     return runner;
+    // }
+
+    /**
+     * Runs all unit tests in the given test suite.
+     * Actual behavior influenced by jsr166.* system properties.
+     */
+    // static void main(Test suite, String[] args) {
+    //     if (useSecurityManager) {
+    //         System.err.println("Setting a permissive security manager");
+    //         Policy.setPolicy(permissivePolicy());
+    //         System.setSecurityManager(new SecurityManager());
+    //     }
+    //     for (int i = 0; i < suiteRuns; i++) {
+    //         TestResult result = newPithyTestRunner().doRun(suite);
+    //         if (!result.wasSuccessful())
+    //             System.exit(1);
+    //         System.gc();
+    //         System.runFinalization();
+    //     }
+    // }
+
+    public static TestSuite newTestSuite(Object... suiteOrClasses) {
+        TestSuite suite = new TestSuite();
+        for (Object suiteOrClass : suiteOrClasses) {
+            if (suiteOrClass instanceof TestSuite)
+                suite.addTest((TestSuite) suiteOrClass);
+            else if (suiteOrClass instanceof Class)
+                suite.addTest(new TestSuite((Class<?>) suiteOrClass));
+            else
+                throw new ClassCastException("not a test suite or class");
+        }
+        return suite;
+    }
+
+    public static void addNamedTestClasses(TestSuite suite,
+                                           String... testClassNames) {
+        for (String testClassName : testClassNames) {
+            try {
+                Class<?> testClass = Class.forName(testClassName);
+                Method m = testClass.getDeclaredMethod("suite",
+                                                       new Class<?>[0]);
+                suite.addTest(newTestSuite((Test)m.invoke(null)));
+            } catch (Exception e) {
+                throw new Error("Missing test class", e);
+            }
+        }
+    }
+
+    public static final double JAVA_CLASS_VERSION;
+    public static final String JAVA_SPECIFICATION_VERSION;
+    static {
+        try {
+            JAVA_CLASS_VERSION = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<Double>() {
+                public Double run() {
+                    return Double.valueOf(System.getProperty("java.class.version"));}});
+            JAVA_SPECIFICATION_VERSION = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty("java.specification.version");}});
+        } catch (Throwable t) {
+            throw new Error(t);
+        }
+    }
+
+    public static boolean atLeastJava6() { return JAVA_CLASS_VERSION >= 50.0; }
+    public static boolean atLeastJava7() { return JAVA_CLASS_VERSION >= 51.0; }
+    public static boolean atLeastJava8() { return JAVA_CLASS_VERSION >= 52.0; }
+    public static boolean atLeastJava9() {
+        return JAVA_CLASS_VERSION >= 53.0
+            // As of 2015-09, java9 still uses 52.0 class file version
+            || JAVA_SPECIFICATION_VERSION.matches("^(1\\.)?(9|[0-9][0-9])$");
+    }
+    public static boolean atLeastJava10() {
+        return JAVA_CLASS_VERSION >= 54.0
+            || JAVA_SPECIFICATION_VERSION.matches("^(1\\.)?[0-9][0-9]$");
+    }
+
+    /**
+     * Collects all JSR166 unit tests as one suite.
+     */
+    // android-note: Removed because the CTS runner does a bad job of
+    // public static Test suite() {
+    //     // Java7+ test classes
+    //     TestSuite suite = newTestSuite(
+    //         ForkJoinPoolTest.suite(),
+    //         ForkJoinTaskTest.suite(),
+    //         RecursiveActionTest.suite(),
+    //         RecursiveTaskTest.suite(),
+    //         LinkedTransferQueueTest.suite(),
+    //         PhaserTest.suite(),
+    //         ThreadLocalRandomTest.suite(),
+    //         AbstractExecutorServiceTest.suite(),
+    //         AbstractQueueTest.suite(),
+    //         AbstractQueuedSynchronizerTest.suite(),
+    //         AbstractQueuedLongSynchronizerTest.suite(),
+    //         ArrayBlockingQueueTest.suite(),
+    //         ArrayDequeTest.suite(),
+    //         AtomicBooleanTest.suite(),
+    //         AtomicIntegerArrayTest.suite(),
+    //         AtomicIntegerFieldUpdaterTest.suite(),
+    //         AtomicIntegerTest.suite(),
+    //         AtomicLongArrayTest.suite(),
+    //         AtomicLongFieldUpdaterTest.suite(),
+    //         AtomicLongTest.suite(),
+    //         AtomicMarkableReferenceTest.suite(),
+    //         AtomicReferenceArrayTest.suite(),
+    //         AtomicReferenceFieldUpdaterTest.suite(),
+    //         AtomicReferenceTest.suite(),
+    //         AtomicStampedReferenceTest.suite(),
+    //         ConcurrentHashMapTest.suite(),
+    //         ConcurrentLinkedDequeTest.suite(),
+    //         ConcurrentLinkedQueueTest.suite(),
+    //         ConcurrentSkipListMapTest.suite(),
+    //         ConcurrentSkipListSubMapTest.suite(),
+    //         ConcurrentSkipListSetTest.suite(),
+    //         ConcurrentSkipListSubSetTest.suite(),
+    //         CopyOnWriteArrayListTest.suite(),
+    //         CopyOnWriteArraySetTest.suite(),
+    //         CountDownLatchTest.suite(),
+    //         CyclicBarrierTest.suite(),
+    //         DelayQueueTest.suite(),
+    //         EntryTest.suite(),
+    //         ExchangerTest.suite(),
+    //         ExecutorsTest.suite(),
+    //         ExecutorCompletionServiceTest.suite(),
+    //         FutureTaskTest.suite(),
+    //         LinkedBlockingDequeTest.suite(),
+    //         LinkedBlockingQueueTest.suite(),
+    //         LinkedListTest.suite(),
+    //         LockSupportTest.suite(),
+    //         PriorityBlockingQueueTest.suite(),
+    //         PriorityQueueTest.suite(),
+    //         ReentrantLockTest.suite(),
+    //         ReentrantReadWriteLockTest.suite(),
+    //         ScheduledExecutorTest.suite(),
+    //         ScheduledExecutorSubclassTest.suite(),
+    //         SemaphoreTest.suite(),
+    //         SynchronousQueueTest.suite(),
+    //         SystemTest.suite(),
+    //         ThreadLocalTest.suite(),
+    //         ThreadPoolExecutorTest.suite(),
+    //         ThreadPoolExecutorSubclassTest.suite(),
+    //         ThreadTest.suite(),
+    //         TimeUnitTest.suite(),
+    //         TreeMapTest.suite(),
+    //         TreeSetTest.suite(),
+    //         TreeSubMapTest.suite(),
+    //         TreeSubSetTest.suite());
+
+    //     // Java8+ test classes
+    //     if (atLeastJava8()) {
+    //         String[] java8TestClassNames = {
+    //             "Atomic8Test",
+    //             "CompletableFutureTest",
+    //             "ConcurrentHashMap8Test",
+    //             "CountedCompleterTest",
+    //             "DoubleAccumulatorTest",
+    //             "DoubleAdderTest",
+    //             "ForkJoinPool8Test",
+    //             "ForkJoinTask8Test",
+    //             "LongAccumulatorTest",
+    //             "LongAdderTest",
+    //             "SplittableRandomTest",
+    //             "StampedLockTest",
+    //             "SubmissionPublisherTest",
+    //             "ThreadLocalRandom8Test",
+    //         };
+    //         addNamedTestClasses(suite, java8TestClassNames);
+    //     }
+
+    //     // Java9+ test classes
+    //     if (atLeastJava9()) {
+    //         String[] java9TestClassNames = {
+    //             // Currently empty, but expecting varhandle tests
+    //         };
+    //         addNamedTestClasses(suite, java9TestClassNames);
+    //     }
+
+    //     return suite;
+    // }
+
+    /** Returns list of junit-style test method names in given class. */
+    public static ArrayList<String> testMethodNames(Class<?> testClass) {
+        Method[] methods = testClass.getDeclaredMethods();
+        ArrayList<String> names = new ArrayList<String>(methods.length);
+        for (Method method : methods) {
+            if (method.getName().startsWith("test")
+                && Modifier.isPublic(method.getModifiers())
+                // method.getParameterCount() requires jdk8+
+                && method.getParameterTypes().length == 0) {
+                names.add(method.getName());
+            }
+        }
+        return names;
+    }
+
+    /**
+     * Returns junit-style testSuite for the given test class, but
+     * parameterized by passing extra data to each test.
+     */
+    public static <ExtraData> Test parameterizedTestSuite
+        (Class<? extends JSR166TestCase> testClass,
+         Class<ExtraData> dataClass,
+         ExtraData data) {
+        try {
+            TestSuite suite = new TestSuite();
+            Constructor c =
+                testClass.getDeclaredConstructor(dataClass, String.class);
+            for (String methodName : testMethodNames(testClass))
+                suite.addTest((Test) c.newInstance(data, methodName));
+            return suite;
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+    }
+
+    /**
+     * Returns junit-style testSuite for the jdk8 extension of the
+     * given test class, but parameterized by passing extra data to
+     * each test.  Uses reflection to allow compilation in jdk7.
+     */
+    public static <ExtraData> Test jdk8ParameterizedTestSuite
+        (Class<? extends JSR166TestCase> testClass,
+         Class<ExtraData> dataClass,
+         ExtraData data) {
+        if (atLeastJava8()) {
+            String name = testClass.getName();
+            String name8 = name.replaceAll("Test$", "8Test");
+            if (name.equals(name8)) throw new Error(name);
+            try {
+                return (Test)
+                    Class.forName(name8)
+                    .getMethod("testSuite", new Class[] { dataClass })
+                    .invoke(null, data);
+            } catch (Exception e) {
+                throw new Error(e);
+            }
+        } else {
+            return new TestSuite();
+        }
+    }
+
+    // Delays for timing-dependent tests, in milliseconds.
 
     public static long SHORT_DELAY_MS;
     public static long SMALL_DELAY_MS;
@@ -136,11 +575,13 @@
     public static long LONG_DELAY_MS;
 
     /**
-     * Returns the shortest timed delay. This could
-     * be reimplemented to use for example a Property.
+     * Returns the shortest timed delay. This can be scaled up for
+     * slow machines using the jsr166.delay.factor system property,
+     * or via jtreg's -timeoutFactor: flag.
+     * http://openjdk.java.net/jtreg/command-help.html
      */
     protected long getShortDelay() {
-        return 50;
+        return (long) (50 * delayFactor * jtregTestTimeoutFactor);
     }
 
     /**
@@ -162,11 +603,12 @@
     }
 
     /**
-     * Returns a new Date instance representing a time delayMillis
-     * milliseconds in the future.
+     * Returns a new Date instance representing a time at least
+     * delayMillis milliseconds in the future.
      */
     Date delayedDate(long delayMillis) {
-        return new Date(System.currentTimeMillis() + delayMillis);
+        // Add 1 because currentTimeMillis is known to round into the past.
+        return new Date(System.currentTimeMillis() + delayMillis + 1);
     }
 
     /**
@@ -182,6 +624,8 @@
      * the same test have no effect.
      */
     public void threadRecordFailure(Throwable t) {
+        System.err.println(t);
+        dumpTestThreads();
         threadFailure.compareAndSet(null, t);
     }
 
@@ -189,6 +633,13 @@
         setDelays();
     }
 
+    void tearDownFail(String format, Object... args) {
+        String msg = toString() + ": " + String.format(format, args);
+        System.err.println(msg);
+        dumpTestThreads();
+        throw new AssertionFailedError(msg);
+    }
+
     /**
      * Extra checks that get done for all test cases.
      *
@@ -216,16 +667,16 @@
         }
 
         if (Thread.interrupted())
-            throw new AssertionFailedError("interrupt status set in main thread");
+            tearDownFail("interrupt status set in main thread");
 
         checkForkJoinPoolThreadLeaks();
     }
 
     /**
-     * Finds missing try { ... } finally { joinPool(e); }
+     * Finds missing PoolCleaners
      */
     void checkForkJoinPoolThreadLeaks() throws InterruptedException {
-        Thread[] survivors = new Thread[5];
+        Thread[] survivors = new Thread[7];
         int count = Thread.enumerate(survivors);
         for (int i = 0; i < count; i++) {
             Thread thread = survivors[i];
@@ -233,13 +684,15 @@
             if (name.startsWith("ForkJoinPool-")) {
                 // give thread some time to terminate
                 thread.join(LONG_DELAY_MS);
-                if (!thread.isAlive()) continue;
-                thread.stop();
-                throw new AssertionFailedError
-                    (String.format("Found leaked ForkJoinPool thread test=%s thread=%s%n",
-                                   toString(), name));
+                if (thread.isAlive())
+                    tearDownFail("Found leaked ForkJoinPool thread thread=%s",
+                                 thread);
             }
         }
+
+        if (!ForkJoinPool.commonPool()
+            .awaitQuiescence(LONG_DELAY_MS, MILLISECONDS))
+            tearDownFail("ForkJoin common pool thread stuck");
     }
 
     /**
@@ -252,7 +705,7 @@
             fail(reason);
         } catch (AssertionFailedError t) {
             threadRecordFailure(t);
-            fail(reason);
+            throw t;
         }
     }
 
@@ -379,44 +832,148 @@
     /**
      * Delays, via Thread.sleep, for the given millisecond delay, but
      * if the sleep is shorter than specified, may re-sleep or yield
-     * until time elapses.
+     * until time elapses.  Ensures that the given time, as measured
+     * by System.nanoTime(), has elapsed.
      */
     static void delay(long millis) throws InterruptedException {
-        long startTime = System.nanoTime();
-        long ns = millis * 1000 * 1000;
-        for (;;) {
+        long nanos = millis * (1000 * 1000);
+        final long wakeupTime = System.nanoTime() + nanos;
+        do {
             if (millis > 0L)
                 Thread.sleep(millis);
             else // too short to sleep
                 Thread.yield();
-            long d = ns - (System.nanoTime() - startTime);
-            if (d > 0L)
-                millis = d / (1000 * 1000);
-            else
-                break;
+            nanos = wakeupTime - System.nanoTime();
+            millis = nanos / (1000 * 1000);
+        } while (nanos >= 0L);
+    }
+
+    /**
+     * Allows use of try-with-resources with per-test thread pools.
+     */
+    class PoolCleaner implements AutoCloseable {
+        private final ExecutorService pool;
+        public PoolCleaner(ExecutorService pool) { this.pool = pool; }
+        public void close() { joinPool(pool); }
+    }
+
+    /**
+     * An extension of PoolCleaner that has an action to release the pool.
+     */
+    class PoolCleanerWithReleaser extends PoolCleaner {
+        private final Runnable releaser;
+        public PoolCleanerWithReleaser(ExecutorService pool, Runnable releaser) {
+            super(pool);
+            this.releaser = releaser;
         }
+        public void close() {
+            try {
+                releaser.run();
+            } finally {
+                super.close();
+            }
+        }
+    }
+
+    PoolCleaner cleaner(ExecutorService pool) {
+        return new PoolCleaner(pool);
+    }
+
+    PoolCleaner cleaner(ExecutorService pool, Runnable releaser) {
+        return new PoolCleanerWithReleaser(pool, releaser);
+    }
+
+    PoolCleaner cleaner(ExecutorService pool, CountDownLatch latch) {
+        return new PoolCleanerWithReleaser(pool, releaser(latch));
+    }
+
+    Runnable releaser(final CountDownLatch latch) {
+        return new Runnable() { public void run() {
+            do { latch.countDown(); }
+            while (latch.getCount() > 0);
+        }};
+    }
+
+    PoolCleaner cleaner(ExecutorService pool, AtomicBoolean flag) {
+        return new PoolCleanerWithReleaser(pool, releaser(flag));
+    }
+
+    Runnable releaser(final AtomicBoolean flag) {
+        return new Runnable() { public void run() { flag.set(true); }};
     }
 
     /**
      * Waits out termination of a thread pool or fails doing so.
      */
-    void joinPool(ExecutorService exec) {
+    void joinPool(ExecutorService pool) {
         try {
-            exec.shutdown();
-            if (!exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS))
-                fail("ExecutorService " + exec +
-                     " did not terminate in a timely manner");
+            pool.shutdown();
+            if (!pool.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) {
+                try {
+                    threadFail("ExecutorService " + pool +
+                               " did not terminate in a timely manner");
+                } finally {
+                    // last resort, for the benefit of subsequent tests
+                    pool.shutdownNow();
+                    pool.awaitTermination(MEDIUM_DELAY_MS, MILLISECONDS);
+                }
+            }
         } catch (SecurityException ok) {
             // Allowed in case test doesn't have privs
         } catch (InterruptedException fail) {
-            fail("Unexpected InterruptedException");
+            threadFail("Unexpected InterruptedException");
+        }
+    }
+
+    /** Like Runnable, but with the freedom to throw anything */
+    interface Action { public void run() throws Throwable; }
+
+    /**
+     * Runs all the given actions in parallel, failing if any fail.
+     * Useful for running multiple variants of tests that are
+     * necessarily individually slow because they must block.
+     */
+    void testInParallel(Action ... actions) {
+        ExecutorService pool = Executors.newCachedThreadPool();
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            ArrayList<Future<?>> futures = new ArrayList<>(actions.length);
+            for (final Action action : actions)
+                futures.add(pool.submit(new CheckedRunnable() {
+                    public void realRun() throws Throwable { action.run();}}));
+            for (Future<?> future : futures)
+                try {
+                    assertNull(future.get(LONG_DELAY_MS, MILLISECONDS));
+                } catch (ExecutionException ex) {
+                    threadUnexpectedException(ex.getCause());
+                } catch (Exception ex) {
+                    threadUnexpectedException(ex);
+                }
         }
     }
 
     /**
-     * A debugging tool to print all stack traces, as jstack does.
+     * A debugging tool to print stack traces of most threads, as jstack does.
+     * Uninteresting threads are filtered out.
      */
-    static void printAllStackTraces() {
+    static void dumpTestThreads() {
+        // Android-change no ThreadMXBean
+        // ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+        // System.err.println("------ stacktrace dump start ------");
+        // for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
+        //     String name = info.getThreadName();
+        //     if ("Signal Dispatcher".equals(name))
+        //         continue;
+        //     if ("Reference Handler".equals(name)
+        //         && info.getLockName().startsWith("java.lang.ref.Reference$Lock"))
+        //         continue;
+        //     if ("Finalizer".equals(name)
+        //         && info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock"))
+        //         continue;
+        //     if ("checkForWedgedTest".equals(name))
+        //         continue;
+        //     System.err.print(info);
+        // }
+        // System.err.println("------ stacktrace dump end ------");
     }
 
     /**
@@ -436,7 +993,7 @@
             delay(millis);
             assertTrue(thread.isAlive());
         } catch (InterruptedException fail) {
-            fail("Unexpected InterruptedException");
+            threadFail("Unexpected InterruptedException");
         }
     }
 
@@ -458,7 +1015,7 @@
             for (Thread thread : threads)
                 assertTrue(thread.isAlive());
         } catch (InterruptedException fail) {
-            fail("Unexpected InterruptedException");
+            threadFail("Unexpected InterruptedException");
         }
     }
 
@@ -532,6 +1089,12 @@
      * getPolicy/setPolicy.
      */
     public void runWithPermissions(Runnable r, Permission... permissions) {
+        // Android-changed - no SecurityManager
+        // SecurityManager sm = System.getSecurityManager();
+        // if (sm == null) {
+        //     r.run();
+        // }
+        // runWithSecurityManagerWithPermissions(r, permissions);
         r.run();
     }
 
@@ -544,6 +1107,30 @@
      */
     public void runWithSecurityManagerWithPermissions(Runnable r,
                                                       Permission... permissions) {
+        // Android-changed - no SecurityManager
+        // SecurityManager sm = System.getSecurityManager();
+        // if (sm == null) {
+        //     Policy savedPolicy = Policy.getPolicy();
+        //     try {
+        //         Policy.setPolicy(permissivePolicy());
+        //         System.setSecurityManager(new SecurityManager());
+        //         runWithSecurityManagerWithPermissions(r, permissions);
+        //     } finally {
+        //         System.setSecurityManager(null);
+        //         Policy.setPolicy(savedPolicy);
+        //     }
+        // } else {
+        //     Policy savedPolicy = Policy.getPolicy();
+        //     AdjustablePolicy policy = new AdjustablePolicy(permissions);
+        //     Policy.setPolicy(policy);
+
+        //     try {
+        //         r.run();
+        //     } finally {
+        //         policy.addPermission(new SecurityPermission("setPolicy"));
+        //         Policy.setPolicy(savedPolicy);
+        //     }
+        // }
         r.run();
     }
 
@@ -648,19 +1235,6 @@
         waitForThreadToEnterWaitState(thread, LONG_DELAY_MS);
     }
 
-    void waitForThreadToEnterWaitStateNoTimeout(Thread thread) {
-        for (;;) {
-            Thread.State s = thread.getState();
-            if (s == Thread.State.BLOCKED ||
-                s == Thread.State.WAITING ||
-                s == Thread.State.TIMED_WAITING)
-                return;
-            else if (s == Thread.State.TERMINATED)
-                fail("Unexpected thread termination");
-            Thread.yield();
-        }
-    }
-
     /**
      * Returns the number of milliseconds since time given by
      * startNanoTime, which must have been previously returned from a
@@ -723,7 +1297,7 @@
         } finally {
             if (t.getState() != Thread.State.TERMINATED) {
                 t.interrupt();
-                fail("Test timed out");
+                threadFail("timed out waiting for thread to terminate");
             }
         }
     }
@@ -848,7 +1422,10 @@
     public static final String TEST_STRING = "a test string";
 
     public static class StringTask implements Callable<String> {
-        public String call() { return TEST_STRING; }
+        final String value;
+        public StringTask() { this(TEST_STRING); }
+        public StringTask(String value) { this.value = value; }
+        public String call() { return value; }
     }
 
     public Callable<String> latchAwaitingStringTask(final CountDownLatch latch) {
@@ -861,24 +1438,50 @@
             }};
     }
 
-    public Runnable awaiter(final CountDownLatch latch) {
+    public Runnable countDowner(final CountDownLatch latch) {
         return new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                await(latch);
+                latch.countDown();
             }};
     }
 
-    public void await(CountDownLatch latch) {
+    class LatchAwaiter extends CheckedRunnable {
+        static final int NEW = 0;
+        static final int RUNNING = 1;
+        static final int DONE = 2;
+        final CountDownLatch latch;
+        int state = NEW;
+        LatchAwaiter(CountDownLatch latch) { this.latch = latch; }
+        public void realRun() throws InterruptedException {
+            state = 1;
+            await(latch);
+            state = 2;
+        }
+    }
+
+    public LatchAwaiter awaiter(CountDownLatch latch) {
+        return new LatchAwaiter(latch);
+    }
+
+    public void await(CountDownLatch latch, long timeoutMillis) {
         try {
-            assertTrue(latch.await(LONG_DELAY_MS, MILLISECONDS));
+            if (!latch.await(timeoutMillis, MILLISECONDS))
+                fail("timed out waiting for CountDownLatch for "
+                     + (timeoutMillis/1000) + " sec");
         } catch (Throwable fail) {
             threadUnexpectedException(fail);
         }
     }
 
+    public void await(CountDownLatch latch) {
+        await(latch, LONG_DELAY_MS);
+    }
+
     public void await(Semaphore semaphore) {
         try {
-            assertTrue(semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS));
+            if (!semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS))
+                fail("timed out waiting for Semaphore for "
+                     + (LONG_DELAY_MS/1000) + " sec");
         } catch (Throwable fail) {
             threadUnexpectedException(fail);
         }
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java
index 62802bb..789373d 100644
--- a/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java
+++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingDequeTest.java
@@ -26,25 +26,24 @@
 
 public class LinkedBlockingDequeTest extends JSR166TestCase {
 
-    // android-note: These tests have been moved into their own separate
-    // classes to work around CTS issues.
-    //
-    // public static class Unbounded extends BlockingQueueTest {
-    //     protected BlockingQueue emptyCollection() {
-    //         return new LinkedBlockingDeque();
-    //     }
-    // }
-    //
-    // public static class Bounded extends BlockingQueueTest {
-    //     protected BlockingQueue emptyCollection() {
-    //         return new LinkedBlockingDeque(SIZE);
-    //     }
-    // }
+    public static class Unbounded extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new LinkedBlockingDeque();
+        }
+    }
+
+    public static class Bounded extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new LinkedBlockingDeque(SIZE);
+        }
+    }
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
     //
     // public static void main(String[] args) {
     //     main(suite(), args);
     // }
-    //
     // public static Test suite() {
     //     return newTestSuite(LinkedBlockingDequeTest.class,
     //                         new Unbounded().testSuite(),
@@ -87,7 +86,7 @@
     public void testSize() {
         LinkedBlockingDeque q = populatedDeque(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.removeFirst();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -152,7 +151,7 @@
      */
     public void testPollLast() {
         LinkedBlockingDeque q = populatedDeque(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.pollLast());
         }
         assertNull(q.pollLast());
@@ -191,7 +190,7 @@
      */
     public void testPeekLast() {
         LinkedBlockingDeque q = populatedDeque(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.peekLast());
             assertEquals(i, q.pollLast());
             assertTrue(q.peekLast() == null ||
@@ -221,7 +220,7 @@
      */
     public void testLastElement() {
         LinkedBlockingDeque q = populatedDeque(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.getLast());
             assertEquals(i, q.pollLast());
         }
@@ -286,7 +285,7 @@
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.removeFirstOccurrence(new Integer(i)));
-            assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+            assertFalse(q.removeFirstOccurrence(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
@@ -301,7 +300,7 @@
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.removeLastOccurrence(new Integer(i)));
-            assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+            assertFalse(q.removeLastOccurrence(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
@@ -372,7 +371,7 @@
      */
     public void testConstructor5() {
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = i;
         Collection<Integer> elements = Arrays.asList(ints);
         try {
@@ -419,7 +418,7 @@
             assertEquals(i, q.remove());
         }
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.remainingCapacity());
+            assertEquals(SIZE - i, q.remainingCapacity());
             assertEquals(SIZE, q.size() + q.remainingCapacity());
             assertTrue(q.add(i));
         }
@@ -429,8 +428,8 @@
      * push(null) throws NPE
      */
     public void testPushNull() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(1);
         try {
-            LinkedBlockingDeque q = new LinkedBlockingDeque(1);
             q.push(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -440,14 +439,14 @@
      * push succeeds if not full; throws ISE if full
      */
     public void testPush() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer x = new Integer(i);
+            q.push(x);
+            assertEquals(x, q.peek());
+        }
+        assertEquals(0, q.remainingCapacity());
         try {
-            LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                Integer x = new Integer(i);
-                q.push(x);
-                assertEquals(x, q.peek());
-            }
-            assertEquals(0, q.remainingCapacity());
             q.push(new Integer(SIZE));
             shouldThrow();
         } catch (IllegalStateException success) {}
@@ -518,7 +517,7 @@
     public void testAddAll3() {
         LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         Collection<Integer> elements = Arrays.asList(ints);
         try {
@@ -756,25 +755,23 @@
         final CountDownLatch aboutToWait = new CountDownLatch(1);
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
                 for (int i = 0; i < SIZE; ++i) {
-                    long t0 = System.nanoTime();
                     assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
-                    assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
                 }
-                long t0 = System.nanoTime();
                 aboutToWait.countDown();
                 try {
-                    q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
                     shouldThrow();
                 } catch (InterruptedException success) {
-                    assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
                 }
             }});
 
         aboutToWait.await();
-        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+        waitForThreadToEnterWaitState(t, LONG_DELAY_MS);
         t.interrupt();
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
         checkEmpty(q);
     }
 
@@ -1055,17 +1052,18 @@
      * returning timeout status
      */
     public void testInterruptedTimedPollFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                LinkedBlockingDeque q = populatedDeque(SIZE);
+                long startTime = System.nanoTime();
                 for (int i = 0; i < SIZE; ++i) {
                     assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
                 }
 
                 Thread.currentThread().interrupt();
                 try {
-                    q.pollFirst(SMALL_DELAY_MS, MILLISECONDS);
+                    q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
                     shouldThrow();
                 } catch (InterruptedException success) {}
                 assertFalse(Thread.interrupted());
@@ -1076,6 +1074,7 @@
                     shouldThrow();
                 } catch (InterruptedException success) {}
                 assertFalse(Thread.interrupted());
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
         await(pleaseInterrupt);
@@ -1251,7 +1250,7 @@
     public void testTakeLast() throws InterruptedException {
         LinkedBlockingDeque q = populatedDeque(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i-1, q.takeLast());
+            assertEquals(SIZE - i - 1, q.takeLast());
         }
     }
 
@@ -1264,7 +1263,7 @@
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
                 for (int i = 0; i < SIZE; ++i) {
-                    assertEquals(SIZE-i-1, q.takeLast());
+                    assertEquals(SIZE - i - 1, q.takeLast());
                 }
 
                 Thread.currentThread().interrupt();
@@ -1294,7 +1293,7 @@
     public void testTimedPollLast0() throws InterruptedException {
         LinkedBlockingDeque q = populatedDeque(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i-1, q.pollLast(0, MILLISECONDS));
+            assertEquals(SIZE - i - 1, q.pollLast(0, MILLISECONDS));
         }
         assertNull(q.pollLast(0, MILLISECONDS));
     }
@@ -1306,7 +1305,7 @@
         LinkedBlockingDeque q = populatedDeque(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             long startTime = System.nanoTime();
-            assertEquals(SIZE-i-1, q.pollLast(LONG_DELAY_MS, MILLISECONDS));
+            assertEquals(SIZE - i - 1, q.pollLast(LONG_DELAY_MS, MILLISECONDS));
             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
         long startTime = System.nanoTime();
@@ -1320,12 +1319,14 @@
      * returning timeout status
      */
     public void testInterruptedTimedPollLast() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                LinkedBlockingDeque q = populatedDeque(SIZE);
+                long startTime = System.nanoTime();
                 for (int i = 0; i < SIZE; ++i) {
-                    assertEquals(SIZE-i-1, q.pollLast(LONG_DELAY_MS, MILLISECONDS));
+                    assertEquals(SIZE - i - 1,
+                                 q.pollLast(LONG_DELAY_MS, MILLISECONDS));
                 }
 
                 Thread.currentThread().interrupt();
@@ -1341,12 +1342,15 @@
                     shouldThrow();
                 } catch (InterruptedException success) {}
                 assertFalse(Thread.interrupted());
+
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
         await(pleaseInterrupt);
         assertThreadStaysAlive(t);
         t.interrupt();
         awaitTermination(t);
+        checkEmpty(q);
     }
 
     /**
@@ -1379,6 +1383,8 @@
                     shouldThrow();
                 } catch (InterruptedException success) {}
                 assertFalse(Thread.interrupted());
+
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
         barrier.await();
@@ -1463,7 +1469,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.remove();
         }
     }
@@ -1476,7 +1482,7 @@
             LinkedBlockingDeque q = populatedDeque(SIZE);
             LinkedBlockingDeque p = populatedDeque(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.remove());
                 assertFalse(q.contains(x));
@@ -1675,23 +1681,23 @@
         final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
         q.add(one);
         q.add(two);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertFalse(q.offer(three));
-                threadsStarted.await();
-                assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
-                assertEquals(0, q.remainingCapacity());
-            }});
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(q.offer(three));
+                    threadsStarted.await();
+                    assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
+                    assertEquals(0, q.remainingCapacity());
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                assertSame(one, q.take());
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertSame(one, q.take());
+                }});
+        }
     }
 
     /**
@@ -1700,22 +1706,22 @@
     public void testPollInExecutor() {
         final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertNull(q.poll());
-                threadsStarted.await();
-                assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
-                checkEmpty(q);
-            }});
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                q.put(one);
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
     }
 
     /**
@@ -1767,7 +1773,7 @@
         final LinkedBlockingDeque q = populatedDeque(SIZE);
         Thread t = new Thread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                q.put(new Integer(SIZE+1));
+                q.put(new Integer(SIZE + 1));
             }});
 
         t.start();
@@ -1792,7 +1798,7 @@
             q.drainTo(l, i);
             int k = (i < SIZE) ? i : SIZE;
             assertEquals(k, l.size());
-            assertEquals(SIZE-k, q.size());
+            assertEquals(SIZE - k, q.size());
             for (int j = 0; j < k; ++j)
                 assertEquals(l.get(j), new Integer(j));
             do {} while (q.poll() != null);
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java
index bd37b2a..faf3f18 100644
--- a/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/LinkedBlockingQueueTest.java
@@ -26,25 +26,27 @@
 
 public class LinkedBlockingQueueTest extends JSR166TestCase {
 
-    // android-note: These tests have been moved into their own separate 
+    // android-note: These tests have been moved into their own separate
     // classes to work around CTS issues.
     //
     // public static class Unbounded extends BlockingQueueTest {
-    //    protected BlockingQueue emptyCollection() {
-    //        return new LinkedBlockingQueue();
+    //     protected BlockingQueue emptyCollection() {
+    //         return new LinkedBlockingQueue();
     //     }
     // }
-    //
+
     // public static class Bounded extends BlockingQueueTest {
-    //    protected BlockingQueue emptyCollection() {
+    //     protected BlockingQueue emptyCollection() {
     //         return new LinkedBlockingQueue(SIZE);
     //     }
     // }
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
     //
     // public static void main(String[] args) {
-    //    main(suite(), args);
+    //     main(suite(), args);
     // }
-    //
     // public static Test suite() {
     //     return newTestSuite(LinkedBlockingQueueTest.class,
     //                         new Unbounded().testSuite(),
@@ -113,7 +115,7 @@
      */
     public void testConstructor5() {
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         Collection<Integer> elements = Arrays.asList(ints);
         try {
@@ -160,7 +162,7 @@
             assertEquals(i, q.remove());
         }
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.remainingCapacity());
+            assertEquals(SIZE - i, q.remainingCapacity());
             assertEquals(SIZE, q.size() + q.remainingCapacity());
             assertTrue(q.add(i));
         }
@@ -207,7 +209,7 @@
     public void testAddAll3() {
         LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         Collection<Integer> elements = Arrays.asList(ints);
         try {
@@ -445,25 +447,23 @@
         final CountDownLatch aboutToWait = new CountDownLatch(1);
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
                 for (int i = 0; i < SIZE; ++i) {
-                    long t0 = System.nanoTime();
                     assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
-                    assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
                 }
-                long t0 = System.nanoTime();
                 aboutToWait.countDown();
                 try {
-                    q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
                     shouldThrow();
                 } catch (InterruptedException success) {
-                    assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
                 }
             }});
 
-        aboutToWait.await();
-        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+        await(aboutToWait);
+        waitForThreadToEnterWaitState(t, LONG_DELAY_MS);
         t.interrupt();
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
         checkEmpty(q);
     }
 
@@ -579,7 +579,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.remove();
         }
     }
@@ -592,7 +592,7 @@
             LinkedBlockingQueue q = populatedQueue(SIZE);
             LinkedBlockingQueue p = populatedQueue(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.remove());
                 assertFalse(q.contains(x));
@@ -727,23 +727,23 @@
         final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
         q.add(one);
         q.add(two);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertFalse(q.offer(three));
-                threadsStarted.await();
-                assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
-                assertEquals(0, q.remainingCapacity());
-            }});
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(q.offer(three));
+                    threadsStarted.await();
+                    assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
+                    assertEquals(0, q.remainingCapacity());
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                assertSame(one, q.take());
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertSame(one, q.take());
+                }});
+        }
     }
 
     /**
@@ -752,22 +752,22 @@
     public void testPollInExecutor() {
         final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertNull(q.poll());
-                threadsStarted.await();
-                assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
-                checkEmpty(q);
-            }});
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                q.put(one);
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
     }
 
     /**
@@ -819,7 +819,7 @@
         final LinkedBlockingQueue q = populatedQueue(SIZE);
         Thread t = new Thread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                q.put(new Integer(SIZE+1));
+                q.put(new Integer(SIZE + 1));
             }});
 
         t.start();
@@ -844,7 +844,7 @@
             q.drainTo(l, i);
             int k = (i < SIZE) ? i : SIZE;
             assertEquals(k, l.size());
-            assertEquals(SIZE-k, q.size());
+            assertEquals(SIZE - k, q.size());
             for (int j = 0; j < k; ++j)
                 assertEquals(l.get(j), new Integer(j));
             do {} while (q.poll() != null);
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedListTest.java b/jsr166-tests/src/test/java/jsr166/LinkedListTest.java
index 9d9481d..9c971b4 100644
--- a/jsr166-tests/src/test/java/jsr166/LinkedListTest.java
+++ b/jsr166-tests/src/test/java/jsr166/LinkedListTest.java
@@ -25,7 +25,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(LinkedListTest.class);
     // }
 
     /**
@@ -91,7 +91,7 @@
     public void testSize() {
         LinkedList q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.remove();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -106,6 +106,8 @@
     public void testOfferNull() {
         LinkedList q = new LinkedList();
         q.offer(null);
+        assertNull(q.get(0));
+        assertTrue(q.contains(null));
     }
 
     /**
@@ -132,8 +134,8 @@
      * addAll(null) throws NPE
      */
     public void testAddAll1() {
+        LinkedList q = new LinkedList();
         try {
-            LinkedList q = new LinkedList();
             q.addAll(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -245,14 +247,14 @@
             assertTrue(q.contains(i));
             assertTrue(q.remove((Integer)i));
             assertFalse(q.contains(i));
-            assertTrue(q.contains(i-1));
+            assertTrue(q.contains(i - 1));
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.contains(i));
             assertTrue(q.remove((Integer)i));
             assertFalse(q.contains(i));
-            assertFalse(q.remove((Integer)(i+1)));
-            assertFalse(q.contains(i+1));
+            assertFalse(q.remove((Integer)(i + 1)));
+            assertFalse(q.contains(i + 1));
         }
         assertTrue(q.isEmpty());
     }
@@ -311,7 +313,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.remove();
         }
     }
@@ -324,7 +326,7 @@
             LinkedList q = populatedQueue(SIZE);
             LinkedList p = populatedQueue(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.remove());
                 assertFalse(q.contains(x));
@@ -549,7 +551,7 @@
      */
     public void testPollLast() {
         LinkedList q = populatedQueue(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.pollLast());
         }
         assertNull(q.pollLast());
@@ -574,7 +576,7 @@
      */
     public void testPeekLast() {
         LinkedList q = populatedQueue(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.peekLast());
             assertEquals(i, q.pollLast());
             assertTrue(q.peekLast() == null ||
@@ -600,7 +602,7 @@
      */
     public void testLastElement() {
         LinkedList q = populatedQueue(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.getLast());
             assertEquals(i, q.pollLast());
         }
@@ -621,7 +623,7 @@
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.removeFirstOccurrence(new Integer(i)));
-            assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+            assertFalse(q.removeFirstOccurrence(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
@@ -636,7 +638,7 @@
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.removeLastOccurrence(new Integer(i)));
-            assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+            assertFalse(q.removeLastOccurrence(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
diff --git a/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java b/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java
index 8d3f276..c712592 100644
--- a/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java
@@ -25,30 +25,33 @@
 import junit.framework.Test;
 
 @SuppressWarnings({"unchecked", "rawtypes"})
-// android-changed: Extend BlockingQueueTest directly.
-public class LinkedTransferQueueTest extends BlockingQueueTest {
+public class LinkedTransferQueueTest extends JSR166TestCase {
+    static class Implementation implements CollectionImplementation {
+        public Class<?> klazz() { return LinkedTransferQueue.class; }
+        public Collection emptyCollection() { return new LinkedTransferQueue(); }
+        public Object makeElement(int i) { return i; }
+        public boolean isConcurrent() { return true; }
+        public boolean permitsNulls() { return false; }
+    }
 
-    // android-changed: Extend BlockingQueueTest directly.
-    //
-    // public static class Generic extends BlockingQueueTest {
-    //     protected BlockingQueue emptyCollection() {
-    //         return new LinkedTransferQueue();
-    //     }
-    // }
+    public static class Generic extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new LinkedTransferQueue();
+        }
+    }
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
     //
     // public static void main(String[] args) {
     //     main(suite(), args);
     // }
-    //
     // public static Test suite() {
     //     return newTestSuite(LinkedTransferQueueTest.class,
-    //                         new Generic().testSuite());
+    //                         new Generic().testSuite(),
+    //                         CollectionTest.testSuite(new Implementation()));
     // }
 
-    protected BlockingQueue emptyCollection() {
-        return new LinkedTransferQueue();
-    }
-
     /**
      * Constructor builds new queue with size being zero and empty
      * being true
@@ -87,7 +90,7 @@
      */
     public void testConstructor4() {
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = i;
         Collection<Integer> elements = Arrays.asList(ints);
         try {
@@ -141,8 +144,8 @@
      * addAll(this) throws IllegalArgumentException
      */
     public void testAddAllSelf() {
+        LinkedTransferQueue q = populatedQueue(SIZE);
         try {
-            LinkedTransferQueue q = populatedQueue(SIZE);
             q.addAll(q);
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -153,12 +156,11 @@
      * NullPointerException after possibly adding some elements
      */
     public void testAddAll3() {
+        LinkedTransferQueue q = new LinkedTransferQueue();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = i;
         try {
-            LinkedTransferQueue q = new LinkedTransferQueue();
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE - 1; ++i) {
-                ints[i] = i;
-            }
             q.addAll(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -265,12 +267,12 @@
      */
     public void testTimedPoll() throws InterruptedException {
         LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
-        for (int i = 0; i < SIZE; ++i) {
-            long startTime = System.nanoTime();
-            assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
-            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
-        }
         long startTime = System.nanoTime();
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+
+        startTime = System.nanoTime();
         assertNull(q.poll(timeoutMillis(), MILLISECONDS));
         assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
         checkEmpty(q);
@@ -285,25 +287,21 @@
         final CountDownLatch aboutToWait = new CountDownLatch(1);
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                for (int i = 0; i < SIZE; ++i) {
-                    long t0 = System.nanoTime();
+                long startTime = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i)
                     assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
-                    assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
-                }
-                long t0 = System.nanoTime();
                 aboutToWait.countDown();
                 try {
-                    q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
                     shouldThrow();
-                } catch (InterruptedException success) {
-                    assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
-                }
+                } catch (InterruptedException success) {}
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
         aboutToWait.await();
-        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+        waitForThreadToEnterWaitState(t);
         t.interrupt();
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
         checkEmpty(q);
     }
 
@@ -315,19 +313,18 @@
         final BlockingQueue<Integer> q = populatedQueue(SIZE);
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
                 Thread.currentThread().interrupt();
-                for (int i = 0; i < SIZE; ++i) {
-                    long t0 = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i)
                     assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
-                    assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
-                }
                 try {
-                    q.poll(MEDIUM_DELAY_MS, MILLISECONDS);
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
                     shouldThrow();
                 } catch (InterruptedException success) {}
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
         checkEmpty(q);
     }
 
@@ -598,22 +595,24 @@
     public void testOfferInExecutor() {
         final LinkedTransferQueue q = new LinkedTransferQueue();
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
-            }});
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    long startTime = System.nanoTime();
+                    assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                assertSame(one, q.take());
-                checkEmpty(q);
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertSame(one, q.take());
+                    checkEmpty(q);
+                }});
+        }
     }
 
     /**
@@ -622,23 +621,25 @@
     public void testPollInExecutor() {
         final LinkedTransferQueue q = new LinkedTransferQueue();
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertNull(q.poll());
-                threadsStarted.await();
-                assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
-                checkEmpty(q);
-            }});
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    long startTime = System.nanoTime();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                    checkEmpty(q);
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                q.put(one);
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
     }
 
     /**
@@ -699,7 +700,7 @@
         assertTrue(l.size() >= SIZE);
         for (int i = 0; i < SIZE; ++i)
             assertEquals(i, l.get(i));
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
         assertTrue(q.size() + l.size() >= SIZE);
     }
 
@@ -736,14 +737,15 @@
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
                 threadStarted.countDown();
+                long startTime = System.nanoTime();
                 assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
                 assertEquals(0, q.getWaitingConsumerCount());
                 assertFalse(q.hasWaitingConsumer());
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
         threadStarted.await();
-        // waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
-        waitForThreadToEnterWaitStateNoTimeout(t);
+        waitForThreadToEnterWaitState(t);
         assertEquals(1, q.getWaitingConsumerCount());
         assertTrue(q.hasWaitingConsumer());
 
@@ -751,7 +753,7 @@
         assertEquals(0, q.getWaitingConsumerCount());
         assertFalse(q.hasWaitingConsumer());
 
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
     }
 
     /**
@@ -782,12 +784,11 @@
             }});
 
         threadStarted.await();
-        // waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
-        waitForThreadToEnterWaitStateNoTimeout(t);
+        waitForThreadToEnterWaitState(t);
         assertEquals(1, q.size());
         assertSame(five, q.poll());
         checkEmpty(q);
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
     }
 
     /**
@@ -843,7 +844,7 @@
         assertEquals(1, q.size());
         assertTrue(q.offer(three));
         assertSame(four, q.poll());
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
     }
 
     /**
@@ -866,15 +867,15 @@
         assertEquals(1, q.size());
         assertSame(four, q.take());
         checkEmpty(q);
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
     }
 
     /**
      * tryTransfer(null) throws NullPointerException
      */
     public void testTryTransfer1() {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
         try {
-            final LinkedTransferQueue q = new LinkedTransferQueue();
             q.tryTransfer(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -908,9 +909,11 @@
                 assertTrue(q.tryTransfer(hotPotato));
             }});
 
-        assertSame(hotPotato, q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
+        long startTime = System.nanoTime();
+        assertSame(hotPotato, q.poll(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         checkEmpty(q);
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
     }
 
     /**
@@ -932,7 +935,7 @@
 
         assertSame(q.take(), hotPotato);
         checkEmpty(q);
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
     }
 
     /**
@@ -945,6 +948,7 @@
 
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
                 Thread.currentThread().interrupt();
                 try {
                     q.tryTransfer(new Object(), LONG_DELAY_MS, MILLISECONDS);
@@ -958,6 +962,7 @@
                     shouldThrow();
                 } catch (InterruptedException success) {}
                 assertFalse(Thread.interrupted());
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
         await(pleaseInterrupt);
@@ -975,10 +980,10 @@
 
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                long t0 = System.nanoTime();
+                long startTime = System.nanoTime();
                 assertFalse(q.tryTransfer(new Object(),
                                           timeoutMillis(), MILLISECONDS));
-                assertTrue(millisElapsedSince(t0) >= timeoutMillis());
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
                 checkEmpty(q);
             }});
 
@@ -996,7 +1001,9 @@
 
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
-                assertTrue(q.tryTransfer(five, MEDIUM_DELAY_MS, MILLISECONDS));
+                long startTime = System.nanoTime();
+                assertTrue(q.tryTransfer(five, LONG_DELAY_MS, MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
                 checkEmpty(q);
             }});
 
@@ -1006,7 +1013,7 @@
         assertSame(four, q.poll());
         assertSame(five, q.poll());
         checkEmpty(q);
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
     }
 
     /**
@@ -1017,9 +1024,9 @@
         final LinkedTransferQueue q = new LinkedTransferQueue();
         assertTrue(q.offer(four));
         assertEquals(1, q.size());
-        long t0 = System.nanoTime();
+        long startTime = System.nanoTime();
         assertFalse(q.tryTransfer(five, timeoutMillis(), MILLISECONDS));
-        assertTrue(millisElapsedSince(t0) >= timeoutMillis());
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
         assertEquals(1, q.size());
         assertSame(four, q.poll());
         assertNull(q.poll());
diff --git a/jsr166-tests/src/test/java/jsr166/LockSupportTest.java b/jsr166-tests/src/test/java/jsr166/LockSupportTest.java
index 8347b08..b3a8ed8 100644
--- a/jsr166-tests/src/test/java/jsr166/LockSupportTest.java
+++ b/jsr166-tests/src/test/java/jsr166/LockSupportTest.java
@@ -26,9 +26,15 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(LockSupportTest.class);
     // }
 
+    static {
+        // Reduce the risk of rare disastrous classloading in first call to
+        // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
+        Class<?> ensureLoaded = LockSupport.class;
+    }
+
     /**
      * Returns the blocker object used by tests in this file.
      * Any old object will do; we'll return a convenient one.
diff --git a/jsr166-tests/src/test/java/jsr166/LongAccumulatorTest.java b/jsr166-tests/src/test/java/jsr166/LongAccumulatorTest.java
new file mode 100644
index 0000000..5dd52e9
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LongAccumulatorTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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 jsr166;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.atomic.LongAccumulator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LongAccumulatorTest extends JSR166TestCase {
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(LongAccumulatorTest.class);
+    // }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0, ai.get());
+    }
+
+    /**
+     * accumulate accumulates given value to current, and get returns current value
+     */
+    public void testAccumulateAndGet() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        ai.accumulate(2);
+        assertEquals(2, ai.get());
+        ai.accumulate(-4);
+        assertEquals(2, ai.get());
+        ai.accumulate(4);
+        assertEquals(4, ai.get());
+    }
+
+    /**
+     * reset() causes subsequent get() to return zero
+     */
+    public void testReset() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        ai.accumulate(2);
+        assertEquals(2, ai.get());
+        ai.reset();
+        assertEquals(0, ai.get());
+    }
+
+    /**
+     * getThenReset() returns current value; subsequent get() returns zero
+     */
+    public void testGetThenReset() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        ai.accumulate(2);
+        assertEquals(2, ai.get());
+        assertEquals(2, ai.getThenReset());
+        assertEquals(0, ai.get());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals("0", ai.toString());
+        ai.accumulate(1);
+        assertEquals(Long.toString(1), ai.toString());
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0, ai.intValue());
+        ai.accumulate(1);
+        assertEquals(1, ai.intValue());
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0, ai.longValue());
+        ai.accumulate(1);
+        assertEquals(1, ai.longValue());
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0.0f, ai.floatValue());
+        ai.accumulate(1);
+        assertEquals(1.0f, ai.floatValue());
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0.0, ai.doubleValue());
+        ai.accumulate(1);
+        assertEquals(1.0, ai.doubleValue());
+    }
+
+    /**
+     * accumulates by multiple threads produce correct result
+     */
+    public void testAccumulateAndGetMT() {
+        final int incs = 1000000;
+        final int nthreads = 4;
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        LongAccumulator a = new LongAccumulator(Long::max, 0L);
+        Phaser phaser = new Phaser(nthreads + 1);
+        for (int i = 0; i < nthreads; ++i)
+            pool.execute(new AccTask(a, phaser, incs));
+        phaser.arriveAndAwaitAdvance();
+        phaser.arriveAndAwaitAdvance();
+        long expected = incs - 1;
+        long result = a.get();
+        assertEquals(expected, result);
+        pool.shutdown();
+    }
+
+    static final class AccTask implements Runnable {
+        final LongAccumulator acc;
+        final Phaser phaser;
+        final int incs;
+        volatile long result;
+        AccTask(LongAccumulator acc, Phaser phaser, int incs) {
+            this.acc = acc;
+            this.phaser = phaser;
+            this.incs = incs;
+        }
+
+        public void run() {
+            phaser.arriveAndAwaitAdvance();
+            LongAccumulator a = acc;
+            for (int i = 0; i < incs; ++i)
+                a.accumulate(i);
+            result = a.get();
+            phaser.arrive();
+        }
+    }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/LongAdderTest.java b/jsr166-tests/src/test/java/jsr166/LongAdderTest.java
new file mode 100644
index 0000000..800a9c8
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LongAdderTest.java
@@ -0,0 +1,198 @@
+/*
+ * 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 jsr166;
+
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.LongAdder;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LongAdderTest extends JSR166TestCase {
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(LongAdderTest.class);
+    // }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0, ai.sum());
+    }
+
+    /**
+     * add adds given value to current, and sum returns current value
+     */
+    public void testAddAndSum() {
+        LongAdder ai = new LongAdder();
+        ai.add(2);
+        assertEquals(2, ai.sum());
+        ai.add(-4);
+        assertEquals(-2, ai.sum());
+    }
+
+    /**
+     * decrement decrements and sum returns current value
+     */
+    public void testDecrementAndsum() {
+        LongAdder ai = new LongAdder();
+        ai.decrement();
+        assertEquals(-1, ai.sum());
+        ai.decrement();
+        assertEquals(-2, ai.sum());
+    }
+
+    /**
+     * incrementAndGet increments and returns current value
+     */
+    public void testIncrementAndsum() {
+        LongAdder ai = new LongAdder();
+        ai.increment();
+        assertEquals(1, ai.sum());
+        ai.increment();
+        assertEquals(2, ai.sum());
+    }
+
+    /**
+     * reset() causes subsequent sum() to return zero
+     */
+    public void testReset() {
+        LongAdder ai = new LongAdder();
+        ai.add(2);
+        assertEquals(2, ai.sum());
+        ai.reset();
+        assertEquals(0, ai.sum());
+    }
+
+    /**
+     * sumThenReset() returns sum; subsequent sum() returns zero
+     */
+    public void testSumThenReset() {
+        LongAdder ai = new LongAdder();
+        ai.add(2);
+        assertEquals(2, ai.sum());
+        assertEquals(2, ai.sumThenReset());
+        assertEquals(0, ai.sum());
+    }
+
+    /**
+     * a deserialized serialized adder holds same value
+     */
+    public void testSerialization() throws Exception {
+        LongAdder x = new LongAdder();
+        LongAdder y = serialClone(x);
+        assertNotSame(x, y);
+        x.add(-22);
+        LongAdder z = serialClone(x);
+        assertNotSame(y, z);
+        assertEquals(-22, x.sum());
+        assertEquals(0, y.sum());
+        assertEquals(-22, z.sum());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        LongAdder ai = new LongAdder();
+        assertEquals("0", ai.toString());
+        ai.increment();
+        assertEquals(Long.toString(1), ai.toString());
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0, ai.intValue());
+        ai.increment();
+        assertEquals(1, ai.intValue());
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0, ai.longValue());
+        ai.increment();
+        assertEquals(1, ai.longValue());
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0.0f, ai.floatValue());
+        ai.increment();
+        assertEquals(1.0f, ai.floatValue());
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0.0, ai.doubleValue());
+        ai.increment();
+        assertEquals(1.0, ai.doubleValue());
+    }
+
+    /**
+     * adds by multiple threads produce correct sum
+     */
+    public void testAddAndSumMT() throws Throwable {
+        final int incs = 1000000;
+        final int nthreads = 4;
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        LongAdder a = new LongAdder();
+        CyclicBarrier barrier = new CyclicBarrier(nthreads + 1);
+        for (int i = 0; i < nthreads; ++i)
+            pool.execute(new AdderTask(a, barrier, incs));
+        barrier.await();
+        barrier.await();
+        long total = (long)nthreads * incs;
+        long sum = a.sum();
+        assertEquals(sum, total);
+        pool.shutdown();
+    }
+
+    static final class AdderTask implements Runnable {
+        final LongAdder adder;
+        final CyclicBarrier barrier;
+        final int incs;
+        volatile long result;
+        AdderTask(LongAdder adder, CyclicBarrier barrier, int incs) {
+            this.adder = adder;
+            this.barrier = barrier;
+            this.incs = incs;
+        }
+
+        public void run() {
+            try {
+                barrier.await();
+                LongAdder a = adder;
+                for (int i = 0; i < incs; ++i)
+                    a.add(1L);
+                result = a.sum();
+                barrier.await();
+            } catch (Throwable t) { throw new Error(t); }
+        }
+    }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/PhaserTest.java b/jsr166-tests/src/test/java/jsr166/PhaserTest.java
index 42d72f4..673e556 100644
--- a/jsr166-tests/src/test/java/jsr166/PhaserTest.java
+++ b/jsr166-tests/src/test/java/jsr166/PhaserTest.java
@@ -28,7 +28,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(PhaserTest.class);
     // }
 
     private static final int maxParties = 65535;
@@ -342,8 +342,8 @@
      * registered or unarrived parties would become negative
      */
     public void testArriveAndDeregister1() {
+        Phaser phaser = new Phaser();
         try {
-            Phaser phaser = new Phaser();
             phaser.arriveAndDeregister();
             shouldThrow();
         } catch (IllegalStateException success) {}
@@ -629,11 +629,11 @@
             threads.add(newStartedThread(new CheckedRunnable() {
                 public void realRun() {
                     for (int k = 0; k < 3; k++) {
-                        assertEquals(2*k+1, phaser.arriveAndAwaitAdvance());
+                        assertEquals(2 * k + 1, phaser.arriveAndAwaitAdvance());
                         count.incrementAndGet();
-                        assertEquals(2*k+1, phaser.arrive());
-                        assertEquals(2*k+2, phaser.awaitAdvance(2*k+1));
-                        assertEquals(4*(k+1), count.get());
+                        assertEquals(2 * k + 1, phaser.arrive());
+                        assertEquals(2 * k + 2, phaser.awaitAdvance(2 * k + 1));
+                        assertEquals(4 * (k + 1), count.get());
                     }}}));
 
         for (Thread thread : threads)
@@ -689,7 +689,7 @@
         for (Phaser phaser : phasers) {
             assertEquals(-42, phaser.awaitAdvance(-42));
             assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
-            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
+            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS));
         }
 
         for (Phaser child : onePartyChildren)
@@ -697,10 +697,10 @@
         for (Phaser phaser : phasers) {
             assertEquals(-42, phaser.awaitAdvance(-42));
             assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
-            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
+            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS));
             assertEquals(1, phaser.awaitAdvance(0));
             assertEquals(1, phaser.awaitAdvanceInterruptibly(0));
-            assertEquals(1, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
+            assertEquals(1, phaser.awaitAdvanceInterruptibly(0, MEDIUM_DELAY_MS, MILLISECONDS));
         }
 
         for (Phaser child : onePartyChildren)
@@ -708,13 +708,13 @@
         for (Phaser phaser : phasers) {
             assertEquals(-42, phaser.awaitAdvance(-42));
             assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
-            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
+            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS));
             assertEquals(2, phaser.awaitAdvance(0));
             assertEquals(2, phaser.awaitAdvanceInterruptibly(0));
-            assertEquals(2, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
+            assertEquals(2, phaser.awaitAdvanceInterruptibly(0, MEDIUM_DELAY_MS, MILLISECONDS));
             assertEquals(2, phaser.awaitAdvance(1));
             assertEquals(2, phaser.awaitAdvanceInterruptibly(1));
-            assertEquals(2, phaser.awaitAdvanceInterruptibly(1, SMALL_DELAY_MS, MILLISECONDS));
+            assertEquals(2, phaser.awaitAdvanceInterruptibly(1, MEDIUM_DELAY_MS, MILLISECONDS));
         }
     }
 
@@ -752,8 +752,8 @@
      * unarrived parties
      */
     public void testArriveAndAwaitAdvance1() {
+        Phaser phaser = new Phaser();
         try {
-            Phaser phaser = new Phaser();
             phaser.arriveAndAwaitAdvance();
             shouldThrow();
         } catch (IllegalStateException success) {}
diff --git a/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java
index 64c3b3a..41b06f5 100644
--- a/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/PriorityBlockingQueueTest.java
@@ -27,7 +27,7 @@
 
 public class PriorityBlockingQueueTest extends JSR166TestCase {
 
-    // android-note: These tests have been moved into their own separate 
+    // android-note: These tests have been moved into their own separate
     // classes to work around CTS issues.
     //
     // public static class Generic extends BlockingQueueTest {
@@ -35,17 +35,19 @@
     //         return new PriorityBlockingQueue();
     //     }
     // }
-    //
+
     // public static class InitialCapacity extends BlockingQueueTest {
     //     protected BlockingQueue emptyCollection() {
     //         return new PriorityBlockingQueue(SIZE);
     //     }
     // }
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
     //
     // public static void main(String[] args) {
     //     main(suite(), args);
     // }
-    //
     // public static Test suite() {
     //     return newTestSuite(PriorityBlockingQueueTest.class,
     //                         new Generic().testSuite(),
@@ -67,7 +69,7 @@
         PriorityBlockingQueue<Integer> q =
             new PriorityBlockingQueue<Integer>(n);
         assertTrue(q.isEmpty());
-        for (int i = n-1; i >= 0; i -= 2)
+        for (int i = n - 1; i >= 0; i -= 2)
             assertTrue(q.offer(new Integer(i)));
         for (int i = (n & 1); i < n; i += 2)
             assertTrue(q.offer(new Integer(i)));
@@ -121,7 +123,7 @@
      */
     public void testConstructor5() {
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = i;
         Collection<Integer> elements = Arrays.asList(ints);
         try {
@@ -153,7 +155,7 @@
         for (int i = 0; i < SIZE; ++i)
             ints[i] = new Integer(i);
         q.addAll(Arrays.asList(ints));
-        for (int i = SIZE-1; i >= 0; --i)
+        for (int i = SIZE - 1; i >= 0; --i)
             assertEquals(ints[i], q.poll());
     }
 
@@ -225,8 +227,8 @@
      * addAll(this) throws IAE
      */
     public void testAddAllSelf() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
         try {
-            PriorityBlockingQueue q = populatedQueue(SIZE);
             q.addAll(q);
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -237,11 +239,11 @@
      * possibly adding some elements
      */
     public void testAddAll3() {
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -253,7 +255,7 @@
     public void testAddAll5() {
         Integer[] empty = new Integer[0];
         Integer[] ints = new Integer[SIZE];
-        for (int i = SIZE-1; i >= 0; --i)
+        for (int i = SIZE - 1; i >= 0; --i)
             ints[i] = new Integer(i);
         PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
         assertFalse(q.addAll(Arrays.asList(empty)));
@@ -398,25 +400,23 @@
         final CountDownLatch aboutToWait = new CountDownLatch(1);
         Thread t = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
                 for (int i = 0; i < SIZE; ++i) {
-                    long t0 = System.nanoTime();
                     assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
-                    assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
                 }
-                long t0 = System.nanoTime();
                 aboutToWait.countDown();
                 try {
                     q.poll(LONG_DELAY_MS, MILLISECONDS);
                     shouldThrow();
                 } catch (InterruptedException success) {
-                    assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS);
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
                 }
             }});
 
         aboutToWait.await();
-        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
+        waitForThreadToEnterWaitState(t, LONG_DELAY_MS);
         t.interrupt();
-        awaitTermination(t, MEDIUM_DELAY_MS);
+        awaitTermination(t);
     }
 
     /**
@@ -517,7 +517,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.remove();
         }
     }
@@ -530,7 +530,7 @@
             PriorityBlockingQueue q = populatedQueue(SIZE);
             PriorityBlockingQueue p = populatedQueue(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.remove());
                 assertFalse(q.contains(x));
@@ -629,22 +629,22 @@
     public void testPollInExecutor() {
         final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertNull(q.poll());
-                threadsStarted.await();
-                assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
-                checkEmpty(q);
-            }});
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                q.put(one);
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
     }
 
     /**
@@ -694,7 +694,7 @@
         final PriorityBlockingQueue q = populatedQueue(SIZE);
         Thread t = new Thread(new CheckedRunnable() {
             public void realRun() {
-                q.put(new Integer(SIZE+1));
+                q.put(new Integer(SIZE + 1));
             }});
 
         t.start();
@@ -711,7 +711,7 @@
      * drainTo(c, n) empties first min(n, size) elements of queue into c
      */
     public void testDrainToN() {
-        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE*2);
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE * 2);
         for (int i = 0; i < SIZE + 2; ++i) {
             for (int j = 0; j < SIZE; j++)
                 assertTrue(q.offer(new Integer(j)));
@@ -719,7 +719,7 @@
             q.drainTo(l, i);
             int k = (i < SIZE) ? i : SIZE;
             assertEquals(k, l.size());
-            assertEquals(SIZE-k, q.size());
+            assertEquals(SIZE - k, q.size());
             for (int j = 0; j < k; ++j)
                 assertEquals(l.get(j), new Integer(j));
             do {} while (q.poll() != null);
diff --git a/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java b/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java
index 88cdd37..f64ef68 100644
--- a/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/PriorityQueueTest.java
@@ -27,7 +27,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(PriorityQueueTest.class);
     // }
 
     static class MyReverseComparator implements Comparator {
@@ -43,7 +43,7 @@
     private PriorityQueue<Integer> populatedQueue(int n) {
         PriorityQueue<Integer> q = new PriorityQueue<Integer>(n);
         assertTrue(q.isEmpty());
-        for (int i = n-1; i >= 0; i -= 2)
+        for (int i = n - 1; i >= 0; i -= 2)
             assertTrue(q.offer(new Integer(i)));
         for (int i = (n & 1); i < n; i += 2)
             assertTrue(q.offer(new Integer(i)));
@@ -84,8 +84,7 @@
      */
     public void testConstructor4() {
         try {
-            Integer[] ints = new Integer[SIZE];
-            new PriorityQueue(Arrays.asList(ints));
+            new PriorityQueue(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -94,10 +93,10 @@
      * Initializing from Collection with some null elements throws NPE
      */
     public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             new PriorityQueue(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -126,7 +125,7 @@
         for (int i = 0; i < SIZE; ++i)
             ints[i] = new Integer(i);
         q.addAll(Arrays.asList(ints));
-        for (int i = SIZE-1; i >= 0; --i)
+        for (int i = SIZE - 1; i >= 0; --i)
             assertEquals(ints[i], q.poll());
     }
 
@@ -150,7 +149,7 @@
     public void testSize() {
         PriorityQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.remove();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -163,8 +162,8 @@
      * offer(null) throws NPE
      */
     public void testOfferNull() {
+        PriorityQueue q = new PriorityQueue(1);
         try {
-            PriorityQueue q = new PriorityQueue(1);
             q.offer(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -174,8 +173,8 @@
      * add(null) throws NPE
      */
     public void testAddNull() {
+        PriorityQueue q = new PriorityQueue(1);
         try {
-            PriorityQueue q = new PriorityQueue(1);
             q.add(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -217,8 +216,8 @@
      * addAll(null) throws NPE
      */
     public void testAddAll1() {
+        PriorityQueue q = new PriorityQueue(1);
         try {
-            PriorityQueue q = new PriorityQueue(1);
             q.addAll(null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -228,10 +227,9 @@
      * addAll of a collection with null elements throws NPE
      */
     public void testAddAll2() {
+        PriorityQueue q = new PriorityQueue(SIZE);
         try {
-            PriorityQueue q = new PriorityQueue(SIZE);
-            Integer[] ints = new Integer[SIZE];
-            q.addAll(Arrays.asList(ints));
+            q.addAll(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -241,11 +239,11 @@
      * possibly adding some elements
      */
     public void testAddAll3() {
+        PriorityQueue q = new PriorityQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            PriorityQueue q = new PriorityQueue(SIZE);
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -258,7 +256,7 @@
         Integer[] empty = new Integer[0];
         Integer[] ints = new Integer[SIZE];
         for (int i = 0; i < SIZE; ++i)
-            ints[i] = new Integer(SIZE-1-i);
+            ints[i] = new Integer(SIZE - 1 - i);
         PriorityQueue q = new PriorityQueue(SIZE);
         assertFalse(q.addAll(Arrays.asList(empty)));
         assertTrue(q.addAll(Arrays.asList(ints)));
@@ -329,14 +327,14 @@
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertTrue(q.contains(i-1));
+            assertTrue(q.contains(i - 1));
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertFalse(q.remove(i+1));
-            assertFalse(q.contains(i+1));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
         }
         assertTrue(q.isEmpty());
     }
@@ -395,7 +393,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.remove();
         }
     }
@@ -408,7 +406,7 @@
             PriorityQueue q = populatedQueue(SIZE);
             PriorityQueue p = populatedQueue(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.remove());
                 assertFalse(q.contains(x));
diff --git a/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java b/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java
index 1c3bba8..c8e33be 100644
--- a/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java
+++ b/jsr166-tests/src/test/java/jsr166/RecursiveActionTest.java
@@ -32,7 +32,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(RecursiveActionTest.class);
     // }
 
     private static ForkJoinPool mainPool() {
@@ -50,14 +50,12 @@
     }
 
     private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
-        try {
+        try (PoolCleaner cleaner = cleaner(pool)) {
             checkNotDone(a);
 
             assertNull(pool.invoke(a));
 
             checkCompletedNormally(a);
-        } finally {
-            joinPool(pool);
         }
     }
 
@@ -429,12 +427,12 @@
 
         t = newStartedThread(r);
         testInvokeOnPool(mainPool(), a);
-        awaitTermination(t, LONG_DELAY_MS);
+        awaitTermination(t);
 
         a.reinitialize();
         t = newStartedThread(r);
         testInvokeOnPool(singletonPool(), a);
-        awaitTermination(t, LONG_DELAY_MS);
+        awaitTermination(t);
     }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java b/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java
index 7783370..2c07c2a 100644
--- a/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java
+++ b/jsr166-tests/src/test/java/jsr166/RecursiveTaskTest.java
@@ -28,7 +28,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(RecursiveTaskTest.class);
     // }
 
     private static ForkJoinPool mainPool() {
@@ -46,15 +46,13 @@
     }
 
     private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) {
-        try {
+        try (PoolCleaner cleaner = cleaner(pool)) {
             checkNotDone(a);
 
             T result = pool.invoke(a);
 
             checkCompletedNormally(a, result);
             return result;
-        } finally {
-            joinPool(pool);
         }
     }
 
@@ -335,6 +333,8 @@
                 FibTask f = new FibTask(8);
                 assertSame(f, f.fork());
                 helpQuiesce();
+                while (!f.isDone()) // wait out race
+                    ;
                 assertEquals(0, getQueuedTaskCount());
                 checkCompletedNormally(f, 21);
                 return NoResult;
diff --git a/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java b/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java
index 17eaf76..0024ff3 100644
--- a/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ReentrantLockTest.java
@@ -30,8 +30,9 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ReentrantLockTest.class);
     // }
+
     /**
      * A checked runnable calling lockInterruptibly
      */
@@ -150,7 +151,7 @@
     enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
 
     /**
-     * Awaits condition using the specified AwaitMethod.
+     * Awaits condition "indefinitely" using the specified AwaitMethod.
      */
     void await(Condition c, AwaitMethod awaitMethod)
             throws InterruptedException {
@@ -163,9 +164,10 @@
             assertTrue(c.await(timeoutMillis, MILLISECONDS));
             break;
         case awaitNanos:
-            long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
-            long nanosRemaining = c.awaitNanos(nanosTimeout);
-            assertTrue(nanosRemaining > 0);
+            long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
+            long nanosRemaining = c.awaitNanos(timeoutNanos);
+            assertTrue(nanosRemaining > timeoutNanos / 2);
+            assertTrue(nanosRemaining <= timeoutNanos);
             break;
         case awaitUntil:
             assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
@@ -428,7 +430,7 @@
         }
         for (int i = SIZE; i > 0; i--) {
             lock.unlock();
-            assertEquals(i-1, lock.getHoldCount());
+            assertEquals(i - 1, lock.getHoldCount());
         }
     }
 
@@ -568,11 +570,11 @@
             final ReentrantLock lock = new ReentrantLock(fair);
             final Condition c = lock.newCondition();
             lock.lock();
-            long startTime = System.nanoTime();
-            long timeoutMillis = 10;
-            java.util.Date d = new java.util.Date();
-            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis)));
-            assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            // We shouldn't assume that nanoTime and currentTimeMillis
+            // use the same time source, so don't use nanoTime here.
+            java.util.Date delayedDate = delayedDate(timeoutMillis());
+            assertFalse(c.awaitUntil(delayedDate));
+            assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
             lock.unlock();
         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
     }
diff --git a/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java b/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java
index 7ef8ea3..918f45d 100644
--- a/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ReentrantReadWriteLockTest.java
@@ -31,7 +31,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ReentrantReadWriteLockTest.class);
     // }
 
     /**
@@ -160,24 +160,26 @@
     enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
 
     /**
-     * Awaits condition using the specified AwaitMethod.
+     * Awaits condition "indefinitely" using the specified AwaitMethod.
      */
     void await(Condition c, AwaitMethod awaitMethod)
             throws InterruptedException {
+        long timeoutMillis = 2 * LONG_DELAY_MS;
         switch (awaitMethod) {
         case await:
             c.await();
             break;
         case awaitTimed:
-            assertTrue(c.await(2 * LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(c.await(timeoutMillis, MILLISECONDS));
             break;
         case awaitNanos:
-            long nanosRemaining = c.awaitNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
-            assertTrue(nanosRemaining > 0);
+            long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
+            long nanosRemaining = c.awaitNanos(timeoutNanos);
+            assertTrue(nanosRemaining > timeoutNanos / 2);
+            assertTrue(nanosRemaining <= timeoutNanos);
             break;
         case awaitUntil:
-            java.util.Date d = new java.util.Date();
-            assertTrue(c.awaitUntil(new java.util.Date(d.getTime() + 2 * LONG_DELAY_MS)));
+            assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
             break;
         default:
             throw new AssertionError();
@@ -241,7 +243,7 @@
         }
         for (int i = SIZE; i > 0; i--) {
             lock.writeLock().unlock();
-            assertEquals(i-1,lock.getWriteHoldCount());
+            assertEquals(i - 1,lock.getWriteHoldCount());
         }
     }
 
@@ -258,7 +260,7 @@
         }
         for (int i = SIZE; i > 0; i--) {
             lock.writeLock().unlock();
-            assertEquals(i-1,lock.writeLock().getHoldCount());
+            assertEquals(i - 1,lock.writeLock().getHoldCount());
         }
     }
 
@@ -275,7 +277,7 @@
         }
         for (int i = SIZE; i > 0; i--) {
             lock.readLock().unlock();
-            assertEquals(i-1,lock.getReadHoldCount());
+            assertEquals(i - 1,lock.getReadHoldCount());
         }
     }
 
@@ -972,11 +974,11 @@
                 new ReentrantReadWriteLock(fair);
             final Condition c = lock.writeLock().newCondition();
             lock.writeLock().lock();
-            long startTime = System.nanoTime();
-            long timeoutMillis = 10;
-            java.util.Date d = new java.util.Date();
-            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis)));
-            assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            // We shouldn't assume that nanoTime and currentTimeMillis
+            // use the same time source, so don't use nanoTime here.
+            java.util.Date delayedDate = delayedDate(timeoutMillis());
+            assertFalse(c.awaitUntil(delayedDate));
+            assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
             lock.writeLock().unlock();
         } catch (InterruptedException fail) { threadUnexpectedException(fail); }
     }
diff --git a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java
index a93feea..194dd58 100644
--- a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorSubclassTest.java
@@ -7,11 +7,15 @@
 package jsr166;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Delayed;
 import java.util.concurrent.ExecutionException;
@@ -27,7 +31,9 @@
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -40,7 +46,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ScheduledExecutorSubclassTest.class);
     // }
 
     static class CustomTask<V> implements RunnableScheduledFuture<V> {
@@ -101,17 +107,13 @@
      * execute successfully executes a runnable
      */
     public void testExecute() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        final Runnable task = new CheckedRunnable() {
-            public void realRun() {
-                done.countDown();
-            }};
-        try {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() { done.countDown(); }};
             p.execute(task);
-            assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
-        } finally {
-            joinPool(p);
+            await(done);
         }
     }
 
@@ -119,10 +121,10 @@
      * delayed schedule of callable successfully executes after delay
      */
     public void testSchedule1() throws Exception {
-        CustomExecutor p = new CustomExecutor(1);
-        final long startTime = System.nanoTime();
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final long startTime = System.nanoTime();
             Callable task = new CheckedCallable<Boolean>() {
                 public Boolean realCall() {
                     done.countDown();
@@ -132,9 +134,6 @@
             Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
             assertSame(Boolean.TRUE, f.get());
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
-            assertTrue(done.await(0L, MILLISECONDS));
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -142,10 +141,10 @@
      * delayed schedule of runnable successfully executes after delay
      */
     public void testSchedule3() throws Exception {
-        CustomExecutor p = new CustomExecutor(1);
-        final long startTime = System.nanoTime();
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
             Runnable task = new CheckedRunnable() {
                 public void realRun() {
                     done.countDown();
@@ -155,8 +154,6 @@
             await(done);
             assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -164,10 +161,10 @@
      * scheduleAtFixedRate executes runnable after given initial delay
      */
     public void testSchedule4() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        final long startTime = System.nanoTime();
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
             Runnable task = new CheckedRunnable() {
                 public void realRun() {
                     done.countDown();
@@ -179,8 +176,6 @@
             await(done);
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
             f.cancel(true);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -188,10 +183,10 @@
      * scheduleWithFixedDelay executes runnable after given initial delay
      */
     public void testSchedule5() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        final long startTime = System.nanoTime();
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
             Runnable task = new CheckedRunnable() {
                 public void realRun() {
                     done.countDown();
@@ -203,8 +198,6 @@
             await(done);
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
             f.cancel(true);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -214,58 +207,77 @@
     }
 
     /**
-     * scheduleAtFixedRate executes series of tasks at given rate
+     * scheduleAtFixedRate executes series of tasks at given rate.
+     * Eventually, it must hold that:
+     *   cycles - 1 <= elapsedMillis/delay < cycles
      */
     public void testFixedRateSequence() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        try {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
-                long startTime = System.nanoTime();
-                int cycles = 10;
+                final long startTime = System.nanoTime();
+                final int cycles = 8;
                 final CountDownLatch done = new CountDownLatch(cycles);
-                Runnable task = new CheckedRunnable() {
+                final Runnable task = new CheckedRunnable() {
                     public void realRun() { done.countDown(); }};
-                ScheduledFuture h =
+                final ScheduledFuture periodicTask =
                     p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
-                done.await();
-                h.cancel(true);
-                double normalizedTime =
-                    (double) millisElapsedSince(startTime) / delay;
-                if (normalizedTime >= cycles - 1 &&
-                    normalizedTime <= cycles)
+                final int totalDelayMillis = (cycles - 1) * delay;
+                await(done, totalDelayMillis + LONG_DELAY_MS);
+                periodicTask.cancel(true);
+                final long elapsedMillis = millisElapsedSince(startTime);
+                assertTrue(elapsedMillis >= totalDelayMillis);
+                if (elapsedMillis <= cycles * delay)
                     return;
+                // else retry with longer delay
             }
-            throw new AssertionError("unexpected execution rate");
-        } finally {
-            joinPool(p);
+            fail("unexpected execution rate");
         }
     }
 
     /**
-     * scheduleWithFixedDelay executes series of tasks with given period
+     * scheduleWithFixedDelay executes series of tasks with given period.
+     * Eventually, it must hold that each task starts at least delay and at
+     * most 2 * delay after the termination of the previous task.
      */
     public void testFixedDelaySequence() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        try {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
-                long startTime = System.nanoTime();
-                int cycles = 10;
+                final long startTime = System.nanoTime();
+                final AtomicLong previous = new AtomicLong(startTime);
+                final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
+                final int cycles = 8;
                 final CountDownLatch done = new CountDownLatch(cycles);
-                Runnable task = new CheckedRunnable() {
-                    public void realRun() { done.countDown(); }};
-                ScheduledFuture h =
+                final int d = delay;
+                final Runnable task = new CheckedRunnable() {
+                    public void realRun() {
+                        long now = System.nanoTime();
+                        long elapsedMillis
+                            = NANOSECONDS.toMillis(now - previous.get());
+                        if (done.getCount() == cycles) { // first execution
+                            if (elapsedMillis >= d)
+                                tryLongerDelay.set(true);
+                        } else {
+                            assertTrue(elapsedMillis >= d);
+                            if (elapsedMillis >= 2 * d)
+                                tryLongerDelay.set(true);
+                        }
+                        previous.set(now);
+                        done.countDown();
+                    }};
+                final ScheduledFuture periodicTask =
                     p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
-                done.await();
-                h.cancel(true);
-                double normalizedTime =
-                    (double) millisElapsedSince(startTime) / delay;
-                if (normalizedTime >= cycles - 1 &&
-                    normalizedTime <= cycles)
+                final int totalDelayMillis = (cycles - 1) * delay;
+                await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
+                periodicTask.cancel(true);
+                final long elapsedMillis = millisElapsedSince(startTime);
+                assertTrue(elapsedMillis >= totalDelayMillis);
+                if (!tryLongerDelay.get())
                     return;
+                // else retry with longer delay
             }
-            throw new AssertionError("unexpected execution rate");
-        } finally {
-            joinPool(p);
+            fail("unexpected execution rate");
         }
     }
 
@@ -273,106 +285,107 @@
      * execute(null) throws NPE
      */
     public void testExecuteNull() throws InterruptedException {
-        CustomExecutor se = new CustomExecutor(1);
-        try {
-            se.execute(null);
-            shouldThrow();
-        } catch (NullPointerException success) {}
-        joinPool(se);
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
     }
 
     /**
      * schedule(null) throws NPE
      */
     public void testScheduleNull() throws InterruptedException {
-        CustomExecutor se = new CustomExecutor(1);
-        try {
-            TrackedCallable callable = null;
-            Future f = se.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {}
-        joinPool(se);
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                TrackedCallable callable = null;
+                Future f = p.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
     }
 
     /**
      * execute throws RejectedExecutionException if shutdown
      */
     public void testSchedule1_RejectedExecutionException() {
-        CustomExecutor se = new CustomExecutor(1);
-        try {
-            se.shutdown();
-            se.schedule(new NoOpRunnable(),
-                        MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpRunnable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-
-        joinPool(se);
     }
 
     /**
      * schedule throws RejectedExecutionException if shutdown
      */
     public void testSchedule2_RejectedExecutionException() {
-        CustomExecutor se = new CustomExecutor(1);
-        try {
-            se.shutdown();
-            se.schedule(new NoOpCallable(),
-                        MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpCallable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-        joinPool(se);
     }
 
     /**
      * schedule callable throws RejectedExecutionException if shutdown
      */
     public void testSchedule3_RejectedExecutionException() {
-        CustomExecutor se = new CustomExecutor(1);
-        try {
-            se.shutdown();
-            se.schedule(new NoOpCallable(),
-                        MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpCallable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-        joinPool(se);
     }
 
     /**
      * scheduleAtFixedRate throws RejectedExecutionException if shutdown
      */
     public void testScheduleAtFixedRate1_RejectedExecutionException() {
-        CustomExecutor se = new CustomExecutor(1);
-        try {
-            se.shutdown();
-            se.scheduleAtFixedRate(new NoOpRunnable(),
-                                   MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.scheduleAtFixedRate(new NoOpRunnable(),
+                                      MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-        joinPool(se);
     }
 
     /**
      * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
      */
     public void testScheduleWithFixedDelay1_RejectedExecutionException() {
-        CustomExecutor se = new CustomExecutor(1);
-        try {
-            se.shutdown();
-            se.scheduleWithFixedDelay(new NoOpRunnable(),
-                                      MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.scheduleWithFixedDelay(new NoOpRunnable(),
+                                         MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-        joinPool(se);
     }
 
     /**
@@ -380,22 +393,19 @@
      * thread becomes active
      */
     public void testGetActiveCount() throws InterruptedException {
-        final ThreadPoolExecutor p = new CustomExecutor(2);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ThreadPoolExecutor p = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertEquals(0, p.getActiveCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertEquals(1, p.getActiveCount());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getActiveCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -405,10 +415,10 @@
      */
     public void testGetCompletedTaskCount() throws InterruptedException {
         final ThreadPoolExecutor p = new CustomExecutor(2);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch threadProceed = new CountDownLatch(1);
-        final CountDownLatch threadDone = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch threadProceed = new CountDownLatch(1);
+            final CountDownLatch threadDone = new CountDownLatch(1);
             assertEquals(0, p.getCompletedTaskCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
@@ -427,8 +437,6 @@
                     fail("timed out");
                 Thread.yield();
             }
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -436,9 +444,10 @@
      * getCorePoolSize returns size given in constructor if not otherwise set
      */
     public void testGetCorePoolSize() {
-        CustomExecutor p = new CustomExecutor(1);
-        assertEquals(1, p.getCorePoolSize());
-        joinPool(p);
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getCorePoolSize());
+        }
     }
 
     /**
@@ -447,25 +456,22 @@
      */
     public void testGetLargestPoolSize() throws InterruptedException {
         final int THREADS = 3;
-        final ThreadPoolExecutor p = new CustomExecutor(THREADS);
-        final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ThreadPoolExecutor p = new CustomExecutor(THREADS);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
             assertEquals(0, p.getLargestPoolSize());
             for (int i = 0; i < THREADS; i++)
                 p.execute(new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadsStarted.countDown();
-                        done.await();
+                        await(done);
                         assertEquals(THREADS, p.getLargestPoolSize());
                     }});
-            assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
-            assertEquals(THREADS, p.getLargestPoolSize());
-        } finally {
-            done.countDown();
-            joinPool(p);
+            await(threadsStarted);
             assertEquals(THREADS, p.getLargestPoolSize());
         }
+        assertEquals(THREADS, p.getLargestPoolSize());
     }
 
     /**
@@ -473,22 +479,19 @@
      * become active
      */
     public void testGetPoolSize() throws InterruptedException {
-        final ThreadPoolExecutor p = new CustomExecutor(1);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertEquals(0, p.getPoolSize());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertEquals(1, p.getPoolSize());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getPoolSize());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -497,58 +500,70 @@
      * submitted
      */
     public void testGetTaskCount() throws InterruptedException {
-        final ThreadPoolExecutor p = new CustomExecutor(1);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
+        final int TASKS = 3;
         final CountDownLatch done = new CountDownLatch(1);
-        final int TASKS = 5;
-        try {
+        final ThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertEquals(0, p.getTaskCount());
-            for (int i = 0; i < TASKS; i++)
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            for (int i = 0; i < TASKS; i++) {
+                assertEquals(1 + i, p.getTaskCount());
                 p.execute(new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadStarted.countDown();
-                        done.await();
+                        assertEquals(1 + TASKS, p.getTaskCount());
+                        await(done);
                     }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
-            assertEquals(TASKS, p.getTaskCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
+            }
+            assertEquals(1 + TASKS, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
         }
+        assertEquals(1 + TASKS, p.getTaskCount());
+        assertEquals(1 + TASKS, p.getCompletedTaskCount());
     }
 
     /**
      * getThreadFactory returns factory in constructor if not set
      */
     public void testGetThreadFactory() {
-        ThreadFactory tf = new SimpleThreadFactory();
-        CustomExecutor p = new CustomExecutor(1, tf);
-        assertSame(tf, p.getThreadFactory());
-        joinPool(p);
+        final ThreadFactory threadFactory = new SimpleThreadFactory();
+        final CustomExecutor p = new CustomExecutor(1, threadFactory);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(threadFactory, p.getThreadFactory());
+        }
     }
 
     /**
      * setThreadFactory sets the thread factory returned by getThreadFactory
      */
     public void testSetThreadFactory() {
-        ThreadFactory tf = new SimpleThreadFactory();
-        CustomExecutor p = new CustomExecutor(1);
-        p.setThreadFactory(tf);
-        assertSame(tf, p.getThreadFactory());
-        joinPool(p);
+        final ThreadFactory threadFactory = new SimpleThreadFactory();
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            p.setThreadFactory(threadFactory);
+            assertSame(threadFactory, p.getThreadFactory());
+        }
     }
 
     /**
      * setThreadFactory(null) throws NPE
      */
     public void testSetThreadFactoryNull() {
-        CustomExecutor p = new CustomExecutor(1);
-        try {
-            p.setThreadFactory(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(p);
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setThreadFactory(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -556,91 +571,84 @@
      * isShutdown is false before shutdown, true after
      */
     public void testIsShutdown() {
-        CustomExecutor p = new CustomExecutor(1);
-        try {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
             assertFalse(p.isShutdown());
-        }
-        finally {
             try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.isShutdown());
         }
-        assertTrue(p.isShutdown());
     }
 
     /**
      * isTerminated is false before termination, true after
      */
     public void testIsTerminated() throws InterruptedException {
-        final ThreadPoolExecutor p = new CustomExecutor(1);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        assertFalse(p.isTerminated());
-        try {
+        final ThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     assertFalse(p.isTerminated());
                     threadStarted.countDown();
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
+            assertFalse(p.isTerminated());
             assertFalse(p.isTerminating());
             done.countDown();
-        } finally {
             try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
         }
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
     }
 
     /**
      * isTerminating is not true when running or when terminated
      */
     public void testIsTerminating() throws InterruptedException {
-        final ThreadPoolExecutor p = new CustomExecutor(1);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertFalse(p.isTerminating());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     assertFalse(p.isTerminating());
                     threadStarted.countDown();
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertFalse(p.isTerminating());
             done.countDown();
-        } finally {
             try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
         }
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
-        assertFalse(p.isTerminating());
     }
 
     /**
      * getQueue returns the work queue, which contains queued tasks
      */
     public void testGetQueue() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new CustomExecutor(1);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             ScheduledFuture[] tasks = new ScheduledFuture[5];
             for (int i = 0; i < tasks.length; i++) {
                 Runnable r = new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadStarted.countDown();
-                        done.await();
+                        await(done);
                     }};
                 tasks[i] = p.schedule(r, 1, MILLISECONDS);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             BlockingQueue<Runnable> q = p.getQueue();
             assertTrue(q.contains(tasks[tasks.length - 1]));
             assertFalse(q.contains(tasks[0]));
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -648,20 +656,20 @@
      * remove(task) removes queued task, and fails to remove active task
      */
     public void testRemove() throws InterruptedException {
-        final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
-        ScheduledFuture[] tasks = new ScheduledFuture[5];
-        final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            ScheduledFuture[] tasks = new ScheduledFuture[5];
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             for (int i = 0; i < tasks.length; i++) {
                 Runnable r = new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadStarted.countDown();
-                        done.await();
+                        await(done);
                     }};
                 tasks[i] = p.schedule(r, 1, MILLISECONDS);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             BlockingQueue<Runnable> q = p.getQueue();
             assertFalse(p.remove((Runnable)tasks[0]));
             assertTrue(q.contains((Runnable)tasks[4]));
@@ -672,9 +680,6 @@
             assertTrue(q.contains((Runnable)tasks[3]));
             assertTrue(p.remove((Runnable)tasks[3]));
             assertFalse(q.contains((Runnable)tasks[3]));
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -682,12 +687,15 @@
      * purge removes cancelled tasks from the queue
      */
     public void testPurge() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        ScheduledFuture[] tasks = new ScheduledFuture[5];
-        for (int i = 0; i < tasks.length; i++)
-            tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
-                                  LONG_DELAY_MS, MILLISECONDS);
-        try {
+        final ScheduledFuture[] tasks = new ScheduledFuture[5];
+        final Runnable releaser = new Runnable() { public void run() {
+            for (ScheduledFuture task : tasks)
+                if (task != null) task.cancel(true); }};
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, releaser)) {
+            for (int i = 0; i < tasks.length; i++)
+                tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
+                                      LONG_DELAY_MS, MILLISECONDS);
             int max = tasks.length;
             if (tasks[4].cancel(true)) --max;
             if (tasks[3].cancel(true)) --max;
@@ -699,159 +707,185 @@
                 long count = p.getTaskCount();
                 if (count == max)
                     return;
-            } while (millisElapsedSince(startTime) < MEDIUM_DELAY_MS);
+            } while (millisElapsedSince(startTime) < LONG_DELAY_MS);
             fail("Purge failed to remove cancelled tasks");
-        } finally {
-            for (ScheduledFuture task : tasks)
-                task.cancel(true);
-            joinPool(p);
         }
     }
 
     /**
-     * shutdownNow returns a list containing tasks that were not run
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
      */
-    public void testShutdownNow() {
-        CustomExecutor p = new CustomExecutor(1);
-        for (int i = 0; i < 5; i++)
-            p.schedule(new SmallPossiblyInterruptedRunnable(),
-                       LONG_DELAY_MS, MILLISECONDS);
+    public void testShutdownNow() throws InterruptedException {
+        final int poolSize = 2;
+        final int count = 5;
+        final AtomicInteger ran = new AtomicInteger(0);
+        final CustomExecutor p = new CustomExecutor(poolSize);
+        final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
+        Runnable waiter = new CheckedRunnable() { public void realRun() {
+            threadsStarted.countDown();
+            try {
+                MILLISECONDS.sleep(2 * LONG_DELAY_MS);
+            } catch (InterruptedException success) {}
+            ran.getAndIncrement();
+        }};
+        for (int i = 0; i < count; i++)
+            p.execute(waiter);
+        await(threadsStarted);
+        assertEquals(poolSize, p.getActiveCount());
+        assertEquals(0, p.getCompletedTaskCount());
+        final List<Runnable> queuedTasks;
         try {
-            List<Runnable> l = p.shutdownNow();
-            assertTrue(p.isShutdown());
-            assertEquals(5, l.size());
+            queuedTasks = p.shutdownNow();
         } catch (SecurityException ok) {
-            // Allowed in case test doesn't have privs
-        } finally {
-            joinPool(p);
+            return; // Allowed in case test doesn't have privs
         }
-    }
-
-    /**
-     * In default setting, shutdown cancels periodic but not delayed
-     * tasks at shutdown
-     */
-    public void testShutdown1() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-        assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-
-        ScheduledFuture[] tasks = new ScheduledFuture[5];
-        for (int i = 0; i < tasks.length; i++)
-            tasks[i] = p.schedule(new NoOpRunnable(),
-                                  SHORT_DELAY_MS, MILLISECONDS);
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
-        BlockingQueue<Runnable> q = p.getQueue();
-        for (ScheduledFuture task : tasks) {
-            assertFalse(task.isDone());
-            assertFalse(task.isCancelled());
-            assertTrue(q.contains(task));
-        }
-        assertTrue(p.isShutdown());
-        assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
-        for (ScheduledFuture task : tasks) {
-            assertTrue(task.isDone());
-            assertFalse(task.isCancelled());
-        }
-    }
-
-    /**
-     * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false,
-     * delayed tasks are cancelled at shutdown
-     */
-    public void testShutdown2() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        p.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-        assertFalse(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-        assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-        ScheduledFuture[] tasks = new ScheduledFuture[5];
-        for (int i = 0; i < tasks.length; i++)
-            tasks[i] = p.schedule(new NoOpRunnable(),
-                                  SHORT_DELAY_MS, MILLISECONDS);
-        BlockingQueue q = p.getQueue();
-        assertEquals(tasks.length, q.size());
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
-        assertTrue(p.isShutdown());
-        assertTrue(q.isEmpty());
-        assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
-        for (ScheduledFuture task : tasks) {
-            assertTrue(task.isDone());
-            assertTrue(task.isCancelled());
-        }
-    }
-
-    /**
-     * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false,
-     * periodic tasks are cancelled at shutdown
-     */
-    public void testShutdown3() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-        assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-        p.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
-        assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-        assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-        long initialDelay = LONG_DELAY_MS;
-        ScheduledFuture task =
-            p.scheduleAtFixedRate(new NoOpRunnable(), initialDelay,
-                                  5, MILLISECONDS);
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
         assertTrue(p.isShutdown());
         assertTrue(p.getQueue().isEmpty());
-        assertTrue(task.isDone());
-        assertTrue(task.isCancelled());
-        joinPool(p);
+        assertEquals(count - poolSize, queuedTasks.size());
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(poolSize, ran.get());
+        assertEquals(poolSize, p.getCompletedTaskCount());
     }
 
     /**
-     * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true,
-     * periodic tasks are not cancelled at shutdown
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
      */
-    public void testShutdown4() throws InterruptedException {
-        CustomExecutor p = new CustomExecutor(1);
-        final CountDownLatch counter = new CountDownLatch(2);
+    public void testShutdownNow_delayedTasks() throws InterruptedException {
+        final CustomExecutor p = new CustomExecutor(1);
+        List<ScheduledFuture> tasks = new ArrayList<>();
+        for (int i = 0; i < 3; i++) {
+            Runnable r = new NoOpRunnable();
+            tasks.add(p.schedule(r, 9, SECONDS));
+            tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS));
+            tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS));
+        }
+        if (testImplementationDetails)
+            assertEquals(new HashSet(tasks), new HashSet(p.getQueue()));
+        final List<Runnable> queuedTasks;
         try {
-            p.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
-            assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-            assertTrue(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-            final Runnable r = new CheckedRunnable() {
-                public void realRun() {
-                    counter.countDown();
-                }};
-            ScheduledFuture task =
-                p.scheduleAtFixedRate(r, 1, 1, MILLISECONDS);
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
+        }
+        assertTrue(p.isShutdown());
+        assertTrue(p.getQueue().isEmpty());
+        if (testImplementationDetails)
+            assertEquals(new HashSet(tasks), new HashSet(queuedTasks));
+        assertEquals(tasks.size(), queuedTasks.size());
+        for (ScheduledFuture task : tasks) {
+            assertFalse(((CustomTask)task).ran);
             assertFalse(task.isDone());
             assertFalse(task.isCancelled());
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
-            assertFalse(task.isCancelled());
-            assertFalse(p.isTerminated());
-            assertTrue(p.isShutdown());
-            assertTrue(counter.await(SMALL_DELAY_MS, MILLISECONDS));
-            assertFalse(task.isCancelled());
-            assertTrue(task.cancel(false));
-            assertTrue(task.isDone());
-            assertTrue(task.isCancelled());
-            assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
-            assertTrue(p.isTerminated());
         }
-        finally {
-            joinPool(p);
-        }
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
     }
 
     /**
+     * By default, periodic tasks are cancelled at shutdown.
+     * By default, delayed tasks keep running after shutdown.
+     * Check that changing the default values work:
+     * - setExecuteExistingDelayedTasksAfterShutdownPolicy
+     * - setContinueExistingPeriodicTasksAfterShutdownPolicy
+     */
+    public void testShutdown_cancellation() throws Exception {
+        Boolean[] allBooleans = { null, Boolean.FALSE, Boolean.TRUE };
+        for (Boolean policy : allBooleans)
+    {
+        final int poolSize = 2;
+        final CustomExecutor p = new CustomExecutor(poolSize);
+        final boolean effectiveDelayedPolicy = (policy != Boolean.FALSE);
+        final boolean effectivePeriodicPolicy = (policy == Boolean.TRUE);
+        final boolean effectiveRemovePolicy = (policy == Boolean.TRUE);
+        if (policy != null) {
+            p.setExecuteExistingDelayedTasksAfterShutdownPolicy(policy);
+            p.setContinueExistingPeriodicTasksAfterShutdownPolicy(policy);
+            p.setRemoveOnCancelPolicy(policy);
+        }
+        assertEquals(effectiveDelayedPolicy,
+                     p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+        assertEquals(effectivePeriodicPolicy,
+                     p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+        assertEquals(effectiveRemovePolicy,
+                     p.getRemoveOnCancelPolicy());
+        // Strategy: Wedge the pool with poolSize "blocker" threads
+        final AtomicInteger ran = new AtomicInteger(0);
+        final CountDownLatch poolBlocked = new CountDownLatch(poolSize);
+        final CountDownLatch unblock = new CountDownLatch(1);
+        final CountDownLatch periodicLatch1 = new CountDownLatch(2);
+        final CountDownLatch periodicLatch2 = new CountDownLatch(2);
+        Runnable task = new CheckedRunnable() { public void realRun()
+                                                    throws InterruptedException {
+            poolBlocked.countDown();
+            assertTrue(unblock.await(LONG_DELAY_MS, MILLISECONDS));
+            ran.getAndIncrement();
+        }};
+        List<Future<?>> blockers = new ArrayList<>();
+        List<Future<?>> periodics = new ArrayList<>();
+        List<Future<?>> delayeds = new ArrayList<>();
+        for (int i = 0; i < poolSize; i++)
+            blockers.add(p.submit(task));
+        assertTrue(poolBlocked.await(LONG_DELAY_MS, MILLISECONDS));
+
+        periodics.add(p.scheduleAtFixedRate(countDowner(periodicLatch1),
+                                            1, 1, MILLISECONDS));
+        periodics.add(p.scheduleWithFixedDelay(countDowner(periodicLatch2),
+                                               1, 1, MILLISECONDS));
+        delayeds.add(p.schedule(task, 1, MILLISECONDS));
+
+        assertTrue(p.getQueue().containsAll(periodics));
+        assertTrue(p.getQueue().containsAll(delayeds));
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(p.isShutdown());
+        assertFalse(p.isTerminated());
+        for (Future<?> periodic : periodics) {
+            assertTrue(effectivePeriodicPolicy ^ periodic.isCancelled());
+            assertTrue(effectivePeriodicPolicy ^ periodic.isDone());
+        }
+        for (Future<?> delayed : delayeds) {
+            assertTrue(effectiveDelayedPolicy ^ delayed.isCancelled());
+            assertTrue(effectiveDelayedPolicy ^ delayed.isDone());
+        }
+        if (testImplementationDetails) {
+            assertEquals(effectivePeriodicPolicy,
+                         p.getQueue().containsAll(periodics));
+            assertEquals(effectiveDelayedPolicy,
+                         p.getQueue().containsAll(delayeds));
+        }
+        // Release all pool threads
+        unblock.countDown();
+
+        for (Future<?> delayed : delayeds) {
+            if (effectiveDelayedPolicy) {
+                assertNull(delayed.get());
+            }
+        }
+        if (effectivePeriodicPolicy) {
+            assertTrue(periodicLatch1.await(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(periodicLatch2.await(LONG_DELAY_MS, MILLISECONDS));
+            for (Future<?> periodic : periodics) {
+                assertTrue(periodic.cancel(false));
+                assertTrue(periodic.isCancelled());
+                assertTrue(periodic.isDone());
+            }
+        }
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(2 + (effectiveDelayedPolicy ? 1 : 0), ran.get());
+    }}
+
+    /**
      * completed submit of callable returns result
      */
     public void testSubmitCallable() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new StringTask());
             String result = future.get();
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -859,13 +893,11 @@
      * completed submit of runnable returns successfully
      */
     public void testSubmitRunnable() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<?> future = e.submit(new NoOpRunnable());
             future.get();
             assertTrue(future.isDone());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -873,13 +905,11 @@
      * completed submit of (runnable, result) returns result
      */
     public void testSubmitRunnable2() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
             String result = future.get();
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -887,13 +917,12 @@
      * invokeAny(null) throws NPE
      */
     public void testInvokeAny1() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
-            e.invokeAny(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -901,13 +930,12 @@
      * invokeAny(empty collection) throws IAE
      */
     public void testInvokeAny2() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>());
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -915,18 +943,17 @@
      * invokeAny(c) throws NPE if c has null elements
      */
     public void testInvokeAny3() throws Exception {
-        CountDownLatch latch = new CountDownLatch(1);
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -934,16 +961,16 @@
      * invokeAny(c) throws ExecutionException if no task completes
      */
     public void testInvokeAny4() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -951,15 +978,13 @@
      * invokeAny(c) returns result of some task
      */
     public void testInvokeAny5() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             String result = e.invokeAny(l);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -967,13 +992,12 @@
      * invokeAll(null) throws NPE
      */
     public void testInvokeAll1() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
-            e.invokeAll(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -981,12 +1005,10 @@
      * invokeAll(empty collection) returns empty collection
      */
     public void testInvokeAll2() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -994,16 +1016,15 @@
      * invokeAll(c) throws NPE if c has null elements
      */
     public void testInvokeAll3() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1011,18 +1032,18 @@
      * get of invokeAll(c) throws exception on failed task
      */
     public void testInvokeAll4() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        List<Future<String>> futures = e.invokeAll(l);
-        assertEquals(1, futures.size());
-        try {
-            futures.get(0).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -1030,8 +1051,8 @@
      * invokeAll(c) returns results of all completed tasks
      */
     public void testInvokeAll5() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
@@ -1039,8 +1060,6 @@
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1048,13 +1067,12 @@
      * timed invokeAny(null) throws NPE
      */
     public void testTimedInvokeAny1() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
-            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1062,15 +1080,14 @@
      * timed invokeAny(,,null) throws NPE
      */
     public void testTimedInvokeAnyNullTimeUnit() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1078,13 +1095,12 @@
      * timed invokeAny(empty collection) throws IAE
      */
     public void testTimedInvokeAny2() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -1093,17 +1109,16 @@
      */
     public void testTimedInvokeAny3() throws Exception {
         CountDownLatch latch = new CountDownLatch(1);
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -1111,16 +1126,18 @@
      * timed invokeAny(c) throws ExecutionException if no task completes
      */
     public void testTimedInvokeAny4() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -1128,15 +1145,15 @@
      * timed invokeAny(c) returns result of some task
      */
     public void testTimedInvokeAny5() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -1144,13 +1161,12 @@
      * timed invokeAll(null) throws NPE
      */
     public void testTimedInvokeAll1() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
-            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1158,15 +1174,14 @@
      * timed invokeAll(,,null) throws NPE
      */
     public void testTimedInvokeAllNullTimeUnit() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1174,12 +1189,10 @@
      * timed invokeAll(empty collection) returns empty collection
      */
     public void testTimedInvokeAll2() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1187,16 +1200,15 @@
      * timed invokeAll(c) throws NPE if c has null elements
      */
     public void testTimedInvokeAll3() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1204,19 +1216,19 @@
      * get of element of invokeAll(c) throws exception on failed task
      */
     public void testTimedInvokeAll4() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        List<Future<String>> futures =
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-        assertEquals(1, futures.size());
-        try {
-            futures.get(0).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            List<Future<String>> futures =
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -1224,18 +1236,16 @@
      * timed invokeAll(c) returns results of all completed tasks
      */
     public void testTimedInvokeAll5() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             List<Future<String>> futures =
-                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1243,21 +1253,37 @@
      * timed invokeAll(c) cancels tasks not completed by timeout
      */
     public void testTimedInvokeAll6() throws Exception {
-        ExecutorService e = new CustomExecutor(2);
-        try {
-            List<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
-            l.add(new StringTask());
-            List<Future<String>> futures =
-                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
-            assertEquals(l.size(), futures.size());
-            for (Future future : futures)
-                assertTrue(future.isDone());
-            assertFalse(futures.get(0).isCancelled());
-            assertTrue(futures.get(1).isCancelled());
-        } finally {
-            joinPool(e);
+        for (long timeout = timeoutMillis();;) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Callable<String> waiter = new CheckedCallable<String>() {
+                public String realCall() {
+                    try { done.await(LONG_DELAY_MS, MILLISECONDS); }
+                    catch (InterruptedException ok) {}
+                    return "1"; }};
+            final ExecutorService p = new CustomExecutor(2);
+            try (PoolCleaner cleaner = cleaner(p, done)) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(waiter);
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    p.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                assertTrue(futures.get(1).isCancelled());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals("2", futures.get(2).get());
+                    break;
+                } catch (CancellationException retryWithLongerTimeout) {
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                }
+            }
         }
     }
 
diff --git a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java
index a2e83d0..81f7370 100644
--- a/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ScheduledExecutorTest.java
@@ -9,11 +9,15 @@
 package jsr166;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
@@ -24,7 +28,9 @@
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -37,24 +43,20 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ScheduledExecutorTest.class);
     // }
 
     /**
      * execute successfully executes a runnable
      */
     public void testExecute() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        final Runnable task = new CheckedRunnable() {
-            public void realRun() {
-                done.countDown();
-            }};
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() { done.countDown(); }};
             p.execute(task);
-            assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
-        } finally {
-            joinPool(p);
+            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
         }
     }
 
@@ -62,10 +64,10 @@
      * delayed schedule of callable successfully executes after delay
      */
     public void testSchedule1() throws Exception {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        final long startTime = System.nanoTime();
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
             Callable task = new CheckedCallable<Boolean>() {
                 public Boolean realCall() {
                     done.countDown();
@@ -76,8 +78,6 @@
             assertSame(Boolean.TRUE, f.get());
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
             assertTrue(done.await(0L, MILLISECONDS));
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -85,10 +85,10 @@
      * delayed schedule of runnable successfully executes after delay
      */
     public void testSchedule3() throws Exception {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        final long startTime = System.nanoTime();
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
             Runnable task = new CheckedRunnable() {
                 public void realRun() {
                     done.countDown();
@@ -98,8 +98,6 @@
             await(done);
             assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -107,10 +105,10 @@
      * scheduleAtFixedRate executes runnable after given initial delay
      */
     public void testSchedule4() throws Exception {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        final long startTime = System.nanoTime();
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
             Runnable task = new CheckedRunnable() {
                 public void realRun() {
                     done.countDown();
@@ -122,8 +120,6 @@
             await(done);
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
             f.cancel(true);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -131,10 +127,10 @@
      * scheduleWithFixedDelay executes runnable after given initial delay
      */
     public void testSchedule5() throws Exception {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        final long startTime = System.nanoTime();
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
             Runnable task = new CheckedRunnable() {
                 public void realRun() {
                     done.countDown();
@@ -146,8 +142,6 @@
             await(done);
             assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
             f.cancel(true);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -157,58 +151,77 @@
     }
 
     /**
-     * scheduleAtFixedRate executes series of tasks at given rate
+     * scheduleAtFixedRate executes series of tasks at given rate.
+     * Eventually, it must hold that:
+     *   cycles - 1 <= elapsedMillis/delay < cycles
      */
     public void testFixedRateSequence() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
-                long startTime = System.nanoTime();
-                int cycles = 10;
+                final long startTime = System.nanoTime();
+                final int cycles = 8;
                 final CountDownLatch done = new CountDownLatch(cycles);
-                Runnable task = new CheckedRunnable() {
+                final Runnable task = new CheckedRunnable() {
                     public void realRun() { done.countDown(); }};
-                ScheduledFuture h =
+                final ScheduledFuture periodicTask =
                     p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
-                done.await();
-                h.cancel(true);
-                double normalizedTime =
-                    (double) millisElapsedSince(startTime) / delay;
-                if (normalizedTime >= cycles - 1 &&
-                    normalizedTime <= cycles)
+                final int totalDelayMillis = (cycles - 1) * delay;
+                await(done, totalDelayMillis + LONG_DELAY_MS);
+                periodicTask.cancel(true);
+                final long elapsedMillis = millisElapsedSince(startTime);
+                assertTrue(elapsedMillis >= totalDelayMillis);
+                if (elapsedMillis <= cycles * delay)
                     return;
+                // else retry with longer delay
             }
-            throw new AssertionError("unexpected execution rate");
-        } finally {
-            joinPool(p);
+            fail("unexpected execution rate");
         }
     }
 
     /**
-     * scheduleWithFixedDelay executes series of tasks with given period
+     * scheduleWithFixedDelay executes series of tasks with given period.
+     * Eventually, it must hold that each task starts at least delay and at
+     * most 2 * delay after the termination of the previous task.
      */
     public void testFixedDelaySequence() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
             for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
-                long startTime = System.nanoTime();
-                int cycles = 10;
+                final long startTime = System.nanoTime();
+                final AtomicLong previous = new AtomicLong(startTime);
+                final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
+                final int cycles = 8;
                 final CountDownLatch done = new CountDownLatch(cycles);
-                Runnable task = new CheckedRunnable() {
-                    public void realRun() { done.countDown(); }};
-                ScheduledFuture h =
+                final int d = delay;
+                final Runnable task = new CheckedRunnable() {
+                    public void realRun() {
+                        long now = System.nanoTime();
+                        long elapsedMillis
+                            = NANOSECONDS.toMillis(now - previous.get());
+                        if (done.getCount() == cycles) { // first execution
+                            if (elapsedMillis >= d)
+                                tryLongerDelay.set(true);
+                        } else {
+                            assertTrue(elapsedMillis >= d);
+                            if (elapsedMillis >= 2 * d)
+                                tryLongerDelay.set(true);
+                        }
+                        previous.set(now);
+                        done.countDown();
+                    }};
+                final ScheduledFuture periodicTask =
                     p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
-                done.await();
-                h.cancel(true);
-                double normalizedTime =
-                    (double) millisElapsedSince(startTime) / delay;
-                if (normalizedTime >= cycles - 1 &&
-                    normalizedTime <= cycles)
+                final int totalDelayMillis = (cycles - 1) * delay;
+                await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
+                periodicTask.cancel(true);
+                final long elapsedMillis = millisElapsedSince(startTime);
+                assertTrue(elapsedMillis >= totalDelayMillis);
+                if (!tryLongerDelay.get())
                     return;
+                // else retry with longer delay
             }
-            throw new AssertionError("unexpected execution rate");
-        } finally {
-            joinPool(p);
+            fail("unexpected execution rate");
         }
     }
 
@@ -216,108 +229,107 @@
      * execute(null) throws NPE
      */
     public void testExecuteNull() throws InterruptedException {
-        ScheduledThreadPoolExecutor se = null;
-        try {
-            se = new ScheduledThreadPoolExecutor(1);
-            se.execute(null);
-            shouldThrow();
-        } catch (NullPointerException success) {}
-
-        joinPool(se);
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
     }
 
     /**
      * schedule(null) throws NPE
      */
     public void testScheduleNull() throws InterruptedException {
-        ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
-        try {
-            TrackedCallable callable = null;
-            Future f = se.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {}
-        joinPool(se);
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                TrackedCallable callable = null;
+                Future f = p.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
     }
 
     /**
      * execute throws RejectedExecutionException if shutdown
      */
     public void testSchedule1_RejectedExecutionException() throws InterruptedException {
-        ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
-        try {
-            se.shutdown();
-            se.schedule(new NoOpRunnable(),
-                        MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpRunnable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-
-        joinPool(se);
     }
 
     /**
      * schedule throws RejectedExecutionException if shutdown
      */
     public void testSchedule2_RejectedExecutionException() throws InterruptedException {
-        ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
-        try {
-            se.shutdown();
-            se.schedule(new NoOpCallable(),
-                        MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpCallable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-        joinPool(se);
     }
 
     /**
      * schedule callable throws RejectedExecutionException if shutdown
      */
     public void testSchedule3_RejectedExecutionException() throws InterruptedException {
-        ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
-        try {
-            se.shutdown();
-            se.schedule(new NoOpCallable(),
-                        MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpCallable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-        joinPool(se);
     }
 
     /**
      * scheduleAtFixedRate throws RejectedExecutionException if shutdown
      */
     public void testScheduleAtFixedRate1_RejectedExecutionException() throws InterruptedException {
-        ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
-        try {
-            se.shutdown();
-            se.scheduleAtFixedRate(new NoOpRunnable(),
-                                   MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.scheduleAtFixedRate(new NoOpRunnable(),
+                                      MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-        joinPool(se);
     }
 
     /**
      * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
      */
     public void testScheduleWithFixedDelay1_RejectedExecutionException() throws InterruptedException {
-        ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
-        try {
-            se.shutdown();
-            se.scheduleWithFixedDelay(new NoOpRunnable(),
-                                      MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (RejectedExecutionException success) {
-        } catch (SecurityException ok) {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.scheduleWithFixedDelay(new NoOpRunnable(),
+                                         MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
         }
-        joinPool(se);
     }
 
     /**
@@ -325,22 +337,19 @@
      * thread becomes active
      */
     public void testGetActiveCount() throws InterruptedException {
-        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(2);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertEquals(0, p.getActiveCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertEquals(1, p.getActiveCount());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getActiveCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -350,10 +359,10 @@
      */
     public void testGetCompletedTaskCount() throws InterruptedException {
         final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(2);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch threadProceed = new CountDownLatch(1);
-        final CountDownLatch threadDone = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch threadProceed = new CountDownLatch(1);
+            final CountDownLatch threadDone = new CountDownLatch(1);
             assertEquals(0, p.getCompletedTaskCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
@@ -372,8 +381,6 @@
                     fail("timed out");
                 Thread.yield();
             }
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -382,8 +389,9 @@
      */
     public void testGetCorePoolSize() throws InterruptedException {
         ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        assertEquals(1, p.getCorePoolSize());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getCorePoolSize());
+        }
     }
 
     /**
@@ -395,22 +403,19 @@
         final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(THREADS);
         final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             assertEquals(0, p.getLargestPoolSize());
             for (int i = 0; i < THREADS; i++)
                 p.execute(new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadsStarted.countDown();
-                        done.await();
+                        await(done);
                         assertEquals(THREADS, p.getLargestPoolSize());
                     }});
-            assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
-            assertEquals(THREADS, p.getLargestPoolSize());
-        } finally {
-            done.countDown();
-            joinPool(p);
+            await(threadsStarted);
             assertEquals(THREADS, p.getLargestPoolSize());
         }
+        assertEquals(THREADS, p.getLargestPoolSize());
     }
 
     /**
@@ -421,19 +426,16 @@
         final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
         final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             assertEquals(0, p.getPoolSize());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertEquals(1, p.getPoolSize());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getPoolSize());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -442,58 +444,71 @@
      * submitted
      */
     public void testGetTaskCount() throws InterruptedException {
-        final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
+        final int TASKS = 3;
         final CountDownLatch done = new CountDownLatch(1);
-        final int TASKS = 5;
-        try {
+        final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertEquals(0, p.getTaskCount());
-            for (int i = 0; i < TASKS; i++)
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            for (int i = 0; i < TASKS; i++) {
+                assertEquals(1 + i, p.getTaskCount());
                 p.execute(new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadStarted.countDown();
-                        done.await();
+                        assertEquals(1 + TASKS, p.getTaskCount());
+                        await(done);
                     }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
-            assertEquals(TASKS, p.getTaskCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
+            }
+            assertEquals(1 + TASKS, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
         }
+        assertEquals(1 + TASKS, p.getTaskCount());
+        assertEquals(1 + TASKS, p.getCompletedTaskCount());
     }
 
     /**
      * getThreadFactory returns factory in constructor if not set
      */
     public void testGetThreadFactory() throws InterruptedException {
-        ThreadFactory tf = new SimpleThreadFactory();
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1, tf);
-        assertSame(tf, p.getThreadFactory());
-        joinPool(p);
+        final ThreadFactory threadFactory = new SimpleThreadFactory();
+        final ScheduledThreadPoolExecutor p =
+            new ScheduledThreadPoolExecutor(1, threadFactory);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(threadFactory, p.getThreadFactory());
+        }
     }
 
     /**
      * setThreadFactory sets the thread factory returned by getThreadFactory
      */
     public void testSetThreadFactory() throws InterruptedException {
-        ThreadFactory tf = new SimpleThreadFactory();
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        p.setThreadFactory(tf);
-        assertSame(tf, p.getThreadFactory());
-        joinPool(p);
+        ThreadFactory threadFactory = new SimpleThreadFactory();
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            p.setThreadFactory(threadFactory);
+            assertSame(threadFactory, p.getThreadFactory());
+        }
     }
 
     /**
      * setThreadFactory(null) throws NPE
      */
     public void testSetThreadFactoryNull() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        try {
-            p.setThreadFactory(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(p);
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setThreadFactory(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -502,7 +517,7 @@
      */
     public void testIsShutdown() {
 
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
         try {
             assertFalse(p.isShutdown());
         }
@@ -517,24 +532,23 @@
      */
     public void testIsTerminated() throws InterruptedException {
         final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        assertFalse(p.isTerminated());
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
+            assertFalse(p.isTerminated());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     assertFalse(p.isTerminated());
                     threadStarted.countDown();
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertFalse(p.isTerminating());
             done.countDown();
-        } finally {
             try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
         }
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
     }
 
     /**
@@ -544,49 +558,45 @@
         final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
         final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             assertFalse(p.isTerminating());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     assertFalse(p.isTerminating());
                     threadStarted.countDown();
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertFalse(p.isTerminating());
             done.countDown();
-        } finally {
             try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
         }
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
-        assertFalse(p.isTerminating());
     }
 
     /**
      * getQueue returns the work queue, which contains queued tasks
      */
     public void testGetQueue() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             ScheduledFuture[] tasks = new ScheduledFuture[5];
             for (int i = 0; i < tasks.length; i++) {
                 Runnable r = new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadStarted.countDown();
-                        done.await();
+                        await(done);
                     }};
                 tasks[i] = p.schedule(r, 1, MILLISECONDS);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             BlockingQueue<Runnable> q = p.getQueue();
             assertTrue(q.contains(tasks[tasks.length - 1]));
             assertFalse(q.contains(tasks[0]));
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -594,20 +604,20 @@
      * remove(task) removes queued task, and fails to remove active task
      */
     public void testRemove() throws InterruptedException {
-        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        ScheduledFuture[] tasks = new ScheduledFuture[5];
-        final CountDownLatch threadStarted = new CountDownLatch(1);
         final CountDownLatch done = new CountDownLatch(1);
-        try {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            ScheduledFuture[] tasks = new ScheduledFuture[5];
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             for (int i = 0; i < tasks.length; i++) {
                 Runnable r = new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadStarted.countDown();
-                        done.await();
+                        await(done);
                     }};
                 tasks[i] = p.schedule(r, 1, MILLISECONDS);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             BlockingQueue<Runnable> q = p.getQueue();
             assertFalse(p.remove((Runnable)tasks[0]));
             assertTrue(q.contains((Runnable)tasks[4]));
@@ -618,9 +628,6 @@
             assertTrue(q.contains((Runnable)tasks[3]));
             assertTrue(p.remove((Runnable)tasks[3]));
             assertFalse(q.contains((Runnable)tasks[3]));
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -628,12 +635,15 @@
      * purge eventually removes cancelled tasks from the queue
      */
     public void testPurge() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        ScheduledFuture[] tasks = new ScheduledFuture[5];
-        for (int i = 0; i < tasks.length; i++)
-            tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
-                                  LONG_DELAY_MS, MILLISECONDS);
-        try {
+        final ScheduledFuture[] tasks = new ScheduledFuture[5];
+        final Runnable releaser = new Runnable() { public void run() {
+            for (ScheduledFuture task : tasks)
+                if (task != null) task.cancel(true); }};
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, releaser)) {
+            for (int i = 0; i < tasks.length; i++)
+                tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
+                                      LONG_DELAY_MS, MILLISECONDS);
             int max = tasks.length;
             if (tasks[4].cancel(true)) --max;
             if (tasks[3].cancel(true)) --max;
@@ -645,159 +655,186 @@
                 long count = p.getTaskCount();
                 if (count == max)
                     return;
-            } while (millisElapsedSince(startTime) < MEDIUM_DELAY_MS);
+            } while (millisElapsedSince(startTime) < LONG_DELAY_MS);
             fail("Purge failed to remove cancelled tasks");
-        } finally {
-            for (ScheduledFuture task : tasks)
-                task.cancel(true);
-            joinPool(p);
         }
     }
 
     /**
-     * shutdownNow returns a list containing tasks that were not run
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
      */
-    public void testShutdownNow() {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        for (int i = 0; i < 5; i++)
-            p.schedule(new SmallPossiblyInterruptedRunnable(),
-                       LONG_DELAY_MS, MILLISECONDS);
+    public void testShutdownNow() throws InterruptedException {
+        final int poolSize = 2;
+        final int count = 5;
+        final AtomicInteger ran = new AtomicInteger(0);
+        final ScheduledThreadPoolExecutor p =
+            new ScheduledThreadPoolExecutor(poolSize);
+        final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
+        Runnable waiter = new CheckedRunnable() { public void realRun() {
+            threadsStarted.countDown();
+            try {
+                MILLISECONDS.sleep(2 * LONG_DELAY_MS);
+            } catch (InterruptedException success) {}
+            ran.getAndIncrement();
+        }};
+        for (int i = 0; i < count; i++)
+            p.execute(waiter);
+        await(threadsStarted);
+        assertEquals(poolSize, p.getActiveCount());
+        assertEquals(0, p.getCompletedTaskCount());
+        final List<Runnable> queuedTasks;
         try {
-            List<Runnable> l = p.shutdownNow();
-            assertTrue(p.isShutdown());
-            assertEquals(5, l.size());
+            queuedTasks = p.shutdownNow();
         } catch (SecurityException ok) {
-            // Allowed in case test doesn't have privs
-        } finally {
-            joinPool(p);
+            return; // Allowed in case test doesn't have privs
         }
-    }
-
-    /**
-     * In default setting, shutdown cancels periodic but not delayed
-     * tasks at shutdown
-     */
-    public void testShutdown1() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-        assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-
-        ScheduledFuture[] tasks = new ScheduledFuture[5];
-        for (int i = 0; i < tasks.length; i++)
-            tasks[i] = p.schedule(new NoOpRunnable(),
-                                  SHORT_DELAY_MS, MILLISECONDS);
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
-        BlockingQueue<Runnable> q = p.getQueue();
-        for (ScheduledFuture task : tasks) {
-            assertFalse(task.isDone());
-            assertFalse(task.isCancelled());
-            assertTrue(q.contains(task));
-        }
-        assertTrue(p.isShutdown());
-        assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
-        for (ScheduledFuture task : tasks) {
-            assertTrue(task.isDone());
-            assertFalse(task.isCancelled());
-        }
-    }
-
-    /**
-     * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false,
-     * delayed tasks are cancelled at shutdown
-     */
-    public void testShutdown2() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        p.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-        assertFalse(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-        assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-        ScheduledFuture[] tasks = new ScheduledFuture[5];
-        for (int i = 0; i < tasks.length; i++)
-            tasks[i] = p.schedule(new NoOpRunnable(),
-                                  SHORT_DELAY_MS, MILLISECONDS);
-        BlockingQueue q = p.getQueue();
-        assertEquals(tasks.length, q.size());
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
-        assertTrue(p.isShutdown());
-        assertTrue(q.isEmpty());
-        assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
-        for (ScheduledFuture task : tasks) {
-            assertTrue(task.isDone());
-            assertTrue(task.isCancelled());
-        }
-    }
-
-    /**
-     * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false,
-     * periodic tasks are cancelled at shutdown
-     */
-    public void testShutdown3() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-        assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-        p.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
-        assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-        assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-        long initialDelay = LONG_DELAY_MS;
-        ScheduledFuture task =
-            p.scheduleAtFixedRate(new NoOpRunnable(), initialDelay,
-                                  5, MILLISECONDS);
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
         assertTrue(p.isShutdown());
         assertTrue(p.getQueue().isEmpty());
-        assertTrue(task.isDone());
-        assertTrue(task.isCancelled());
-        joinPool(p);
+        assertEquals(count - poolSize, queuedTasks.size());
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(poolSize, ran.get());
+        assertEquals(poolSize, p.getCompletedTaskCount());
     }
 
     /**
-     * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true,
-     * periodic tasks are not cancelled at shutdown
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
      */
-    public void testShutdown4() throws InterruptedException {
-        ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
-        final CountDownLatch counter = new CountDownLatch(2);
+    public void testShutdownNow_delayedTasks() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        List<ScheduledFuture> tasks = new ArrayList<>();
+        for (int i = 0; i < 3; i++) {
+            Runnable r = new NoOpRunnable();
+            tasks.add(p.schedule(r, 9, SECONDS));
+            tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS));
+            tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS));
+        }
+        if (testImplementationDetails)
+            assertEquals(new HashSet(tasks), new HashSet(p.getQueue()));
+        final List<Runnable> queuedTasks;
         try {
-            p.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
-            assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-            assertTrue(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
-            final Runnable r = new CheckedRunnable() {
-                public void realRun() {
-                    counter.countDown();
-                }};
-            ScheduledFuture task =
-                p.scheduleAtFixedRate(r, 1, 1, MILLISECONDS);
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
+        }
+        assertTrue(p.isShutdown());
+        assertTrue(p.getQueue().isEmpty());
+        if (testImplementationDetails)
+            assertEquals(new HashSet(tasks), new HashSet(queuedTasks));
+        assertEquals(tasks.size(), queuedTasks.size());
+        for (ScheduledFuture task : tasks) {
             assertFalse(task.isDone());
             assertFalse(task.isCancelled());
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
-            assertFalse(task.isCancelled());
-            assertFalse(p.isTerminated());
-            assertTrue(p.isShutdown());
-            assertTrue(counter.await(SMALL_DELAY_MS, MILLISECONDS));
-            assertFalse(task.isCancelled());
-            assertTrue(task.cancel(false));
-            assertTrue(task.isDone());
-            assertTrue(task.isCancelled());
-            assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
-            assertTrue(p.isTerminated());
         }
-        finally {
-            joinPool(p);
-        }
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
     }
 
     /**
+     * By default, periodic tasks are cancelled at shutdown.
+     * By default, delayed tasks keep running after shutdown.
+     * Check that changing the default values work:
+     * - setExecuteExistingDelayedTasksAfterShutdownPolicy
+     * - setContinueExistingPeriodicTasksAfterShutdownPolicy
+     */
+    public void testShutdown_cancellation() throws Exception {
+        Boolean[] allBooleans = { null, Boolean.FALSE, Boolean.TRUE };
+        for (Boolean policy : allBooleans)
+    {
+        final int poolSize = 2;
+        final ScheduledThreadPoolExecutor p
+            = new ScheduledThreadPoolExecutor(poolSize);
+        final boolean effectiveDelayedPolicy = (policy != Boolean.FALSE);
+        final boolean effectivePeriodicPolicy = (policy == Boolean.TRUE);
+        final boolean effectiveRemovePolicy = (policy == Boolean.TRUE);
+        if (policy != null) {
+            p.setExecuteExistingDelayedTasksAfterShutdownPolicy(policy);
+            p.setContinueExistingPeriodicTasksAfterShutdownPolicy(policy);
+            p.setRemoveOnCancelPolicy(policy);
+        }
+        assertEquals(effectiveDelayedPolicy,
+                     p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+        assertEquals(effectivePeriodicPolicy,
+                     p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+        assertEquals(effectiveRemovePolicy,
+                     p.getRemoveOnCancelPolicy());
+        // Strategy: Wedge the pool with poolSize "blocker" threads
+        final AtomicInteger ran = new AtomicInteger(0);
+        final CountDownLatch poolBlocked = new CountDownLatch(poolSize);
+        final CountDownLatch unblock = new CountDownLatch(1);
+        final CountDownLatch periodicLatch1 = new CountDownLatch(2);
+        final CountDownLatch periodicLatch2 = new CountDownLatch(2);
+        Runnable task = new CheckedRunnable() { public void realRun()
+                                                    throws InterruptedException {
+            poolBlocked.countDown();
+            assertTrue(unblock.await(LONG_DELAY_MS, MILLISECONDS));
+            ran.getAndIncrement();
+        }};
+        List<Future<?>> blockers = new ArrayList<>();
+        List<Future<?>> periodics = new ArrayList<>();
+        List<Future<?>> delayeds = new ArrayList<>();
+        for (int i = 0; i < poolSize; i++)
+            blockers.add(p.submit(task));
+        assertTrue(poolBlocked.await(LONG_DELAY_MS, MILLISECONDS));
+
+        periodics.add(p.scheduleAtFixedRate(countDowner(periodicLatch1),
+                                            1, 1, MILLISECONDS));
+        periodics.add(p.scheduleWithFixedDelay(countDowner(periodicLatch2),
+                                               1, 1, MILLISECONDS));
+        delayeds.add(p.schedule(task, 1, MILLISECONDS));
+
+        assertTrue(p.getQueue().containsAll(periodics));
+        assertTrue(p.getQueue().containsAll(delayeds));
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(p.isShutdown());
+        assertFalse(p.isTerminated());
+        for (Future<?> periodic : periodics) {
+            assertTrue(effectivePeriodicPolicy ^ periodic.isCancelled());
+            assertTrue(effectivePeriodicPolicy ^ periodic.isDone());
+        }
+        for (Future<?> delayed : delayeds) {
+            assertTrue(effectiveDelayedPolicy ^ delayed.isCancelled());
+            assertTrue(effectiveDelayedPolicy ^ delayed.isDone());
+        }
+        if (testImplementationDetails) {
+            assertEquals(effectivePeriodicPolicy,
+                         p.getQueue().containsAll(periodics));
+            assertEquals(effectiveDelayedPolicy,
+                         p.getQueue().containsAll(delayeds));
+        }
+        // Release all pool threads
+        unblock.countDown();
+
+        for (Future<?> delayed : delayeds) {
+            if (effectiveDelayedPolicy) {
+                assertNull(delayed.get());
+            }
+        }
+        if (effectivePeriodicPolicy) {
+            assertTrue(periodicLatch1.await(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(periodicLatch2.await(LONG_DELAY_MS, MILLISECONDS));
+            for (Future<?> periodic : periodics) {
+                assertTrue(periodic.cancel(false));
+                assertTrue(periodic.isCancelled());
+                assertTrue(periodic.isDone());
+            }
+        }
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(2 + (effectiveDelayedPolicy ? 1 : 0), ran.get());
+    }}
+
+    /**
      * completed submit of callable returns result
      */
     public void testSubmitCallable() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new StringTask());
             String result = future.get();
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -805,13 +842,11 @@
      * completed submit of runnable returns successfully
      */
     public void testSubmitRunnable() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<?> future = e.submit(new NoOpRunnable());
             future.get();
             assertTrue(future.isDone());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -819,13 +854,11 @@
      * completed submit of (runnable, result) returns result
      */
     public void testSubmitRunnable2() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
             String result = future.get();
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -833,13 +866,12 @@
      * invokeAny(null) throws NPE
      */
     public void testInvokeAny1() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
-            e.invokeAny(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -847,13 +879,12 @@
      * invokeAny(empty collection) throws IAE
      */
     public void testInvokeAny2() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>());
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -862,17 +893,16 @@
      */
     public void testInvokeAny3() throws Exception {
         CountDownLatch latch = new CountDownLatch(1);
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -880,16 +910,16 @@
      * invokeAny(c) throws ExecutionException if no task completes
      */
     public void testInvokeAny4() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -897,15 +927,13 @@
      * invokeAny(c) returns result of some task
      */
     public void testInvokeAny5() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             String result = e.invokeAny(l);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -913,13 +941,12 @@
      * invokeAll(null) throws NPE
      */
     public void testInvokeAll1() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
-            e.invokeAll(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -927,12 +954,10 @@
      * invokeAll(empty collection) returns empty collection
      */
     public void testInvokeAll2() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -940,16 +965,15 @@
      * invokeAll(c) throws NPE if c has null elements
      */
     public void testInvokeAll3() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -957,18 +981,18 @@
      * get of invokeAll(c) throws exception on failed task
      */
     public void testInvokeAll4() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        List<Future<String>> futures = e.invokeAll(l);
-        assertEquals(1, futures.size());
-        try {
-            futures.get(0).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -976,8 +1000,8 @@
      * invokeAll(c) returns results of all completed tasks
      */
     public void testInvokeAll5() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
@@ -985,8 +1009,6 @@
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -994,13 +1016,12 @@
      * timed invokeAny(null) throws NPE
      */
     public void testTimedInvokeAny1() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
-            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1008,15 +1029,14 @@
      * timed invokeAny(,,null) throws NPE
      */
     public void testTimedInvokeAnyNullTimeUnit() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1024,13 +1044,12 @@
      * timed invokeAny(empty collection) throws IAE
      */
     public void testTimedInvokeAny2() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -1039,17 +1058,16 @@
      */
     public void testTimedInvokeAny3() throws Exception {
         CountDownLatch latch = new CountDownLatch(1);
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -1057,16 +1075,18 @@
      * timed invokeAny(c) throws ExecutionException if no task completes
      */
     public void testTimedInvokeAny4() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -1074,15 +1094,15 @@
      * timed invokeAny(c) returns result of some task
      */
     public void testTimedInvokeAny5() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -1090,13 +1110,12 @@
      * timed invokeAll(null) throws NPE
      */
     public void testTimedInvokeAll1() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
-            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1104,15 +1123,14 @@
      * timed invokeAll(,,null) throws NPE
      */
     public void testTimedInvokeAllNullTimeUnit() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1120,12 +1138,11 @@
      * timed invokeAll(empty collection) returns empty collection
      */
     public void testTimedInvokeAll2() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
-            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(),
+                                                 MEDIUM_DELAY_MS, MILLISECONDS);
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1133,16 +1150,15 @@
      * timed invokeAll(c) throws NPE if c has null elements
      */
     public void testTimedInvokeAll3() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1150,19 +1166,19 @@
      * get of element of invokeAll(c) throws exception on failed task
      */
     public void testTimedInvokeAll4() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        List<Future<String>> futures =
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-        assertEquals(1, futures.size());
-        try {
-            futures.get(0).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -1170,18 +1186,16 @@
      * timed invokeAll(c) returns results of all completed tasks
      */
     public void testTimedInvokeAll5() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             List<Future<String>> futures =
-                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1189,21 +1203,60 @@
      * timed invokeAll(c) cancels tasks not completed by timeout
      */
     public void testTimedInvokeAll6() throws Exception {
-        ExecutorService e = new ScheduledThreadPoolExecutor(2);
-        try {
-            List<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
-            l.add(new StringTask());
-            List<Future<String>> futures =
-                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
-            assertEquals(l.size(), futures.size());
-            for (Future future : futures)
-                assertTrue(future.isDone());
-            assertFalse(futures.get(0).isCancelled());
-            assertTrue(futures.get(1).isCancelled());
-        } finally {
-            joinPool(e);
+        for (long timeout = timeoutMillis();;) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Callable<String> waiter = new CheckedCallable<String>() {
+                public String realCall() {
+                    try { done.await(LONG_DELAY_MS, MILLISECONDS); }
+                    catch (InterruptedException ok) {}
+                    return "1"; }};
+            final ExecutorService p = new ScheduledThreadPoolExecutor(2);
+            try (PoolCleaner cleaner = cleaner(p, done)) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(waiter);
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    p.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                assertTrue(futures.get(1).isCancelled());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals("2", futures.get(2).get());
+                    break;
+                } catch (CancellationException retryWithLongerTimeout) {
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                }
+            }
+        }
+    }
+
+    /**
+     * A fixed delay task with overflowing period should not prevent a
+     * one-shot task from executing.
+     * https://bugs.openjdk.java.net/browse/JDK-8051859
+     */
+    public void testScheduleWithFixedDelay_overflow() throws Exception {
+        final CountDownLatch delayedDone = new CountDownLatch(1);
+        final CountDownLatch immediateDone = new CountDownLatch(1);
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final Runnable immediate = new Runnable() { public void run() {
+                immediateDone.countDown();
+            }};
+            final Runnable delayed = new Runnable() { public void run() {
+                delayedDone.countDown();
+                p.submit(immediate);
+            }};
+            p.scheduleWithFixedDelay(delayed, 0L, Long.MAX_VALUE, SECONDS);
+            await(delayedDone);
+            await(immediateDone);
         }
     }
 
diff --git a/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java b/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java
index db4f4b4..09c82c8 100644
--- a/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java
+++ b/jsr166-tests/src/test/java/jsr166/SemaphoreTest.java
@@ -26,8 +26,9 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(SemaphoreTest.class);
     // }
+
     /**
      * Subclass to expose protected methods
      */
@@ -471,11 +472,16 @@
             clone.release();
             assertEquals(2, s.availablePermits());
             assertEquals(1, clone.availablePermits());
+            assertFalse(s.hasQueuedThreads());
+            assertFalse(clone.hasQueuedThreads());
+        } catch (InterruptedException e) { threadUnexpectedException(e); }
 
-            s = new Semaphore(0, fair);
+        {
+            PublicSemaphore s = new PublicSemaphore(0, fair);
             Thread t = newStartedThread(new InterruptibleLockRunnable(s));
-            waitForQueuedThreads(s);
-            clone = serialClone(s);
+            // waitForQueuedThreads(s); // suffers from "flicker", so ...
+            waitForQueuedThread(s, t);  // ... we use this instead
+            PublicSemaphore clone = serialClone(s);
             assertEquals(fair, s.isFair());
             assertEquals(fair, clone.isFair());
             assertEquals(0, s.availablePermits());
@@ -486,7 +492,7 @@
             awaitTermination(t);
             assertFalse(s.hasQueuedThreads());
             assertFalse(clone.hasQueuedThreads());
-        } catch (InterruptedException e) { threadUnexpectedException(e); }
+        }
     }
 
     /**
@@ -594,7 +600,7 @@
                 s.acquire(3);
             }});
 
-        waitForQueuedThreads(s);
+        waitForQueuedThread(s, t1);
 
         Thread t2 = newStartedThread(new CheckedRunnable() {
             public void realRun() throws InterruptedException {
diff --git a/jsr166-tests/src/test/java/jsr166/StampedLockTest.java b/jsr166-tests/src/test/java/jsr166/StampedLockTest.java
new file mode 100644
index 0000000..d347c7d
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/StampedLockTest.java
@@ -0,0 +1,884 @@
+/*
+ * Written by Doug Lea and Martin Buchholz
+ * 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 jsr166;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.StampedLock;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class StampedLockTest extends JSR166TestCase {
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(StampedLockTest.class);
+    // }
+
+    /**
+     * A runnable calling writeLockInterruptibly
+     */
+    class InterruptibleLockRunnable extends CheckedRunnable {
+        final StampedLock lock;
+        InterruptibleLockRunnable(StampedLock l) { lock = l; }
+        public void realRun() throws InterruptedException {
+            lock.writeLockInterruptibly();
+        }
+    }
+
+    /**
+     * A runnable calling writeLockInterruptibly that expects to be
+     * interrupted
+     */
+    class InterruptedLockRunnable extends CheckedInterruptedRunnable {
+        final StampedLock lock;
+        InterruptedLockRunnable(StampedLock l) { lock = l; }
+        public void realRun() throws InterruptedException {
+            lock.writeLockInterruptibly();
+        }
+    }
+
+    /**
+     * Releases write lock, checking isWriteLocked before and after
+     */
+    void releaseWriteLock(StampedLock lock, long s) {
+        assertTrue(lock.isWriteLocked());
+        lock.unlockWrite(s);
+        assertFalse(lock.isWriteLocked());
+    }
+
+    /**
+     * Constructed StampedLock is in unlocked state
+     */
+    public void testConstructor() {
+        StampedLock lock;
+        lock = new StampedLock();
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+    }
+
+    /**
+     * write-locking and read-locking an unlocked lock succeed
+     */
+    public void testLock() {
+        StampedLock lock = new StampedLock();
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+        long s = lock.writeLock();
+        assertTrue(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+        lock.unlockWrite(s);
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+        long rs = lock.readLock();
+        assertFalse(lock.isWriteLocked());
+        assertTrue(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 1);
+        lock.unlockRead(rs);
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+    }
+
+    /**
+     * unlock releases either a read or write lock
+     */
+    public void testUnlock() {
+        StampedLock lock = new StampedLock();
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+        long s = lock.writeLock();
+        assertTrue(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+        lock.unlock(s);
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+        long rs = lock.readLock();
+        assertFalse(lock.isWriteLocked());
+        assertTrue(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 1);
+        lock.unlock(rs);
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+    }
+
+    /**
+     * tryUnlockRead/Write succeeds if locked in associated mode else
+     * returns false
+     */
+    public void testTryUnlock() {
+        StampedLock lock = new StampedLock();
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+        long s = lock.writeLock();
+        assertTrue(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+        assertFalse(lock.tryUnlockRead());
+        assertTrue(lock.tryUnlockWrite());
+        assertFalse(lock.tryUnlockWrite());
+        assertFalse(lock.tryUnlockRead());
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+        long rs = lock.readLock();
+        assertFalse(lock.isWriteLocked());
+        assertTrue(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 1);
+        assertFalse(lock.tryUnlockWrite());
+        assertTrue(lock.tryUnlockRead());
+        assertFalse(lock.tryUnlockRead());
+        assertFalse(lock.tryUnlockWrite());
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        assertEquals(lock.getReadLockCount(), 0);
+    }
+
+    /**
+     * write-unlocking an unlocked lock throws IllegalMonitorStateException
+     */
+    public void testWriteUnlock_IMSE() {
+        StampedLock lock = new StampedLock();
+        try {
+            lock.unlockWrite(0L);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * write-unlocking an unlocked lock throws IllegalMonitorStateException
+     */
+    public void testWriteUnlock_IMSE2() {
+        StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        lock.unlockWrite(s);
+        try {
+            lock.unlockWrite(s);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * write-unlocking after readlock throws IllegalMonitorStateException
+     */
+    public void testWriteUnlock_IMSE3() {
+        StampedLock lock = new StampedLock();
+        long s = lock.readLock();
+        try {
+            lock.unlockWrite(s);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * read-unlocking an unlocked lock throws IllegalMonitorStateException
+     */
+    public void testReadUnlock_IMSE() {
+        StampedLock lock = new StampedLock();
+        long s = lock.readLock();
+        lock.unlockRead(s);
+        try {
+            lock.unlockRead(s);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * read-unlocking an unlocked lock throws IllegalMonitorStateException
+     */
+    public void testReadUnlock_IMSE2() {
+        StampedLock lock = new StampedLock();
+        try {
+            lock.unlockRead(0L);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * read-unlocking after writeLock throws IllegalMonitorStateException
+     */
+    public void testReadUnlock_IMSE3() {
+        StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        try {
+            lock.unlockRead(s);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * validate(0) fails
+     */
+    public void testValidate0() {
+        StampedLock lock = new StampedLock();
+        assertFalse(lock.validate(0L));
+    }
+
+    /**
+     * A stamp obtained from a successful lock operation validates
+     */
+    public void testValidate() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        assertTrue(lock.validate(s));
+        lock.unlockWrite(s);
+        s = lock.readLock();
+        assertTrue(lock.validate(s));
+        lock.unlockRead(s);
+        assertTrue((s = lock.tryWriteLock()) != 0L);
+        assertTrue(lock.validate(s));
+        lock.unlockWrite(s);
+        assertTrue((s = lock.tryReadLock()) != 0L);
+        assertTrue(lock.validate(s));
+        lock.unlockRead(s);
+        assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+        assertTrue(lock.validate(s));
+        lock.unlockWrite(s);
+        assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+        assertTrue(lock.validate(s));
+        lock.unlockRead(s);
+        assertTrue((s = lock.tryOptimisticRead()) != 0L);
+    }
+
+    /**
+     * A stamp obtained from an unsuccessful lock operation does not validate
+     */
+    public void testValidate2() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s;
+        assertTrue((s = lock.writeLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertFalse(lock.validate(lock.tryWriteLock()));
+        assertFalse(lock.validate(lock.tryWriteLock(10L, MILLISECONDS)));
+        assertFalse(lock.validate(lock.tryReadLock()));
+        assertFalse(lock.validate(lock.tryReadLock(10L, MILLISECONDS)));
+        assertFalse(lock.validate(lock.tryOptimisticRead()));
+        lock.unlockWrite(s);
+    }
+
+    /**
+     * writeLockInterruptibly is interruptible
+     */
+    public void testWriteLockInterruptibly_Interruptible()
+            throws InterruptedException {
+        final CountDownLatch running = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                running.countDown();
+                lock.writeLockInterruptibly();
+            }});
+
+        running.await();
+        waitForThreadToEnterWaitState(t, 100);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * timed tryWriteLock is interruptible
+     */
+    public void testWriteTryLock_Interruptible() throws InterruptedException {
+        final CountDownLatch running = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                running.countDown();
+                lock.tryWriteLock(2 * LONG_DELAY_MS, MILLISECONDS);
+            }});
+
+        running.await();
+        waitForThreadToEnterWaitState(t, 100);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * readLockInterruptibly is interruptible
+     */
+    public void testReadLockInterruptibly_Interruptible()
+            throws InterruptedException {
+        final CountDownLatch running = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                running.countDown();
+                lock.readLockInterruptibly();
+            }});
+
+        running.await();
+        waitForThreadToEnterWaitState(t, 100);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * timed tryReadLock is interruptible
+     */
+    public void testReadTryLock_Interruptible() throws InterruptedException {
+        final CountDownLatch running = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                running.countDown();
+                lock.tryReadLock(2 * LONG_DELAY_MS, MILLISECONDS);
+            }});
+
+        running.await();
+        waitForThreadToEnterWaitState(t, 100);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * tryWriteLock on an unlocked lock succeeds
+     */
+    public void testWriteTryLock() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.tryWriteLock();
+        assertTrue(s != 0L);
+        assertTrue(lock.isWriteLocked());
+        long s2 = lock.tryWriteLock();
+        assertEquals(s2, 0L);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * tryWriteLock fails if locked
+     */
+    public void testWriteTryLockWhenLocked() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long ws = lock.tryWriteLock();
+                assertTrue(ws == 0L);
+            }});
+
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * tryReadLock fails if write-locked
+     */
+    public void testReadTryLockWhenLocked() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long rs = lock.tryReadLock();
+                assertEquals(rs, 0L);
+            }});
+
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * Multiple threads can hold a read lock when not write-locked
+     */
+    public void testMultipleReadLocks() {
+        final StampedLock lock = new StampedLock();
+        final long s = lock.readLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long s2 = lock.tryReadLock();
+                assertTrue(s2 != 0L);
+                lock.unlockRead(s2);
+                long s3 = lock.tryReadLock(LONG_DELAY_MS, MILLISECONDS);
+                assertTrue(s3 != 0L);
+                lock.unlockRead(s3);
+                long s4 = lock.readLock();
+                lock.unlockRead(s4);
+            }});
+
+        awaitTermination(t);
+        lock.unlockRead(s);
+    }
+
+    /**
+     * A writelock succeeds only after a reading thread unlocks
+     */
+    public void testWriteAfterReadLock() throws InterruptedException {
+        final CountDownLatch running = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        long rs = lock.readLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                running.countDown();
+                long s = lock.writeLock();
+                lock.unlockWrite(s);
+            }});
+
+        running.await();
+        waitForThreadToEnterWaitState(t, 100);
+        assertFalse(lock.isWriteLocked());
+        lock.unlockRead(rs);
+        awaitTermination(t);
+        assertFalse(lock.isWriteLocked());
+    }
+
+    /**
+     * A writelock succeeds only after reading threads unlock
+     */
+    public void testWriteAfterMultipleReadLocks() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.readLock();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long rs = lock.readLock();
+                lock.unlockRead(rs);
+            }});
+
+        awaitTermination(t1);
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long ws = lock.writeLock();
+                lock.unlockWrite(ws);
+            }});
+
+        assertFalse(lock.isWriteLocked());
+        lock.unlockRead(s);
+        awaitTermination(t2);
+        assertFalse(lock.isWriteLocked());
+    }
+
+    /**
+     * Readlocks succeed only after a writing thread unlocks
+     */
+    public void testReadAfterWriteLock() {
+        final StampedLock lock = new StampedLock();
+        final long s = lock.writeLock();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long rs = lock.readLock();
+                lock.unlockRead(rs);
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long rs = lock.readLock();
+                lock.unlockRead(rs);
+            }});
+
+        releaseWriteLock(lock, s);
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * tryReadLock succeeds if readlocked but not writelocked
+     */
+    public void testTryLockWhenReadLocked() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.readLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long rs = lock.tryReadLock();
+                threadAssertTrue(rs != 0L);
+                lock.unlockRead(rs);
+            }});
+
+        awaitTermination(t);
+        lock.unlockRead(s);
+    }
+
+    /**
+     * tryWriteLock fails when readlocked
+     */
+    public void testWriteTryLockWhenReadLocked() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.readLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long ws = lock.tryWriteLock();
+                threadAssertEquals(ws, 0L);
+            }});
+
+        awaitTermination(t);
+        lock.unlockRead(s);
+    }
+
+    /**
+     * timed tryWriteLock times out if locked
+     */
+    public void testWriteTryLock_Timeout() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                long timeoutMillis = 10;
+                long ws = lock.tryWriteLock(timeoutMillis, MILLISECONDS);
+                assertEquals(ws, 0L);
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            }});
+
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * timed tryReadLock times out if write-locked
+     */
+    public void testReadTryLock_Timeout() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                long timeoutMillis = 10;
+                long rs = lock.tryReadLock(timeoutMillis, MILLISECONDS);
+                assertEquals(rs, 0L);
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            }});
+
+        awaitTermination(t);
+        assertTrue(lock.isWriteLocked());
+        lock.unlockWrite(s);
+    }
+
+    /**
+     * writeLockInterruptibly succeeds if unlocked, else is interruptible
+     */
+    public void testWriteLockInterruptibly() throws InterruptedException {
+        final CountDownLatch running = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLockInterruptibly();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                running.countDown();
+                lock.writeLockInterruptibly();
+            }});
+
+        running.await();
+        waitForThreadToEnterWaitState(t, 100);
+        t.interrupt();
+        assertTrue(lock.isWriteLocked());
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * readLockInterruptibly succeeds if lock free else is interruptible
+     */
+    public void testReadLockInterruptibly() throws InterruptedException {
+        final CountDownLatch running = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        long s;
+        s = lock.readLockInterruptibly();
+        lock.unlockRead(s);
+        s = lock.writeLockInterruptibly();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                running.countDown();
+                lock.readLockInterruptibly();
+            }});
+
+        running.await();
+        waitForThreadToEnterWaitState(t, 100);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * A serialized lock deserializes as unlocked
+     */
+    public void testSerialization() {
+        StampedLock lock = new StampedLock();
+        lock.writeLock();
+        StampedLock clone = serialClone(lock);
+        assertTrue(lock.isWriteLocked());
+        assertFalse(clone.isWriteLocked());
+        long s = clone.writeLock();
+        assertTrue(clone.isWriteLocked());
+        clone.unlockWrite(s);
+        assertFalse(clone.isWriteLocked());
+    }
+
+    /**
+     * toString indicates current lock state
+     */
+    public void testToString() {
+        StampedLock lock = new StampedLock();
+        assertTrue(lock.toString().contains("Unlocked"));
+        long s = lock.writeLock();
+        assertTrue(lock.toString().contains("Write-locked"));
+        lock.unlockWrite(s);
+        s = lock.readLock();
+        assertTrue(lock.toString().contains("Read-locks"));
+    }
+
+    /**
+     * tryOptimisticRead succeeds and validates if unlocked, fails if locked
+     */
+    public void testValidateOptimistic() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s, p;
+        assertTrue((p = lock.tryOptimisticRead()) != 0L);
+        assertTrue(lock.validate(p));
+        assertTrue((s = lock.writeLock()) != 0L);
+        assertFalse((p = lock.tryOptimisticRead()) != 0L);
+        assertTrue(lock.validate(s));
+        lock.unlockWrite(s);
+        assertTrue((p = lock.tryOptimisticRead()) != 0L);
+        assertTrue(lock.validate(p));
+        assertTrue((s = lock.readLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryOptimisticRead()) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockRead(s);
+        assertTrue((s = lock.tryWriteLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertFalse((p = lock.tryOptimisticRead()) != 0L);
+        lock.unlockWrite(s);
+        assertTrue((s = lock.tryReadLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryOptimisticRead()) != 0L);
+        lock.unlockRead(s);
+        assertTrue(lock.validate(p));
+        assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+        assertFalse((p = lock.tryOptimisticRead()) != 0L);
+        assertTrue(lock.validate(s));
+        lock.unlockWrite(s);
+        assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryOptimisticRead()) != 0L);
+        lock.unlockRead(s);
+        assertTrue((p = lock.tryOptimisticRead()) != 0L);
+    }
+
+    /**
+     * tryOptimisticRead stamp does not validate if a write lock intervenes
+     */
+    public void testValidateOptimisticWriteLocked() {
+        StampedLock lock = new StampedLock();
+        long s, p;
+        assertTrue((p = lock.tryOptimisticRead()) != 0L);
+        assertTrue((s = lock.writeLock()) != 0L);
+        assertFalse(lock.validate(p));
+        assertFalse((p = lock.tryOptimisticRead()) != 0L);
+        assertTrue(lock.validate(s));
+        lock.unlockWrite(s);
+    }
+
+    /**
+     * tryOptimisticRead stamp does not validate if a write lock
+     * intervenes in another thread
+     */
+    public void testValidateOptimisticWriteLocked2()
+            throws InterruptedException {
+        final CountDownLatch running = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        long s, p;
+        assertTrue((p = lock.tryOptimisticRead()) != 0L);
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLockInterruptibly();
+                running.countDown();
+                lock.writeLockInterruptibly();
+            }});
+
+        running.await();
+        assertFalse(lock.validate(p));
+        assertFalse((p = lock.tryOptimisticRead()) != 0L);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * tryConvertToOptimisticRead succeeds and validates if successfully locked,
+     */
+    public void testTryConvertToOptimisticRead() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s, p;
+        s = 0L;
+        assertFalse((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+        assertTrue((s = lock.tryOptimisticRead()) != 0L);
+        assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+        assertTrue((s = lock.writeLock()) != 0L);
+        assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+        assertTrue(lock.validate(p));
+        assertTrue((s = lock.readLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+        assertTrue(lock.validate(p));
+        assertTrue((s = lock.tryWriteLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+        assertTrue(lock.validate(p));
+        assertTrue((s = lock.tryReadLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+        assertTrue(lock.validate(p));
+        assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+        assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+        assertTrue(lock.validate(p));
+        assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+        assertTrue(lock.validate(p));
+    }
+
+    /**
+     * tryConvertToReadLock succeeds and validates if successfully locked
+     * or lock free;
+     */
+    public void testTryConvertToReadLock() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s, p;
+        s = 0L;
+        assertFalse((p = lock.tryConvertToReadLock(s)) != 0L);
+        assertTrue((s = lock.tryOptimisticRead()) != 0L);
+        assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+        lock.unlockRead(p);
+        assertTrue((s = lock.writeLock()) != 0L);
+        assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockRead(p);
+        assertTrue((s = lock.readLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockRead(p);
+        assertTrue((s = lock.tryWriteLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockRead(p);
+        assertTrue((s = lock.tryReadLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockRead(p);
+        assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+        assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockRead(p);
+        assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockRead(p);
+    }
+
+    /**
+     * tryConvertToWriteLock succeeds and validates if successfully locked
+     * or lock free;
+     */
+    public void testTryConvertToWriteLock() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s, p;
+        s = 0L;
+        assertFalse((p = lock.tryConvertToWriteLock(s)) != 0L);
+        assertTrue((s = lock.tryOptimisticRead()) != 0L);
+        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+        lock.unlockWrite(p);
+        assertTrue((s = lock.writeLock()) != 0L);
+        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockWrite(p);
+        assertTrue((s = lock.readLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockWrite(p);
+        assertTrue((s = lock.tryWriteLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockWrite(p);
+        assertTrue((s = lock.tryReadLock()) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockWrite(p);
+        assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockWrite(p);
+        assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+        assertTrue(lock.validate(s));
+        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+        assertTrue(lock.validate(p));
+        lock.unlockWrite(p);
+    }
+
+    /**
+     * asWriteLock can be locked and unlocked
+     */
+    public void testAsWriteLock() {
+        StampedLock sl = new StampedLock();
+        Lock lock = sl.asWriteLock();
+        lock.lock();
+        assertFalse(lock.tryLock());
+        lock.unlock();
+        assertTrue(lock.tryLock());
+    }
+
+    /**
+     * asReadLock can be locked and unlocked
+     */
+    public void testAsReadLock() {
+        StampedLock sl = new StampedLock();
+        Lock lock = sl.asReadLock();
+        lock.lock();
+        lock.unlock();
+        assertTrue(lock.tryLock());
+    }
+
+    /**
+     * asReadWriteLock.writeLock can be locked and unlocked
+     */
+    public void testAsReadWriteLockWriteLock() {
+        StampedLock sl = new StampedLock();
+        Lock lock = sl.asReadWriteLock().writeLock();
+        lock.lock();
+        assertFalse(lock.tryLock());
+        lock.unlock();
+        assertTrue(lock.tryLock());
+    }
+
+    /**
+     * asReadWriteLock.readLock can be locked and unlocked
+     */
+    public void testAsReadWriteLockReadLock() {
+        StampedLock sl = new StampedLock();
+        Lock lock = sl.asReadWriteLock().readLock();
+        lock.lock();
+        lock.unlock();
+        assertTrue(lock.tryLock());
+    }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java b/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java
index 605a955..9d3f212 100644
--- a/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java
+++ b/jsr166-tests/src/test/java/jsr166/SynchronousQueueTest.java
@@ -25,7 +25,7 @@
 
 public class SynchronousQueueTest extends JSR166TestCase {
 
-    // android-note: These tests have been moved into their own separate 
+    // android-note: These tests have been moved into their own separate
     // classes to work around CTS issues.
     //
     // public static class Fair extends BlockingQueueTest {
@@ -33,17 +33,19 @@
     //         return new SynchronousQueue(true);
     //     }
     // }
-    //
+
     // public static class NonFair extends BlockingQueueTest {
     //     protected BlockingQueue emptyCollection() {
     //         return new SynchronousQueue(false);
     //     }
     // }
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
     //
     // public static void main(String[] args) {
     //     main(suite(), args);
     // }
-    //
     // public static Test suite() {
     //     return newTestSuite(SynchronousQueueTest.class,
     //                         new Fair().testSuite(),
@@ -262,7 +264,6 @@
                 pleaseOffer.countDown();
                 startTime = System.nanoTime();
                 assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
-                assertTrue(millisElapsedSince(startTime) < MEDIUM_DELAY_MS);
 
                 Thread.currentThread().interrupt();
                 try {
@@ -277,13 +278,15 @@
                     shouldThrow();
                 } catch (InterruptedException success) {}
                 assertFalse(Thread.interrupted());
+
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             }});
 
         await(pleaseOffer);
         long startTime = System.nanoTime();
         try { assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); }
         catch (InterruptedException e) { threadUnexpectedException(e); }
-        assertTrue(millisElapsedSince(startTime) < MEDIUM_DELAY_MS);
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
 
         await(pleaseInterrupt);
         assertThreadStaysAlive(t);
@@ -474,24 +477,24 @@
     public void testOfferInExecutor_fair() { testOfferInExecutor(true); }
     public void testOfferInExecutor(boolean fair) {
         final SynchronousQueue q = new SynchronousQueue(fair);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertFalse(q.offer(one));
-                threadsStarted.await();
-                assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
-                assertEquals(0, q.remainingCapacity());
-            }});
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(q.offer(one));
+                    threadsStarted.await();
+                    assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
+                    assertEquals(0, q.remainingCapacity());
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                assertSame(one, q.take());
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertSame(one, q.take());
+                }});
+        }
     }
 
     /**
@@ -502,22 +505,22 @@
     public void testPollInExecutor(boolean fair) {
         final SynchronousQueue q = new SynchronousQueue(fair);
         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
-        ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                assertNull(q.poll());
-                threadsStarted.await();
-                assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
-                assertTrue(q.isEmpty());
-            }});
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    assertTrue(q.isEmpty());
+                }});
 
-        executor.execute(new CheckedRunnable() {
-            public void realRun() throws InterruptedException {
-                threadsStarted.await();
-                q.put(one);
-            }});
-
-        joinPool(executor);
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
     }
 
     /**
@@ -595,10 +598,12 @@
             }});
 
         ArrayList l = new ArrayList();
-        delay(SHORT_DELAY_MS);
-        q.drainTo(l, 1);
+        int drained;
+        while ((drained = q.drainTo(l, 1)) == 0) Thread.yield();
+        assertEquals(1, drained);
         assertEquals(1, l.size());
-        q.drainTo(l, 1);
+        while ((drained = q.drainTo(l, 1)) == 0) Thread.yield();
+        assertEquals(1, drained);
         assertEquals(2, l.size());
         assertTrue(l.contains(one));
         assertTrue(l.contains(two));
diff --git a/jsr166-tests/src/test/java/jsr166/SystemTest.java b/jsr166-tests/src/test/java/jsr166/SystemTest.java
index 6918374..412ce17 100644
--- a/jsr166-tests/src/test/java/jsr166/SystemTest.java
+++ b/jsr166-tests/src/test/java/jsr166/SystemTest.java
@@ -19,7 +19,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(SystemTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadLocalRandom8Test.java b/jsr166-tests/src/test/java/jsr166/ThreadLocalRandom8Test.java
new file mode 100644
index 0000000..614af83
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/ThreadLocalRandom8Test.java
@@ -0,0 +1,241 @@
+/*
+ * 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 jsr166;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ThreadLocalRandom8Test extends JSR166TestCase {
+
+    // android-note: Removed because the CTS runner does a bad job of
+    // retrying tests that have suite() declarations.
+    //
+    // public static void main(String[] args) {
+    //     main(suite(), args);
+    // }
+    // public static Test suite() {
+    //     return new TestSuite(ThreadLocalRandom8Test.class);
+    // }
+
+    // max sampled int bound
+    static final int MAX_INT_BOUND = (1 << 26);
+
+    // max sampled long bound
+    static final long MAX_LONG_BOUND = (1L << 42);
+
+    // Number of replications for other checks
+    static final int REPS =
+        Integer.getInteger("ThreadLocalRandom8Test.reps", 4);
+
+    /**
+     * Invoking sized ints, long, doubles, with negative sizes throws
+     * IllegalArgumentException
+     */
+    // TODO(streams):
+    // public void testBadStreamSize() {
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     Runnable[] throwingActions = {
+    //         () -> r.ints(-1L),
+    //         () -> r.ints(-1L, 2, 3),
+    //         () -> r.longs(-1L),
+    //         () -> r.longs(-1L, -1L, 1L),
+    //         () -> r.doubles(-1L),
+    //         () -> r.doubles(-1L, .5, .6),
+    //     };
+    //     assertThrows(IllegalArgumentException.class, throwingActions);
+    // }
+
+    // /**
+    //  * Invoking bounded ints, long, doubles, with illegal bounds throws
+    //  * IllegalArgumentException
+    //  */
+    // public void testBadStreamBounds() {
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     Runnable[] throwingActions = {
+    //         () -> r.ints(2, 1),
+    //         () -> r.ints(10, 42, 42),
+    //         () -> r.longs(-1L, -1L),
+    //         () -> r.longs(10, 1L, -2L),
+    //         () -> r.doubles(0.0, 0.0),
+    //         () -> r.doubles(10, .5, .4),
+    //     };
+    //     assertThrows(IllegalArgumentException.class, throwingActions);
+    // }
+
+    // /**
+    //  * A parallel sized stream of ints generates the given number of values
+    //  */
+    // public void testIntsCount() {
+    //     LongAdder counter = new LongAdder();
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 0;
+    //     for (int reps = 0; reps < REPS; ++reps) {
+    //         counter.reset();
+    //         r.ints(size).parallel().forEach(x -> counter.increment());
+    //         assertEquals(size, counter.sum());
+    //         size += 524959;
+    //     }
+    // }
+
+    // /**
+    //  * A parallel sized stream of longs generates the given number of values
+    //  */
+    // public void testLongsCount() {
+    //     LongAdder counter = new LongAdder();
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 0;
+    //     for (int reps = 0; reps < REPS; ++reps) {
+    //         counter.reset();
+    //         r.longs(size).parallel().forEach(x -> counter.increment());
+    //         assertEquals(size, counter.sum());
+    //         size += 524959;
+    //     }
+    // }
+
+    // /**
+    //  * A parallel sized stream of doubles generates the given number of values
+    //  */
+    // public void testDoublesCount() {
+    //     LongAdder counter = new LongAdder();
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 0;
+    //     for (int reps = 0; reps < REPS; ++reps) {
+    //         counter.reset();
+    //         r.doubles(size).parallel().forEach(x -> counter.increment());
+    //         assertEquals(size, counter.sum());
+    //         size += 524959;
+    //     }
+    // }
+
+    // /**
+    //  * Each of a parallel sized stream of bounded ints is within bounds
+    //  */
+    // public void testBoundedInts() {
+    //     AtomicInteger fails = new AtomicInteger(0);
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 12345L;
+    //     for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
+    //         for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
+    //             final int lo = least, hi = bound;
+    //             r.ints(size, lo, hi).parallel().forEach(
+    //                 x -> {
+    //                     if (x < lo || x >= hi)
+    //                         fails.getAndIncrement(); });
+    //         }
+    //     }
+    //     assertEquals(0, fails.get());
+    // }
+
+    // /**
+    //  * Each of a parallel sized stream of bounded longs is within bounds
+    //  */
+    // public void testBoundedLongs() {
+    //     AtomicInteger fails = new AtomicInteger(0);
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 123L;
+    //     for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
+    //         for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+    //             final long lo = least, hi = bound;
+    //             r.longs(size, lo, hi).parallel().forEach(
+    //                 x -> {
+    //                     if (x < lo || x >= hi)
+    //                         fails.getAndIncrement(); });
+    //         }
+    //     }
+    //     assertEquals(0, fails.get());
+    // }
+
+    // /**
+    //  * Each of a parallel sized stream of bounded doubles is within bounds
+    //  */
+    // public void testBoundedDoubles() {
+    //     AtomicInteger fails = new AtomicInteger(0);
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 456;
+    //     for (double least = 0.00011; least < 1.0e20; least *= 9) {
+    //         for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
+    //             final double lo = least, hi = bound;
+    //             r.doubles(size, lo, hi).parallel().forEach(
+    //                 x -> {
+    //                     if (x < lo || x >= hi)
+    //                         fails.getAndIncrement(); });
+    //         }
+    //     }
+    //     assertEquals(0, fails.get());
+    // }
+
+    // /**
+    //  * A parallel unsized stream of ints generates at least 100 values
+    //  */
+    // public void testUnsizedIntsCount() {
+    //     LongAdder counter = new LongAdder();
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 100;
+    //     r.ints().limit(size).parallel().forEach(x -> counter.increment());
+    //     assertEquals(size, counter.sum());
+    // }
+
+    // /**
+    //  * A parallel unsized stream of longs generates at least 100 values
+    //  */
+    // public void testUnsizedLongsCount() {
+    //     LongAdder counter = new LongAdder();
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 100;
+    //     r.longs().limit(size).parallel().forEach(x -> counter.increment());
+    //     assertEquals(size, counter.sum());
+    // }
+
+    // /**
+    //  * A parallel unsized stream of doubles generates at least 100 values
+    //  */
+    // public void testUnsizedDoublesCount() {
+    //     LongAdder counter = new LongAdder();
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 100;
+    //     r.doubles().limit(size).parallel().forEach(x -> counter.increment());
+    //     assertEquals(size, counter.sum());
+    // }
+
+    // /**
+    //  * A sequential unsized stream of ints generates at least 100 values
+    //  */
+    // public void testUnsizedIntsCountSeq() {
+    //     LongAdder counter = new LongAdder();
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 100;
+    //     r.ints().limit(size).forEach(x -> counter.increment());
+    //     assertEquals(size, counter.sum());
+    // }
+
+    // /**
+    //  * A sequential unsized stream of longs generates at least 100 values
+    //  */
+    // public void testUnsizedLongsCountSeq() {
+    //     LongAdder counter = new LongAdder();
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 100;
+    //     r.longs().limit(size).forEach(x -> counter.increment());
+    //     assertEquals(size, counter.sum());
+    // }
+
+    // /**
+    //  * A sequential unsized stream of doubles generates at least 100 values
+    //  */
+    // public void testUnsizedDoublesCountSeq() {
+    //     LongAdder counter = new LongAdder();
+    //     ThreadLocalRandom r = ThreadLocalRandom.current();
+    //     long size = 100;
+    //     r.doubles().limit(size).forEach(x -> counter.increment());
+    //     assertEquals(size, counter.sum());
+    // }
+
+}
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java b/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java
index 4ae141d..5d9f894 100644
--- a/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ThreadLocalRandomTest.java
@@ -22,7 +22,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ThreadLocalRandomTest.class);
     // }
 
     /*
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java b/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java
index 7f5f072..8bfcf70 100644
--- a/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ThreadLocalTest.java
@@ -19,7 +19,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ThreadLocalTest.class);
     // }
 
     static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java
index 5f38d39..a502392 100644
--- a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorSubclassTest.java
@@ -9,12 +9,14 @@
 package jsr166;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
@@ -30,6 +32,7 @@
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -44,7 +47,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ThreadPoolExecutorSubclassTest.class);
     // }
 
     static class CustomTask<V> implements RunnableFuture<V> {
@@ -103,11 +106,13 @@
             }
             lock.lock();
             try {
-                result = v;
-                exception = e;
-                done = true;
-                thread = null;
-                cond.signalAll();
+                if (!done) {
+                    result = v;
+                    exception = e;
+                    done = true;
+                    thread = null;
+                    cond.signalAll();
+                }
             }
             finally { lock.unlock(); }
         }
@@ -116,6 +121,8 @@
             try {
                 while (!done)
                     cond.await();
+                if (cancelled)
+                    throw new CancellationException();
                 if (exception != null)
                     throw new ExecutionException(exception);
                 return result;
@@ -127,12 +134,13 @@
             long nanos = unit.toNanos(timeout);
             lock.lock();
             try {
-                for (;;) {
-                    if (done) break;
-                    if (nanos < 0)
+                while (!done) {
+                    if (nanos <= 0L)
                         throw new TimeoutException();
                     nanos = cond.awaitNanos(nanos);
                 }
+                if (cancelled)
+                    throw new CancellationException();
                 if (exception != null)
                     throw new ExecutionException(exception);
                 return result;
@@ -229,18 +237,14 @@
     public void testExecute() throws InterruptedException {
         final ThreadPoolExecutor p =
             new CustomTPE(1, 1,
-                          LONG_DELAY_MS, MILLISECONDS,
+                          2 * LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch done = new CountDownLatch(1);
-        final Runnable task = new CheckedRunnable() {
-            public void realRun() {
-                done.countDown();
-            }};
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() { done.countDown(); }};
             p.execute(task);
-            assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
-        } finally {
-            joinPool(p);
+            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
         }
     }
 
@@ -249,25 +253,22 @@
      * thread becomes active
      */
     public void testGetActiveCount() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
         final ThreadPoolExecutor p =
             new CustomTPE(2, 2,
                           LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertEquals(0, p.getActiveCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertEquals(1, p.getActiveCount());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getActiveCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -275,28 +276,48 @@
      * prestartCoreThread starts a thread if under corePoolSize, else doesn't
      */
     public void testPrestartCoreThread() {
-        ThreadPoolExecutor p = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(0, p.getPoolSize());
-        assertTrue(p.prestartCoreThread());
-        assertEquals(1, p.getPoolSize());
-        assertTrue(p.prestartCoreThread());
-        assertEquals(2, p.getPoolSize());
-        assertFalse(p.prestartCoreThread());
-        assertEquals(2, p.getPoolSize());
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 6,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(0, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(1, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(2, p.getPoolSize());
+            assertFalse(p.prestartCoreThread());
+            assertEquals(2, p.getPoolSize());
+            p.setCorePoolSize(4);
+            assertTrue(p.prestartCoreThread());
+            assertEquals(3, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(4, p.getPoolSize());
+            assertFalse(p.prestartCoreThread());
+            assertEquals(4, p.getPoolSize());
+        }
     }
 
     /**
      * prestartAllCoreThreads starts all corePoolSize threads
      */
     public void testPrestartAllCoreThreads() {
-        ThreadPoolExecutor p = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(0, p.getPoolSize());
-        p.prestartAllCoreThreads();
-        assertEquals(2, p.getPoolSize());
-        p.prestartAllCoreThreads();
-        assertEquals(2, p.getPoolSize());
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 6,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(0, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(2, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(2, p.getPoolSize());
+            p.setCorePoolSize(4);
+            p.prestartAllCoreThreads();
+            assertEquals(4, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(4, p.getPoolSize());
+        }
     }
 
     /**
@@ -308,10 +329,10 @@
             new CustomTPE(2, 2,
                           LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch threadProceed = new CountDownLatch(1);
-        final CountDownLatch threadDone = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch threadProceed = new CountDownLatch(1);
+            final CountDownLatch threadDone = new CountDownLatch(1);
             assertEquals(0, p.getCompletedTaskCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
@@ -330,8 +351,6 @@
                     fail("timed out");
                 Thread.yield();
             }
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -339,52 +358,72 @@
      * getCorePoolSize returns size given in constructor if not otherwise set
      */
     public void testGetCorePoolSize() {
-        ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(1, p.getCorePoolSize());
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getCorePoolSize());
+        }
     }
 
     /**
      * getKeepAliveTime returns value given in constructor if not otherwise set
      */
     public void testGetKeepAliveTime() {
-        ThreadPoolExecutor p = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(1, p.getKeepAliveTime(TimeUnit.SECONDS));
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 2,
+                          1000, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getKeepAliveTime(SECONDS));
+        }
     }
 
     /**
      * getThreadFactory returns factory in constructor if not set
      */
     public void testGetThreadFactory() {
-        ThreadFactory tf = new SimpleThreadFactory();
-        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), tf, new NoOpREHandler());
-        assertSame(tf, p.getThreadFactory());
-        joinPool(p);
+        final ThreadFactory threadFactory = new SimpleThreadFactory();
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          threadFactory,
+                          new NoOpREHandler());
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(threadFactory, p.getThreadFactory());
+        }
     }
 
     /**
      * setThreadFactory sets the thread factory returned by getThreadFactory
      */
     public void testSetThreadFactory() {
-        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        ThreadFactory tf = new SimpleThreadFactory();
-        p.setThreadFactory(tf);
-        assertSame(tf, p.getThreadFactory());
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            ThreadFactory threadFactory = new SimpleThreadFactory();
+            p.setThreadFactory(threadFactory);
+            assertSame(threadFactory, p.getThreadFactory());
+        }
     }
 
     /**
      * setThreadFactory(null) throws NPE
      */
     public void testSetThreadFactoryNull() {
-        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setThreadFactory(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setThreadFactory(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -392,10 +431,15 @@
      * getRejectedExecutionHandler returns handler in constructor if not set
      */
     public void testGetRejectedExecutionHandler() {
-        RejectedExecutionHandler h = new NoOpREHandler();
-        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), h);
-        assertSame(h, p.getRejectedExecutionHandler());
-        joinPool(p);
+        final RejectedExecutionHandler handler = new NoOpREHandler();
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          handler);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(handler, p.getRejectedExecutionHandler());
+        }
     }
 
     /**
@@ -403,24 +447,30 @@
      * getRejectedExecutionHandler
      */
     public void testSetRejectedExecutionHandler() {
-        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        RejectedExecutionHandler h = new NoOpREHandler();
-        p.setRejectedExecutionHandler(h);
-        assertSame(h, p.getRejectedExecutionHandler());
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            RejectedExecutionHandler handler = new NoOpREHandler();
+            p.setRejectedExecutionHandler(handler);
+            assertSame(handler, p.getRejectedExecutionHandler());
+        }
     }
 
     /**
      * setRejectedExecutionHandler(null) throws NPE
      */
     public void testSetRejectedExecutionHandlerNull() {
-        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setRejectedExecutionHandler(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setRejectedExecutionHandler(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -430,28 +480,25 @@
      */
     public void testGetLargestPoolSize() throws InterruptedException {
         final int THREADS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
         final ThreadPoolExecutor p =
             new CustomTPE(THREADS, THREADS,
                           LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             assertEquals(0, p.getLargestPoolSize());
+            final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
             for (int i = 0; i < THREADS; i++)
                 p.execute(new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadsStarted.countDown();
-                        done.await();
+                        await(done);
                         assertEquals(THREADS, p.getLargestPoolSize());
                     }});
-            assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
-            assertEquals(THREADS, p.getLargestPoolSize());
-        } finally {
-            done.countDown();
-            joinPool(p);
+            await(threadsStarted);
             assertEquals(THREADS, p.getLargestPoolSize());
         }
+        assertEquals(THREADS, p.getLargestPoolSize());
     }
 
     /**
@@ -459,9 +506,17 @@
      * otherwise set
      */
     public void testGetMaximumPoolSize() {
-        ThreadPoolExecutor p = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(2, p.getMaximumPoolSize());
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 3,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(3, p.getMaximumPoolSize());
+            p.setMaximumPoolSize(5);
+            assertEquals(5, p.getMaximumPoolSize());
+            p.setMaximumPoolSize(4);
+            assertEquals(4, p.getMaximumPoolSize());
+        }
     }
 
     /**
@@ -469,25 +524,22 @@
      * become active
      */
     public void testGetPoolSize() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
         final ThreadPoolExecutor p =
             new CustomTPE(1, 1,
                           LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             assertEquals(0, p.getPoolSize());
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertEquals(1, p.getPoolSize());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getPoolSize());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -495,38 +547,53 @@
      * getTaskCount increases, but doesn't overestimate, when tasks submitted
      */
     public void testGetTaskCount() throws InterruptedException {
+        final int TASKS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
         final ThreadPoolExecutor p =
             new CustomTPE(1, 1,
                           LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertEquals(0, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
-                    assertEquals(1, p.getTaskCount());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getTaskCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
+            assertEquals(0, p.getCompletedTaskCount());
+            for (int i = 0; i < TASKS; i++) {
+                assertEquals(1 + i, p.getTaskCount());
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        assertEquals(1 + TASKS, p.getTaskCount());
+                        await(done);
+                    }});
+            }
+            assertEquals(1 + TASKS, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
         }
+        assertEquals(1 + TASKS, p.getTaskCount());
+        assertEquals(1 + TASKS, p.getCompletedTaskCount());
     }
 
     /**
      * isShutdown is false before shutdown, true after
      */
     public void testIsShutdown() {
-
-        ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        assertFalse(p.isShutdown());
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
-        assertTrue(p.isShutdown());
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isShutdown());
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.isShutdown());
+        }
     }
 
     /**
@@ -537,25 +604,24 @@
             new CustomTPE(1, 1,
                           LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
             assertFalse(p.isTerminating());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     assertFalse(p.isTerminating());
                     threadStarted.countDown();
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertFalse(p.isTerminating());
             done.countDown();
-        } finally {
             try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
         }
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
-        assertFalse(p.isTerminating());
     }
 
     /**
@@ -566,59 +632,55 @@
             new CustomTPE(1, 1,
                           LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
             assertFalse(p.isTerminating());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     assertFalse(p.isTerminating());
                     threadStarted.countDown();
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertFalse(p.isTerminating());
             done.countDown();
-        } finally {
             try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
         }
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
-        assertFalse(p.isTerminating());
     }
 
     /**
      * getQueue returns the work queue, which contains queued tasks
      */
     public void testGetQueue() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
         final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
         final ThreadPoolExecutor p =
             new CustomTPE(1, 1,
                           LONG_DELAY_MS, MILLISECONDS,
                           q);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             FutureTask[] tasks = new FutureTask[5];
             for (int i = 0; i < tasks.length; i++) {
                 Callable task = new CheckedCallable<Boolean>() {
                     public Boolean realCall() throws InterruptedException {
                         threadStarted.countDown();
                         assertSame(q, p.getQueue());
-                        done.await();
+                        await(done);
                         return Boolean.TRUE;
                     }};
                 tasks[i] = new FutureTask(task);
                 p.execute(tasks[i]);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertSame(q, p.getQueue());
             assertFalse(q.contains(tasks[0]));
             assertTrue(q.contains(tasks[tasks.length - 1]));
             assertEquals(tasks.length - 1, q.size());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -626,24 +688,24 @@
      * remove(task) removes queued task, and fails to remove active task
      */
     public void testRemove() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
         BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
         final ThreadPoolExecutor p =
             new CustomTPE(1, 1,
                           LONG_DELAY_MS, MILLISECONDS,
                           q);
-        Runnable[] tasks = new Runnable[6];
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable[] tasks = new Runnable[6];
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             for (int i = 0; i < tasks.length; i++) {
                 tasks[i] = new CheckedRunnable() {
-                        public void realRun() throws InterruptedException {
-                            threadStarted.countDown();
-                            done.await();
-                        }};
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        await(done);
+                    }};
                 p.execute(tasks[i]);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertFalse(p.remove(tasks[0]));
             assertTrue(q.contains(tasks[4]));
             assertTrue(q.contains(tasks[3]));
@@ -653,9 +715,6 @@
             assertTrue(q.contains(tasks[3]));
             assertTrue(p.remove(tasks[3]));
             assertFalse(q.contains(tasks[3]));
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -670,19 +729,19 @@
             new CustomTPE(1, 1,
                           LONG_DELAY_MS, MILLISECONDS,
                           q);
-        FutureTask[] tasks = new FutureTask[5];
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            FutureTask[] tasks = new FutureTask[5];
             for (int i = 0; i < tasks.length; i++) {
                 Callable task = new CheckedCallable<Boolean>() {
                     public Boolean realCall() throws InterruptedException {
                         threadStarted.countDown();
-                        done.await();
+                        await(done);
                         return Boolean.TRUE;
                     }};
                 tasks[i] = new FutureTask(task);
                 p.execute(tasks[i]);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(tasks.length, p.getTaskCount());
             assertEquals(tasks.length - 1, q.size());
             assertEquals(1L, p.getActiveCount());
@@ -695,29 +754,47 @@
             p.purge();         // Nothing to do
             assertEquals(tasks.length - 3, q.size());
             assertEquals(tasks.length - 2, p.getTaskCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
     /**
-     * shutdownNow returns a list containing tasks that were not run
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
      */
-    public void testShutdownNow() {
-        ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List l;
-        try {
-            for (int i = 0; i < 5; i++)
-                p.execute(new MediumPossiblyInterruptedRunnable());
-        }
-        finally {
+    public void testShutdownNow() throws InterruptedException {
+        final int poolSize = 2;
+        final int count = 5;
+        final AtomicInteger ran = new AtomicInteger(0);
+        final ThreadPoolExecutor p =
+            new CustomTPE(poolSize, poolSize,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
+        Runnable waiter = new CheckedRunnable() { public void realRun() {
+            threadsStarted.countDown();
             try {
-                l = p.shutdownNow();
-            } catch (SecurityException ok) { return; }
+                MILLISECONDS.sleep(2 * LONG_DELAY_MS);
+            } catch (InterruptedException success) {}
+            ran.getAndIncrement();
+        }};
+        for (int i = 0; i < count; i++)
+            p.execute(waiter);
+        await(threadsStarted);
+        assertEquals(poolSize, p.getActiveCount());
+        assertEquals(0, p.getCompletedTaskCount());
+        final List<Runnable> queuedTasks;
+        try {
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
         }
         assertTrue(p.isShutdown());
-        assertTrue(l.size() <= 4);
+        assertTrue(p.getQueue().isEmpty());
+        assertEquals(count - poolSize, queuedTasks.size());
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(poolSize, ran.get());
+        assertEquals(poolSize, p.getCompletedTaskCount());
     }
 
     // Exception Tests
@@ -727,7 +804,8 @@
      */
     public void testConstructor1() {
         try {
-            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new CustomTPE(-1, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -737,7 +815,8 @@
      */
     public void testConstructor2() {
         try {
-            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new CustomTPE(1, -1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -747,7 +826,8 @@
      */
     public void testConstructor3() {
         try {
-            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new CustomTPE(1, 0, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -757,7 +837,8 @@
      */
     public void testConstructor4() {
         try {
-            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new CustomTPE(1, 2, -1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -767,7 +848,8 @@
      */
     public void testConstructor5() {
         try {
-            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new CustomTPE(2, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -777,7 +859,7 @@
      */
     public void testConstructorNullPointerException() {
         try {
-            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null);
+            new CustomTPE(1, 2, 1L, SECONDS, null);
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -787,7 +869,9 @@
      */
     public void testConstructor6() {
         try {
-            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new CustomTPE(-1, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -797,7 +881,9 @@
      */
     public void testConstructor7() {
         try {
-            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new CustomTPE(1,-1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -807,7 +893,9 @@
      */
     public void testConstructor8() {
         try {
-            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new CustomTPE(1, 0, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -817,7 +905,9 @@
      */
     public void testConstructor9() {
         try {
-            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new CustomTPE(1, 2, -1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -827,7 +917,9 @@
      */
     public void testConstructor10() {
         try {
-            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new CustomTPE(2, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -837,7 +929,7 @@
      */
     public void testConstructorNullPointerException2() {
         try {
-            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory());
+            new CustomTPE(1, 2, 1L, SECONDS, null, new SimpleThreadFactory());
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -847,8 +939,9 @@
      */
     public void testConstructorNullPointerException3() {
         try {
-            ThreadFactory f = null;
-            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f);
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          (ThreadFactory) null);
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -858,7 +951,9 @@
      */
     public void testConstructor11() {
         try {
-            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new CustomTPE(-1, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -868,7 +963,9 @@
      */
     public void testConstructor12() {
         try {
-            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new CustomTPE(1, -1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -878,7 +975,9 @@
      */
     public void testConstructor13() {
         try {
-            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new CustomTPE(1, 0, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -888,7 +987,9 @@
      */
     public void testConstructor14() {
         try {
-            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new CustomTPE(1, 2, -1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -898,7 +999,9 @@
      */
     public void testConstructor15() {
         try {
-            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new CustomTPE(2, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -908,7 +1011,9 @@
      */
     public void testConstructorNullPointerException4() {
         try {
-            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new NoOpREHandler());
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          null,
+                          new NoOpREHandler());
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -918,8 +1023,9 @@
      */
     public void testConstructorNullPointerException5() {
         try {
-            RejectedExecutionHandler r = null;
-            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),r);
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          (RejectedExecutionHandler) null);
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -929,7 +1035,10 @@
      */
     public void testConstructor16() {
         try {
-            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new CustomTPE(-1, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -939,7 +1048,10 @@
      */
     public void testConstructor17() {
         try {
-            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new CustomTPE(1, -1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -949,7 +1061,10 @@
      */
     public void testConstructor18() {
         try {
-            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new CustomTPE(1, 0, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -959,7 +1074,10 @@
      */
     public void testConstructor19() {
         try {
-            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new CustomTPE(1, 2, -1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -969,7 +1087,10 @@
      */
     public void testConstructor20() {
         try {
-            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new CustomTPE(2, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (IllegalArgumentException success) {}
     }
@@ -979,7 +1100,10 @@
      */
     public void testConstructorNullPointerException6() {
         try {
-            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory(),new NoOpREHandler());
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          null,
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -989,8 +1113,10 @@
      */
     public void testConstructorNullPointerException7() {
         try {
-            RejectedExecutionHandler r = null;
-            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),r);
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          (RejectedExecutionHandler) null);
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -1000,8 +1126,7 @@
      */
     public void testConstructorNullPointerException8() {
         try {
-            new CustomTPE(1, 2,
-                          LONG_DELAY_MS, MILLISECONDS,
+            new CustomTPE(1, 2, 1L, SECONDS,
                           new ArrayBlockingQueue<Runnable>(10),
                           (ThreadFactory) null,
                           new NoOpREHandler());
@@ -1013,15 +1138,15 @@
      * execute throws RejectedExecutionException if saturated.
      */
     public void testSaturatedExecute() {
-        ThreadPoolExecutor p =
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
             new CustomTPE(1, 1,
                           LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(1));
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             Runnable task = new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
-                    done.await();
+                    await(done);
                 }};
             for (int i = 0; i < 2; ++i)
                 p.execute(task);
@@ -1032,9 +1157,6 @@
                 } catch (RejectedExecutionException success) {}
                 assertTrue(p.getTaskCount() <= 2);
             }
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -1042,24 +1164,26 @@
      * executor using CallerRunsPolicy runs task if saturated.
      */
     public void testSaturatedExecute2() {
-        RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
-        ThreadPoolExecutor p = new CustomTPE(1, 1,
-                                             LONG_DELAY_MS, MILLISECONDS,
-                                             new ArrayBlockingQueue<Runnable>(1),
-                                             h);
-        try {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.CallerRunsPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable blocker = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    await(done);
+                }};
+            p.execute(blocker);
             TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
-            for (int i = 0; i < tasks.length; ++i)
+            for (int i = 0; i < tasks.length; i++)
                 tasks[i] = new TrackedNoOpRunnable();
-            TrackedLongRunnable mr = new TrackedLongRunnable();
-            p.execute(mr);
-            for (int i = 0; i < tasks.length; ++i)
+            for (int i = 0; i < tasks.length; i++)
                 p.execute(tasks[i]);
-            for (int i = 1; i < tasks.length; ++i)
+            for (int i = 1; i < tasks.length; i++)
                 assertTrue(tasks[i].done);
-            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
-        } finally {
-            joinPool(p);
+            assertFalse(tasks[0].done); // waiting in queue
         }
     }
 
@@ -1067,77 +1191,88 @@
      * executor using DiscardPolicy drops task if saturated.
      */
     public void testSaturatedExecute3() {
-        RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
-        ThreadPoolExecutor p =
+        final TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+        for (int i = 0; i < tasks.length; ++i)
+            tasks[i] = new TrackedNoOpRunnable();
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
             new CustomTPE(1, 1,
                           LONG_DELAY_MS, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(1),
-                          h);
-        try {
-            TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
-            for (int i = 0; i < tasks.length; ++i)
-                tasks[i] = new TrackedNoOpRunnable();
-            p.execute(new TrackedLongRunnable());
+                          new CustomTPE.DiscardPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            p.execute(awaiter(done));
+
             for (TrackedNoOpRunnable task : tasks)
                 p.execute(task);
-            for (TrackedNoOpRunnable task : tasks)
-                assertFalse(task.done);
-            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
-        } finally {
-            joinPool(p);
+            for (int i = 1; i < tasks.length; i++)
+                assertFalse(tasks[i].done);
         }
+        for (int i = 1; i < tasks.length; i++)
+            assertFalse(tasks[i].done);
+        assertTrue(tasks[0].done); // was waiting in queue
     }
 
     /**
      * executor using DiscardOldestPolicy drops oldest task if saturated.
      */
     public void testSaturatedExecute4() {
-        RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
-        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
-        try {
-            p.execute(new TrackedLongRunnable());
-            TrackedLongRunnable r2 = new TrackedLongRunnable();
+        final CountDownLatch done = new CountDownLatch(1);
+        LatchAwaiter r1 = awaiter(done);
+        LatchAwaiter r2 = awaiter(done);
+        LatchAwaiter r3 = awaiter(done);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.DiscardOldestPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(LatchAwaiter.NEW, r1.state);
+            assertEquals(LatchAwaiter.NEW, r2.state);
+            assertEquals(LatchAwaiter.NEW, r3.state);
+            p.execute(r1);
             p.execute(r2);
             assertTrue(p.getQueue().contains(r2));
-            TrackedNoOpRunnable r3 = new TrackedNoOpRunnable();
             p.execute(r3);
             assertFalse(p.getQueue().contains(r2));
             assertTrue(p.getQueue().contains(r3));
-            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
-        } finally {
-            joinPool(p);
         }
+        assertEquals(LatchAwaiter.DONE, r1.state);
+        assertEquals(LatchAwaiter.NEW, r2.state);
+        assertEquals(LatchAwaiter.DONE, r3.state);
     }
 
     /**
      * execute throws RejectedExecutionException if shutdown
      */
     public void testRejectedExecutionExceptionOnShutdown() {
-        ThreadPoolExecutor p =
-            new CustomTPE(1,1,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(1));
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1));
         try { p.shutdown(); } catch (SecurityException ok) { return; }
-        try {
-            p.execute(new NoOpRunnable());
-            shouldThrow();
-        } catch (RejectedExecutionException success) {}
-
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(new NoOpRunnable());
+                shouldThrow();
+            } catch (RejectedExecutionException success) {}
+        }
     }
 
     /**
      * execute using CallerRunsPolicy drops task on shutdown
      */
     public void testCallerRunsOnShutdown() {
-        RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
-        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
-
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.CallerRunsPolicy());
         try { p.shutdown(); } catch (SecurityException ok) { return; }
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
             p.execute(r);
             assertFalse(r.done);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1145,16 +1280,16 @@
      * execute using DiscardPolicy drops task on shutdown
      */
     public void testDiscardOnShutdown() {
-        RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
-        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
-
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.DiscardPolicy());
         try { p.shutdown(); } catch (SecurityException ok) { return; }
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
             p.execute(r);
             assertFalse(r.done);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1162,16 +1297,17 @@
      * execute using DiscardOldestPolicy drops task on shutdown
      */
     public void testDiscardOldestOnShutdown() {
-        RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
-        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.DiscardOldestPolicy());
 
         try { p.shutdown(); } catch (SecurityException ok) { return; }
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
             p.execute(r);
             assertFalse(r.done);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1179,30 +1315,32 @@
      * execute(null) throws NPE
      */
     public void testExecuteNull() {
-        ThreadPoolExecutor p = null;
-        try {
-            p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
-            p.execute(null);
-            shouldThrow();
-        } catch (NullPointerException success) {}
-
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
     }
 
     /**
      * setCorePoolSize of negative value throws IllegalArgumentException
      */
     public void testCorePoolSizeIllegalArgumentException() {
-        ThreadPoolExecutor p =
-            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setCorePoolSize(-1);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setCorePoolSize(-1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
-        joinPool(p);
     }
 
     /**
@@ -1210,16 +1348,16 @@
      * if given a value less the core pool size
      */
     public void testMaximumPoolSizeIllegalArgumentException() {
-        ThreadPoolExecutor p =
-            new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setMaximumPoolSize(1);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 3,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setMaximumPoolSize(1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
-        joinPool(p);
     }
 
     /**
@@ -1227,16 +1365,16 @@
      * if given a negative value
      */
     public void testMaximumPoolSizeIllegalArgumentException2() {
-        ThreadPoolExecutor p =
-            new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setMaximumPoolSize(-1);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 3,
+                          LONG_DELAY_MS,
+                          MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setMaximumPoolSize(-1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
-        joinPool(p);
     }
 
     /**
@@ -1244,17 +1382,16 @@
      * when given a negative value
      */
     public void testKeepAliveTimeIllegalArgumentException() {
-        ThreadPoolExecutor p =
-            new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
-
-        try {
-            p.setKeepAliveTime(-1,MILLISECONDS);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 3,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setKeepAliveTime(-1, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
-        joinPool(p);
     }
 
     /**
@@ -1262,9 +1399,11 @@
      */
     public void testTerminated() {
         CustomTPE p = new CustomTPE();
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
-        assertTrue(p.terminatedCalled());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.terminatedCalled());
+            assertTrue(p.isShutdown());
+        }
     }
 
     /**
@@ -1272,7 +1411,7 @@
      */
     public void testBeforeAfter() throws InterruptedException {
         CustomTPE p = new CustomTPE();
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             final CountDownLatch done = new CountDownLatch(1);
             p.execute(new CheckedRunnable() {
                 public void realRun() {
@@ -1282,9 +1421,6 @@
             assertEquals(0, done.getCount());
             assertTrue(p.afterCalled());
             assertTrue(p.beforeCalled());
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1292,13 +1428,14 @@
      * completed submit of callable returns result
      */
     public void testSubmitCallable() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new StringTask());
             String result = future.get();
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1306,13 +1443,14 @@
      * completed submit of runnable returns successfully
      */
     public void testSubmitRunnable() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<?> future = e.submit(new NoOpRunnable());
             future.get();
             assertTrue(future.isDone());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1320,13 +1458,14 @@
      * completed submit of (runnable, result) returns result
      */
     public void testSubmitRunnable2() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
             String result = future.get();
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1334,13 +1473,15 @@
      * invokeAny(null) throws NPE
      */
     public void testInvokeAny1() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAny(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1348,13 +1489,15 @@
      * invokeAny(empty collection) throws IAE
      */
     public void testInvokeAny2() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>());
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -1363,17 +1506,19 @@
      */
     public void testInvokeAny3() throws Exception {
         CountDownLatch latch = new CountDownLatch(1);
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -1381,16 +1526,19 @@
      * invokeAny(c) throws ExecutionException if no task completes
      */
     public void testInvokeAny4() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -1398,15 +1546,16 @@
      * invokeAny(c) returns result of some task
      */
     public void testInvokeAny5() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             String result = e.invokeAny(l);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1414,13 +1563,15 @@
      * invokeAll(null) throws NPE
      */
     public void testInvokeAll1() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAll(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1428,12 +1579,13 @@
      * invokeAll(empty collection) returns empty collection
      */
     public void testInvokeAll2() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1441,16 +1593,18 @@
      * invokeAll(c) throws NPE if c has null elements
      */
     public void testInvokeAll3() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1458,18 +1612,21 @@
      * get of element of invokeAll(c) throws exception on failed task
      */
     public void testInvokeAll4() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        List<Future<String>> futures = e.invokeAll(l);
-        assertEquals(1, futures.size());
-        try {
-            futures.get(0).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -1477,8 +1634,11 @@
      * invokeAll(c) returns results of all completed tasks
      */
     public void testInvokeAll5() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
@@ -1486,8 +1646,6 @@
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1495,13 +1653,15 @@
      * timed invokeAny(null) throws NPE
      */
     public void testTimedInvokeAny1() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1509,15 +1669,17 @@
      * timed invokeAny(,,null) throws NPE
      */
     public void testTimedInvokeAnyNullTimeUnit() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1525,13 +1687,16 @@
      * timed invokeAny(empty collection) throws IAE
      */
     public void testTimedInvokeAny2() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(),
+                            MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -1540,17 +1705,19 @@
      */
     public void testTimedInvokeAny3() throws Exception {
         CountDownLatch latch = new CountDownLatch(1);
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -1558,16 +1725,21 @@
      * timed invokeAny(c) throws ExecutionException if no task completes
      */
     public void testTimedInvokeAny4() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -1575,15 +1747,18 @@
      * timed invokeAny(c) returns result of some task
      */
     public void testTimedInvokeAny5() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -1591,13 +1766,15 @@
      * timed invokeAll(null) throws NPE
      */
     public void testTimedInvokeAll1() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1605,15 +1782,17 @@
      * timed invokeAll(,,null) throws NPE
      */
     public void testTimedInvokeAllNullTimeUnit() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1621,12 +1800,14 @@
      * timed invokeAll(empty collection) returns empty collection
      */
     public void testTimedInvokeAll2() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(),
+                                                 MEDIUM_DELAY_MS, MILLISECONDS);
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1634,16 +1815,18 @@
      * timed invokeAll(c) throws NPE if c has null elements
      */
     public void testTimedInvokeAll3() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1651,19 +1834,22 @@
      * get of element of invokeAll(c) throws exception on failed task
      */
     public void testTimedInvokeAll4() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        List<Future<String>> futures =
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-        assertEquals(1, futures.size());
-        try {
-            futures.get(0).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -1671,18 +1857,19 @@
      * timed invokeAll(c) returns results of all completed tasks
      */
     public void testTimedInvokeAll5() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             List<Future<String>> futures =
-                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1690,21 +1877,40 @@
      * timed invokeAll(c) cancels tasks not completed by timeout
      */
     public void testTimedInvokeAll6() throws Exception {
-        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            List<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
-            l.add(new StringTask());
-            List<Future<String>> futures =
-                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
-            assertEquals(l.size(), futures.size());
-            for (Future future : futures)
-                assertTrue(future.isDone());
-            assertFalse(futures.get(0).isCancelled());
-            assertTrue(futures.get(1).isCancelled());
-        } finally {
-            joinPool(e);
+        for (long timeout = timeoutMillis();;) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Callable<String> waiter = new CheckedCallable<String>() {
+                public String realCall() {
+                    try { done.await(LONG_DELAY_MS, MILLISECONDS); }
+                    catch (InterruptedException ok) {}
+                    return "1"; }};
+            final ExecutorService p =
+                new CustomTPE(2, 2,
+                              LONG_DELAY_MS, MILLISECONDS,
+                              new ArrayBlockingQueue<Runnable>(10));
+            try (PoolCleaner cleaner = cleaner(p, done)) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(waiter);
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    p.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                assertTrue(futures.get(1).isCancelled());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals("2", futures.get(2).get());
+                    break;
+                } catch (CancellationException retryWithLongerTimeout) {
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                }
+            }
         }
     }
 
@@ -1718,7 +1924,7 @@
                           LONG_DELAY_MS, MILLISECONDS,
                           new LinkedBlockingQueue<Runnable>(),
                           new FailingThreadFactory());
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             final int TASKS = 100;
             final CountDownLatch done = new CountDownLatch(TASKS);
             for (int k = 0; k < TASKS; ++k)
@@ -1727,8 +1933,6 @@
                         done.countDown();
                     }});
             assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1736,38 +1940,40 @@
      * allowsCoreThreadTimeOut is by default false.
      */
     public void testAllowsCoreThreadTimeOut() {
-        ThreadPoolExecutor p = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        assertFalse(p.allowsCoreThreadTimeOut());
-        joinPool(p);
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 2,
+                          1000, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.allowsCoreThreadTimeOut());
+        }
     }
 
     /**
      * allowCoreThreadTimeOut(true) causes idle threads to time out
      */
     public void testAllowCoreThreadTimeOut_true() throws Exception {
-        long coreThreadTimeOut = SHORT_DELAY_MS;
+        long keepAliveTime = timeoutMillis();
         final ThreadPoolExecutor p =
             new CustomTPE(2, 10,
-                          coreThreadTimeOut, MILLISECONDS,
+                          keepAliveTime, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             p.allowCoreThreadTimeOut(true);
             p.execute(new CheckedRunnable() {
-                public void realRun() throws InterruptedException {
+                public void realRun() {
                     threadStarted.countDown();
                     assertEquals(1, p.getPoolSize());
                 }});
             await(threadStarted);
-            delay(coreThreadTimeOut);
+            delay(keepAliveTime);
             long startTime = System.nanoTime();
             while (p.getPoolSize() > 0
                    && millisElapsedSince(startTime) < LONG_DELAY_MS)
                 Thread.yield();
             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             assertEquals(0, p.getPoolSize());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1775,23 +1981,59 @@
      * allowCoreThreadTimeOut(false) causes idle threads not to time out
      */
     public void testAllowCoreThreadTimeOut_false() throws Exception {
-        long coreThreadTimeOut = SHORT_DELAY_MS;
+        long keepAliveTime = timeoutMillis();
         final ThreadPoolExecutor p =
             new CustomTPE(2, 10,
-                          coreThreadTimeOut, MILLISECONDS,
+                          keepAliveTime, MILLISECONDS,
                           new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             p.allowCoreThreadTimeOut(false);
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertTrue(p.getPoolSize() >= 1);
                 }});
-            delay(2 * coreThreadTimeOut);
+            delay(2 * keepAliveTime);
             assertTrue(p.getPoolSize() >= 1);
-        } finally {
-            joinPool(p);
+        }
+    }
+
+    /**
+     * get(cancelled task) throws CancellationException
+     * (in part, a test of CustomTPE itself)
+     */
+    public void testGet_cancelled() throws Exception {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ExecutorService e =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new LinkedBlockingQueue<Runnable>());
+        try (PoolCleaner cleaner = cleaner(e, done)) {
+            final CountDownLatch blockerStarted = new CountDownLatch(1);
+            final List<Future<?>> futures = new ArrayList<>();
+            for (int i = 0; i < 2; i++) {
+                Runnable r = new CheckedRunnable() { public void realRun()
+                                                         throws Throwable {
+                    blockerStarted.countDown();
+                    assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
+                }};
+                futures.add(e.submit(r));
+            }
+            await(blockerStarted);
+            for (Future<?> future : futures) future.cancel(false);
+            for (Future<?> future : futures) {
+                try {
+                    future.get();
+                    shouldThrow();
+                } catch (CancellationException success) {}
+                try {
+                    future.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {}
+                assertTrue(future.isCancelled());
+                assertTrue(future.isDone());
+            }
         }
     }
 
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java
index 52a7002..7fe26f4 100644
--- a/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ThreadPoolExecutorTest.java
@@ -10,12 +10,14 @@
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
@@ -29,6 +31,7 @@
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -41,7 +44,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ThreadPoolExecutorTest.class);
     // }
 
     static class ExtendedTPE extends ThreadPoolExecutor {
@@ -89,16 +92,12 @@
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch done = new CountDownLatch(1);
-        final Runnable task = new CheckedRunnable() {
-            public void realRun() {
-                done.countDown();
-            }};
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() { done.countDown(); }};
             p.execute(task);
-            assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
-        } finally {
-            joinPool(p);
+            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
         }
     }
 
@@ -107,25 +106,22 @@
      * thread becomes active
      */
     public void testGetActiveCount() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertEquals(0, p.getActiveCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertEquals(1, p.getActiveCount());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getActiveCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -134,17 +130,25 @@
      */
     public void testPrestartCoreThread() {
         final ThreadPoolExecutor p =
-            new ThreadPoolExecutor(2, 2,
+            new ThreadPoolExecutor(2, 6,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(0, p.getPoolSize());
-        assertTrue(p.prestartCoreThread());
-        assertEquals(1, p.getPoolSize());
-        assertTrue(p.prestartCoreThread());
-        assertEquals(2, p.getPoolSize());
-        assertFalse(p.prestartCoreThread());
-        assertEquals(2, p.getPoolSize());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(0, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(1, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(2, p.getPoolSize());
+            assertFalse(p.prestartCoreThread());
+            assertEquals(2, p.getPoolSize());
+            p.setCorePoolSize(4);
+            assertTrue(p.prestartCoreThread());
+            assertEquals(3, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(4, p.getPoolSize());
+            assertFalse(p.prestartCoreThread());
+            assertEquals(4, p.getPoolSize());
+        }
     }
 
     /**
@@ -152,15 +156,21 @@
      */
     public void testPrestartAllCoreThreads() {
         final ThreadPoolExecutor p =
-            new ThreadPoolExecutor(2, 2,
+            new ThreadPoolExecutor(2, 6,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(0, p.getPoolSize());
-        p.prestartAllCoreThreads();
-        assertEquals(2, p.getPoolSize());
-        p.prestartAllCoreThreads();
-        assertEquals(2, p.getPoolSize());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(0, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(2, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(2, p.getPoolSize());
+            p.setCorePoolSize(4);
+            p.prestartAllCoreThreads();
+            assertEquals(4, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(4, p.getPoolSize());
+        }
     }
 
     /**
@@ -172,10 +182,10 @@
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch threadProceed = new CountDownLatch(1);
-        final CountDownLatch threadDone = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch threadProceed = new CountDownLatch(1);
+            final CountDownLatch threadDone = new CountDownLatch(1);
             assertEquals(0, p.getCompletedTaskCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
@@ -194,8 +204,6 @@
                     fail("timed out");
                 Thread.yield();
             }
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -207,8 +215,9 @@
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(1, p.getCorePoolSize());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getCorePoolSize());
+        }
     }
 
     /**
@@ -219,23 +228,25 @@
             new ThreadPoolExecutor(2, 2,
                                    1000, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(1, p.getKeepAliveTime(TimeUnit.SECONDS));
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getKeepAliveTime(SECONDS));
+        }
     }
 
     /**
      * getThreadFactory returns factory in constructor if not set
      */
     public void testGetThreadFactory() {
-        ThreadFactory tf = new SimpleThreadFactory();
+        ThreadFactory threadFactory = new SimpleThreadFactory();
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
-                                   tf,
+                                   threadFactory,
                                    new NoOpREHandler());
-        assertSame(tf, p.getThreadFactory());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(threadFactory, p.getThreadFactory());
+        }
     }
 
     /**
@@ -246,10 +257,11 @@
             new ThreadPoolExecutor(1, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        ThreadFactory tf = new SimpleThreadFactory();
-        p.setThreadFactory(tf);
-        assertSame(tf, p.getThreadFactory());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            ThreadFactory threadFactory = new SimpleThreadFactory();
+            p.setThreadFactory(threadFactory);
+            assertSame(threadFactory, p.getThreadFactory());
+        }
     }
 
     /**
@@ -260,12 +272,11 @@
             new ThreadPoolExecutor(1, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setThreadFactory(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setThreadFactory(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -273,14 +284,15 @@
      * getRejectedExecutionHandler returns handler in constructor if not set
      */
     public void testGetRejectedExecutionHandler() {
-        final RejectedExecutionHandler h = new NoOpREHandler();
+        final RejectedExecutionHandler handler = new NoOpREHandler();
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
-                                   h);
-        assertSame(h, p.getRejectedExecutionHandler());
-        joinPool(p);
+                                   handler);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(handler, p.getRejectedExecutionHandler());
+        }
     }
 
     /**
@@ -292,10 +304,11 @@
             new ThreadPoolExecutor(1, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        RejectedExecutionHandler h = new NoOpREHandler();
-        p.setRejectedExecutionHandler(h);
-        assertSame(h, p.getRejectedExecutionHandler());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            RejectedExecutionHandler handler = new NoOpREHandler();
+            p.setRejectedExecutionHandler(handler);
+            assertSame(handler, p.getRejectedExecutionHandler());
+        }
     }
 
     /**
@@ -306,12 +319,11 @@
             new ThreadPoolExecutor(1, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setRejectedExecutionHandler(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setRejectedExecutionHandler(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -321,28 +333,25 @@
      */
     public void testGetLargestPoolSize() throws InterruptedException {
         final int THREADS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(THREADS, THREADS,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             assertEquals(0, p.getLargestPoolSize());
+            final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
             for (int i = 0; i < THREADS; i++)
                 p.execute(new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadsStarted.countDown();
-                        done.await();
+                        await(done);
                         assertEquals(THREADS, p.getLargestPoolSize());
                     }});
-            assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
-            assertEquals(THREADS, p.getLargestPoolSize());
-        } finally {
-            done.countDown();
-            joinPool(p);
+            await(threadsStarted);
             assertEquals(THREADS, p.getLargestPoolSize());
         }
+        assertEquals(THREADS, p.getLargestPoolSize());
     }
 
     /**
@@ -354,8 +363,13 @@
             new ThreadPoolExecutor(2, 3,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        assertEquals(3, p.getMaximumPoolSize());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(3, p.getMaximumPoolSize());
+            p.setMaximumPoolSize(5);
+            assertEquals(5, p.getMaximumPoolSize());
+            p.setMaximumPoolSize(4);
+            assertEquals(4, p.getMaximumPoolSize());
+        }
     }
 
     /**
@@ -363,25 +377,22 @@
      * become active
      */
     public void testGetPoolSize() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             assertEquals(0, p.getPoolSize());
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertEquals(1, p.getPoolSize());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getPoolSize());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -389,26 +400,38 @@
      * getTaskCount increases, but doesn't overestimate, when tasks submitted
      */
     public void testGetTaskCount() throws InterruptedException {
+        final int TASKS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             assertEquals(0, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
-                    assertEquals(1, p.getTaskCount());
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(1, p.getTaskCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
+            assertEquals(0, p.getCompletedTaskCount());
+            for (int i = 0; i < TASKS; i++) {
+                assertEquals(1 + i, p.getTaskCount());
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        assertEquals(1 + TASKS, p.getTaskCount());
+                        await(done);
+                    }});
+            }
+            assertEquals(1 + TASKS, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
         }
+        assertEquals(1 + TASKS, p.getTaskCount());
+        assertEquals(1 + TASKS, p.getCompletedTaskCount());
     }
 
     /**
@@ -419,10 +442,11 @@
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        assertFalse(p.isShutdown());
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
-        assertTrue(p.isShutdown());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isShutdown());
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.isShutdown());
+        }
     }
 
     /**
@@ -433,26 +457,28 @@
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        assertFalse(p.isTerminated());
-        assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
-        assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
-        assertFalse(p.awaitTermination(-1L, NANOSECONDS));
-        assertFalse(p.awaitTermination(-1L, MILLISECONDS));
-        assertFalse(p.awaitTermination(0L, NANOSECONDS));
-        assertFalse(p.awaitTermination(0L, MILLISECONDS));
-        long timeoutNanos = 999999L;
-        long startTime = System.nanoTime();
-        assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
-        assertTrue(System.nanoTime() - startTime >= timeoutNanos);
-        assertFalse(p.isTerminated());
-        startTime = System.nanoTime();
-        long timeoutMillis = timeoutMillis();
-        assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
-        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
-        assertFalse(p.isTerminated());
-        p.shutdown();
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isTerminated());
+            assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
+            assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
+            assertFalse(p.awaitTermination(-1L, NANOSECONDS));
+            assertFalse(p.awaitTermination(-1L, MILLISECONDS));
+            assertFalse(p.awaitTermination(0L, NANOSECONDS));
+            assertFalse(p.awaitTermination(0L, MILLISECONDS));
+            long timeoutNanos = 999999L;
+            long startTime = System.nanoTime();
+            assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
+            assertTrue(System.nanoTime() - startTime >= timeoutNanos);
+            assertFalse(p.isTerminated());
+            startTime = System.nanoTime();
+            long timeoutMillis = timeoutMillis();
+            assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            assertFalse(p.isTerminated());
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+        }
     }
 
     /**
@@ -463,24 +489,24 @@
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        assertFalse(p.isTerminated());
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
+            assertFalse(p.isTerminating());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
-                    assertFalse(p.isTerminated());
+                    assertFalse(p.isTerminating());
                     threadStarted.countDown();
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertFalse(p.isTerminating());
             done.countDown();
-        } finally {
             try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
         }
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
     }
 
     /**
@@ -491,59 +517,55 @@
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
             assertFalse(p.isTerminating());
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     assertFalse(p.isTerminating());
                     threadStarted.countDown();
-                    done.await();
+                    await(done);
                 }});
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertFalse(p.isTerminating());
             done.countDown();
-        } finally {
             try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
         }
-        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
-        assertTrue(p.isTerminated());
-        assertFalse(p.isTerminating());
     }
 
     /**
      * getQueue returns the work queue, which contains queued tasks
      */
     public void testGetQueue() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
         final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    q);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             FutureTask[] tasks = new FutureTask[5];
             for (int i = 0; i < tasks.length; i++) {
                 Callable task = new CheckedCallable<Boolean>() {
                     public Boolean realCall() throws InterruptedException {
                         threadStarted.countDown();
                         assertSame(q, p.getQueue());
-                        done.await();
+                        await(done);
                         return Boolean.TRUE;
                     }};
                 tasks[i] = new FutureTask(task);
                 p.execute(tasks[i]);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertSame(q, p.getQueue());
             assertFalse(q.contains(tasks[0]));
             assertTrue(q.contains(tasks[tasks.length - 1]));
             assertEquals(tasks.length - 1, q.size());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -551,24 +573,24 @@
      * remove(task) removes queued task, and fails to remove active task
      */
     public void testRemove() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
         BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    q);
-        Runnable[] tasks = new Runnable[5];
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable[] tasks = new Runnable[6];
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             for (int i = 0; i < tasks.length; i++) {
                 tasks[i] = new CheckedRunnable() {
                     public void realRun() throws InterruptedException {
                         threadStarted.countDown();
-                        done.await();
+                        await(done);
                     }};
                 p.execute(tasks[i]);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertFalse(p.remove(tasks[0]));
             assertTrue(q.contains(tasks[4]));
             assertTrue(q.contains(tasks[3]));
@@ -578,9 +600,6 @@
             assertTrue(q.contains(tasks[3]));
             assertTrue(p.remove(tasks[3]));
             assertFalse(q.contains(tasks[3]));
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -595,19 +614,19 @@
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    q);
-        FutureTask[] tasks = new FutureTask[5];
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            FutureTask[] tasks = new FutureTask[5];
             for (int i = 0; i < tasks.length; i++) {
                 Callable task = new CheckedCallable<Boolean>() {
                     public Boolean realCall() throws InterruptedException {
                         threadStarted.countDown();
-                        done.await();
+                        await(done);
                         return Boolean.TRUE;
                     }};
                 tasks[i] = new FutureTask(task);
                 p.execute(tasks[i]);
             }
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             assertEquals(tasks.length, p.getTaskCount());
             assertEquals(tasks.length - 1, q.size());
             assertEquals(1L, p.getActiveCount());
@@ -620,32 +639,47 @@
             p.purge();         // Nothing to do
             assertEquals(tasks.length - 3, q.size());
             assertEquals(tasks.length - 2, p.getTaskCount());
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
     /**
-     * shutdownNow returns a list containing tasks that were not run
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
      */
-    public void testShutdownNow() {
+    public void testShutdownNow() throws InterruptedException {
+        final int poolSize = 2;
+        final int count = 5;
+        final AtomicInteger ran = new AtomicInteger(0);
         final ThreadPoolExecutor p =
-            new ThreadPoolExecutor(1, 1,
+            new ThreadPoolExecutor(poolSize, poolSize,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List l;
-        try {
-            for (int i = 0; i < 5; i++)
-                p.execute(new MediumPossiblyInterruptedRunnable());
-        }
-        finally {
+        final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
+        Runnable waiter = new CheckedRunnable() { public void realRun() {
+            threadsStarted.countDown();
             try {
-                l = p.shutdownNow();
-            } catch (SecurityException ok) { return; }
+                MILLISECONDS.sleep(2 * LONG_DELAY_MS);
+            } catch (InterruptedException success) {}
+            ran.getAndIncrement();
+        }};
+        for (int i = 0; i < count; i++)
+            p.execute(waiter);
+        await(threadsStarted);
+        assertEquals(poolSize, p.getActiveCount());
+        assertEquals(0, p.getCompletedTaskCount());
+        final List<Runnable> queuedTasks;
+        try {
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
         }
         assertTrue(p.isShutdown());
-        assertTrue(l.size() <= 4);
+        assertTrue(p.getQueue().isEmpty());
+        assertEquals(count - poolSize, queuedTasks.size());
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(poolSize, ran.get());
+        assertEquals(poolSize, p.getCompletedTaskCount());
     }
 
     // Exception Tests
@@ -655,8 +689,7 @@
      */
     public void testConstructor1() {
         try {
-            new ThreadPoolExecutor(-1, 1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -667,8 +700,7 @@
      */
     public void testConstructor2() {
         try {
-            new ThreadPoolExecutor(1, -1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, -1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -679,8 +711,7 @@
      */
     public void testConstructor3() {
         try {
-            new ThreadPoolExecutor(1, 0,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 0, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -691,8 +722,7 @@
      */
     public void testConstructor4() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   -1L, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, -1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -703,8 +733,7 @@
      */
     public void testConstructor5() {
         try {
-            new ThreadPoolExecutor(2, 1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(2, 1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
         } catch (IllegalArgumentException success) {}
@@ -715,8 +744,7 @@
      */
     public void testConstructorNullPointerException() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
                                    (BlockingQueue) null);
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -727,8 +755,7 @@
      */
     public void testConstructor6() {
         try {
-            new ThreadPoolExecutor(-1, 1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory());
             shouldThrow();
@@ -740,8 +767,7 @@
      */
     public void testConstructor7() {
         try {
-            new ThreadPoolExecutor(1, -1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, -1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory());
             shouldThrow();
@@ -753,8 +779,7 @@
      */
     public void testConstructor8() {
         try {
-            new ThreadPoolExecutor(1, 0,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 0, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory());
             shouldThrow();
@@ -766,8 +791,7 @@
      */
     public void testConstructor9() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   -1L, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, -1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory());
             shouldThrow();
@@ -779,8 +803,7 @@
      */
     public void testConstructor10() {
         try {
-            new ThreadPoolExecutor(2, 1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(2, 1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory());
             shouldThrow();
@@ -792,8 +815,7 @@
      */
     public void testConstructorNullPointerException2() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
                                    (BlockingQueue) null,
                                    new SimpleThreadFactory());
             shouldThrow();
@@ -805,8 +827,7 @@
      */
     public void testConstructorNullPointerException3() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    (ThreadFactory) null);
             shouldThrow();
@@ -818,8 +839,7 @@
      */
     public void testConstructor11() {
         try {
-            new ThreadPoolExecutor(-1, 1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new NoOpREHandler());
             shouldThrow();
@@ -831,8 +851,7 @@
      */
     public void testConstructor12() {
         try {
-            new ThreadPoolExecutor(1, -1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, -1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new NoOpREHandler());
             shouldThrow();
@@ -844,8 +863,7 @@
      */
     public void testConstructor13() {
         try {
-            new ThreadPoolExecutor(1, 0,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 0, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new NoOpREHandler());
             shouldThrow();
@@ -857,8 +875,7 @@
      */
     public void testConstructor14() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   -1L, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, -1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new NoOpREHandler());
             shouldThrow();
@@ -870,8 +887,7 @@
      */
     public void testConstructor15() {
         try {
-            new ThreadPoolExecutor(2, 1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(2, 1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new NoOpREHandler());
             shouldThrow();
@@ -883,8 +899,7 @@
      */
     public void testConstructorNullPointerException4() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
                                    (BlockingQueue) null,
                                    new NoOpREHandler());
             shouldThrow();
@@ -896,8 +911,7 @@
      */
     public void testConstructorNullPointerException5() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    (RejectedExecutionHandler) null);
             shouldThrow();
@@ -909,8 +923,7 @@
      */
     public void testConstructor16() {
         try {
-            new ThreadPoolExecutor(-1, 1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory(),
                                    new NoOpREHandler());
@@ -923,8 +936,7 @@
      */
     public void testConstructor17() {
         try {
-            new ThreadPoolExecutor(1, -1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, -1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory(),
                                    new NoOpREHandler());
@@ -937,8 +949,7 @@
      */
     public void testConstructor18() {
         try {
-            new ThreadPoolExecutor(1, 0,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 0, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory(),
                                    new NoOpREHandler());
@@ -951,8 +962,7 @@
      */
     public void testConstructor19() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   -1L, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, -1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory(),
                                    new NoOpREHandler());
@@ -965,8 +975,7 @@
      */
     public void testConstructor20() {
         try {
-            new ThreadPoolExecutor(2, 1,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(2, 1, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory(),
                                    new NoOpREHandler());
@@ -979,8 +988,7 @@
      */
     public void testConstructorNullPointerException6() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
                                    (BlockingQueue) null,
                                    new SimpleThreadFactory(),
                                    new NoOpREHandler());
@@ -993,8 +1001,7 @@
      */
     public void testConstructorNullPointerException7() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    new SimpleThreadFactory(),
                                    (RejectedExecutionHandler) null);
@@ -1007,8 +1014,7 @@
      */
     public void testConstructorNullPointerException8() {
         try {
-            new ThreadPoolExecutor(1, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10),
                                    (ThreadFactory) null,
                                    new NoOpREHandler());
@@ -1020,31 +1026,28 @@
      * get of submitted callable throws InterruptedException if interrupted
      */
     public void testInterruptedSubmit() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
-                                   60, TimeUnit.SECONDS,
+                                   60, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
 
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             Thread t = newStartedThread(new CheckedInterruptedRunnable() {
                 public void realRun() throws Exception {
                     Callable task = new CheckedCallable<Boolean>() {
                         public Boolean realCall() throws InterruptedException {
                             threadStarted.countDown();
-                            done.await();
+                            await(done);
                             return Boolean.TRUE;
                         }};
                     p.submit(task).get();
                 }});
 
-            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
+            await(threadStarted);
             t.interrupt();
-            awaitTermination(t, MEDIUM_DELAY_MS);
-        } finally {
-            done.countDown();
-            joinPool(p);
+            awaitTermination(t);
         }
     }
 
@@ -1052,15 +1055,15 @@
      * execute throws RejectedExecutionException if saturated.
      */
     public void testSaturatedExecute() {
-        ThreadPoolExecutor p =
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(1));
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             Runnable task = new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
-                    done.await();
+                    await(done);
                 }};
             for (int i = 0; i < 2; ++i)
                 p.execute(task);
@@ -1071,9 +1074,6 @@
                 } catch (RejectedExecutionException success) {}
                 assertTrue(p.getTaskCount() <= 2);
             }
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -1081,15 +1081,15 @@
      * submit(runnable) throws RejectedExecutionException if saturated.
      */
     public void testSaturatedSubmitRunnable() {
-        ThreadPoolExecutor p =
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(1));
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             Runnable task = new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
-                    done.await();
+                    await(done);
                 }};
             for (int i = 0; i < 2; ++i)
                 p.submit(task);
@@ -1100,9 +1100,6 @@
                 } catch (RejectedExecutionException success) {}
                 assertTrue(p.getTaskCount() <= 2);
             }
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -1110,15 +1107,15 @@
      * submit(callable) throws RejectedExecutionException if saturated.
      */
     public void testSaturatedSubmitCallable() {
-        ThreadPoolExecutor p =
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(1));
-        final CountDownLatch done = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p, done)) {
             Runnable task = new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
-                    done.await();
+                    await(done);
                 }};
             for (int i = 0; i < 2; ++i)
                 p.submit(Executors.callable(task));
@@ -1129,9 +1126,6 @@
                 } catch (RejectedExecutionException success) {}
                 assertTrue(p.getTaskCount() <= 2);
             }
-        } finally {
-            done.countDown();
-            joinPool(p);
         }
     }
 
@@ -1139,26 +1133,28 @@
      * executor using CallerRunsPolicy runs task if saturated.
      */
     public void testSaturatedExecute2() {
-        RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy();
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS,
                                    MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(1),
-                                   h);
-        try {
+                                   new ThreadPoolExecutor.CallerRunsPolicy());
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            Runnable blocker = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    await(done);
+                }};
+            p.execute(blocker);
             TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
-            for (int i = 0; i < tasks.length; ++i)
+            for (int i = 0; i < tasks.length; i++)
                 tasks[i] = new TrackedNoOpRunnable();
-            TrackedLongRunnable mr = new TrackedLongRunnable();
-            p.execute(mr);
-            for (int i = 0; i < tasks.length; ++i)
+            for (int i = 0; i < tasks.length; i++)
                 p.execute(tasks[i]);
-            for (int i = 1; i < tasks.length; ++i)
+            for (int i = 1; i < tasks.length; i++)
                 assertTrue(tasks[i].done);
-            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
-        } finally {
-            joinPool(p);
+            assertFalse(tasks[0].done); // waiting in queue
+            done.countDown();
         }
     }
 
@@ -1166,67 +1162,72 @@
      * executor using DiscardPolicy drops task if saturated.
      */
     public void testSaturatedExecute3() {
-        RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy();
+        final CountDownLatch done = new CountDownLatch(1);
+        final TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+        for (int i = 0; i < tasks.length; ++i)
+            tasks[i] = new TrackedNoOpRunnable();
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
-                                   LONG_DELAY_MS, MILLISECONDS,
-                                   new ArrayBlockingQueue<Runnable>(1),
-                                   h);
-        try {
-            TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
-            for (int i = 0; i < tasks.length; ++i)
-                tasks[i] = new TrackedNoOpRunnable();
-            p.execute(new TrackedLongRunnable());
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new ThreadPoolExecutor.DiscardPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            p.execute(awaiter(done));
+
             for (TrackedNoOpRunnable task : tasks)
                 p.execute(task);
-            for (TrackedNoOpRunnable task : tasks)
-                assertFalse(task.done);
-            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
-        } finally {
-            joinPool(p);
+            for (int i = 1; i < tasks.length; i++)
+                assertFalse(tasks[i].done);
         }
+        for (int i = 1; i < tasks.length; i++)
+            assertFalse(tasks[i].done);
+        assertTrue(tasks[0].done); // was waiting in queue
     }
 
     /**
      * executor using DiscardOldestPolicy drops oldest task if saturated.
      */
     public void testSaturatedExecute4() {
-        RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy();
+        final CountDownLatch done = new CountDownLatch(1);
+        LatchAwaiter r1 = awaiter(done);
+        LatchAwaiter r2 = awaiter(done);
+        LatchAwaiter r3 = awaiter(done);
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(1),
-                                   h);
-        try {
-            p.execute(new TrackedLongRunnable());
-            TrackedLongRunnable r2 = new TrackedLongRunnable();
+                                   new ThreadPoolExecutor.DiscardOldestPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(LatchAwaiter.NEW, r1.state);
+            assertEquals(LatchAwaiter.NEW, r2.state);
+            assertEquals(LatchAwaiter.NEW, r3.state);
+            p.execute(r1);
             p.execute(r2);
             assertTrue(p.getQueue().contains(r2));
-            TrackedNoOpRunnable r3 = new TrackedNoOpRunnable();
             p.execute(r3);
             assertFalse(p.getQueue().contains(r2));
             assertTrue(p.getQueue().contains(r3));
-            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
-        } finally {
-            joinPool(p);
         }
+        assertEquals(LatchAwaiter.DONE, r1.state);
+        assertEquals(LatchAwaiter.NEW, r2.state);
+        assertEquals(LatchAwaiter.DONE, r3.state);
     }
 
     /**
      * execute throws RejectedExecutionException if shutdown
      */
     public void testRejectedExecutionExceptionOnShutdown() {
-        ThreadPoolExecutor p =
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(1));
         try { p.shutdown(); } catch (SecurityException ok) { return; }
-        try {
-            p.execute(new NoOpRunnable());
-            shouldThrow();
-        } catch (RejectedExecutionException success) {}
-
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(new NoOpRunnable());
+                shouldThrow();
+            } catch (RejectedExecutionException success) {}
+        }
     }
 
     /**
@@ -1240,12 +1241,10 @@
                                    new ArrayBlockingQueue<Runnable>(1), h);
 
         try { p.shutdown(); } catch (SecurityException ok) { return; }
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
             p.execute(r);
             assertFalse(r.done);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1253,20 +1252,17 @@
      * execute using DiscardPolicy drops task on shutdown
      */
     public void testDiscardOnShutdown() {
-        RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy();
-        ThreadPoolExecutor p =
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(1),
-                                   h);
+                                   new ThreadPoolExecutor.DiscardPolicy());
 
         try { p.shutdown(); } catch (SecurityException ok) { return; }
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
             p.execute(r);
             assertFalse(r.done);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1274,20 +1270,17 @@
      * execute using DiscardOldestPolicy drops task on shutdown
      */
     public void testDiscardOldestOnShutdown() {
-        RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy();
-        ThreadPoolExecutor p =
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 1,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(1),
-                                   h);
+                                   new ThreadPoolExecutor.DiscardOldestPolicy());
 
         try { p.shutdown(); } catch (SecurityException ok) { return; }
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
             p.execute(r);
             assertFalse(r.done);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1295,34 +1288,32 @@
      * execute(null) throws NPE
      */
     public void testExecuteNull() {
-        ThreadPoolExecutor p =
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
+                                   1L, SECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.execute(null);
-            shouldThrow();
-        } catch (NullPointerException success) {}
-
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
     }
 
     /**
      * setCorePoolSize of negative value throws IllegalArgumentException
      */
     public void testCorePoolSizeIllegalArgumentException() {
-        ThreadPoolExecutor p =
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(1, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setCorePoolSize(-1);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setCorePoolSize(-1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
-        joinPool(p);
     }
 
     /**
@@ -1330,18 +1321,16 @@
      * given a value less the core pool size
      */
     public void testMaximumPoolSizeIllegalArgumentException() {
-        ThreadPoolExecutor p =
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(2, 3,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setMaximumPoolSize(1);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setMaximumPoolSize(1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
-        joinPool(p);
     }
 
     /**
@@ -1349,18 +1338,45 @@
      * if given a negative value
      */
     public void testMaximumPoolSizeIllegalArgumentException2() {
-        ThreadPoolExecutor p =
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(2, 3,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setMaximumPoolSize(-1);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setMaximumPoolSize(-1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
-        joinPool(p);
+    }
+
+    /**
+     * Configuration changes that allow core pool size greater than
+     * max pool size result in IllegalArgumentException.
+     */
+    public void testPoolSizeInvariants() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            for (int s = 1; s < 5; s++) {
+                p.setMaximumPoolSize(s);
+                p.setCorePoolSize(s);
+                try {
+                    p.setMaximumPoolSize(s - 1);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+                assertEquals(s, p.getCorePoolSize());
+                assertEquals(s, p.getMaximumPoolSize());
+                try {
+                    p.setCorePoolSize(s + 1);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+                assertEquals(s, p.getCorePoolSize());
+                assertEquals(s, p.getMaximumPoolSize());
+            }
+        }
     }
 
     /**
@@ -1368,18 +1384,16 @@
      * when given a negative value
      */
     public void testKeepAliveTimeIllegalArgumentException() {
-        ThreadPoolExecutor p =
+        final ThreadPoolExecutor p =
             new ThreadPoolExecutor(2, 3,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            p.setKeepAliveTime(-1,MILLISECONDS);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setKeepAliveTime(-1, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
-        joinPool(p);
     }
 
     /**
@@ -1387,9 +1401,11 @@
      */
     public void testTerminated() {
         ExtendedTPE p = new ExtendedTPE();
-        try { p.shutdown(); } catch (SecurityException ok) { return; }
-        assertTrue(p.terminatedCalled());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.terminatedCalled());
+            assertTrue(p.isShutdown());
+        }
     }
 
     /**
@@ -1397,7 +1413,7 @@
      */
     public void testBeforeAfter() throws InterruptedException {
         ExtendedTPE p = new ExtendedTPE();
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             final CountDownLatch done = new CountDownLatch(1);
             p.execute(new CheckedRunnable() {
                 public void realRun() {
@@ -1407,9 +1423,6 @@
             assertEquals(0, done.getCount());
             assertTrue(p.afterCalled());
             assertTrue(p.beforeCalled());
-            try { p.shutdown(); } catch (SecurityException ok) { return; }
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1417,16 +1430,14 @@
      * completed submit of callable returns result
      */
     public void testSubmitCallable() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new StringTask());
             String result = future.get();
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1434,16 +1445,14 @@
      * completed submit of runnable returns successfully
      */
     public void testSubmitRunnable() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<?> future = e.submit(new NoOpRunnable());
             future.get();
             assertTrue(future.isDone());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1451,16 +1460,14 @@
      * completed submit of (runnable, result) returns result
      */
     public void testSubmitRunnable2() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
             String result = future.get();
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1468,16 +1475,15 @@
      * invokeAny(null) throws NPE
      */
     public void testInvokeAny1() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAny(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1485,16 +1491,15 @@
      * invokeAny(empty collection) throws IAE
      */
     public void testInvokeAny2() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>());
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -1507,16 +1512,15 @@
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -1524,19 +1528,19 @@
      * invokeAny(c) throws ExecutionException if no task completes
      */
     public void testInvokeAny4() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -1544,18 +1548,16 @@
      * invokeAny(c) returns result of some task
      */
     public void testInvokeAny5() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             String result = e.invokeAny(l);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1563,16 +1565,15 @@
      * invokeAll(null) throws NPE
      */
     public void testInvokeAll1() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAll(null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1580,15 +1581,13 @@
      * invokeAll(empty collection) returns empty collection
      */
     public void testInvokeAll2() throws InterruptedException {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1596,19 +1595,18 @@
      * invokeAll(c) throws NPE if c has null elements
      */
     public void testInvokeAll3() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1616,11 +1614,11 @@
      * get of element of invokeAll(c) throws exception on failed task
      */
     public void testInvokeAll4() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new NPETask());
             List<Future<String>> futures = e.invokeAll(l);
@@ -1631,8 +1629,6 @@
             } catch (ExecutionException success) {
                 assertTrue(success.getCause() instanceof NullPointerException);
             }
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1640,11 +1636,11 @@
      * invokeAll(c) returns results of all completed tasks
      */
     public void testInvokeAll5() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
@@ -1652,8 +1648,6 @@
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1661,16 +1655,15 @@
      * timed invokeAny(null) throws NPE
      */
     public void testTimedInvokeAny1() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1678,18 +1671,17 @@
      * timed invokeAny(,,null) throws NPE
      */
     public void testTimedInvokeAnyNullTimeUnit() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1697,16 +1689,16 @@
      * timed invokeAny(empty collection) throws IAE
      */
     public void testTimedInvokeAny2() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(),
+                            MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
         }
     }
 
@@ -1719,16 +1711,15 @@
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(latchAwaitingStringTask(latch));
-        l.add(null);
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
             latch.countDown();
-            joinPool(e);
         }
     }
 
@@ -1736,19 +1727,21 @@
      * timed invokeAny(c) throws ExecutionException if no task completes
      */
     public void testTimedInvokeAny4() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        try {
-            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -1756,18 +1749,18 @@
      * timed invokeAny(c) returns result of some task
      */
     public void testTimedInvokeAny5() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
             assertSame(TEST_STRING, result);
-        } finally {
-            joinPool(e);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
         }
     }
 
@@ -1775,16 +1768,15 @@
      * timed invokeAll(null) throws NPE
      */
     public void testTimedInvokeAll1() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1792,18 +1784,17 @@
      * timed invokeAll(,,null) throws NPE
      */
     public void testTimedInvokeAllNullTimeUnit() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, null);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1811,15 +1802,14 @@
      * timed invokeAll(empty collection) returns empty collection
      */
     public void testTimedInvokeAll2() throws InterruptedException {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
-            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(),
+                                                 MEDIUM_DELAY_MS, MILLISECONDS);
             assertTrue(r.isEmpty());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1827,19 +1817,18 @@
      * timed invokeAll(c) throws NPE if c has null elements
      */
     public void testTimedInvokeAll3() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new StringTask());
-        l.add(null);
-        try {
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-            shouldThrow();
-        } catch (NullPointerException success) {
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
         }
     }
 
@@ -1847,22 +1836,22 @@
      * get of element of invokeAll(c) throws exception on failed task
      */
     public void testTimedInvokeAll4() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        List<Callable<String>> l = new ArrayList<Callable<String>>();
-        l.add(new NPETask());
-        List<Future<String>> futures =
-            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
-        assertEquals(1, futures.size());
-        try {
-            futures.get(0).get();
-            shouldThrow();
-        } catch (ExecutionException success) {
-            assertTrue(success.getCause() instanceof NullPointerException);
-        } finally {
-            joinPool(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new NPETask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         }
     }
 
@@ -1870,21 +1859,19 @@
      * timed invokeAll(c) returns results of all completed tasks
      */
     public void testTimedInvokeAll5() throws Exception {
-        ExecutorService e =
+        final ExecutorService e =
             new ThreadPoolExecutor(2, 2,
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             List<Future<String>> futures =
-                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
             assertEquals(2, futures.size());
             for (Future<String> future : futures)
                 assertSame(TEST_STRING, future.get());
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1892,24 +1879,40 @@
      * timed invokeAll(c) cancels tasks not completed by timeout
      */
     public void testTimedInvokeAll6() throws Exception {
-        ExecutorService e =
-            new ThreadPoolExecutor(2, 2,
-                                   LONG_DELAY_MS, MILLISECONDS,
-                                   new ArrayBlockingQueue<Runnable>(10));
-        try {
-            List<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
-            l.add(new StringTask());
-            List<Future<String>> futures =
-                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
-            assertEquals(l.size(), futures.size());
-            for (Future future : futures)
-                assertTrue(future.isDone());
-            assertFalse(futures.get(0).isCancelled());
-            assertTrue(futures.get(1).isCancelled());
-        } finally {
-            joinPool(e);
+        for (long timeout = timeoutMillis();;) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Callable<String> waiter = new CheckedCallable<String>() {
+                public String realCall() {
+                    try { done.await(LONG_DELAY_MS, MILLISECONDS); }
+                    catch (InterruptedException ok) {}
+                    return "1"; }};
+            final ExecutorService p =
+                new ThreadPoolExecutor(2, 2,
+                                       LONG_DELAY_MS, MILLISECONDS,
+                                       new ArrayBlockingQueue<Runnable>(10));
+            try (PoolCleaner cleaner = cleaner(p, done)) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(waiter);
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    p.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                assertTrue(futures.get(1).isCancelled());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals("2", futures.get(2).get());
+                    break;
+                } catch (CancellationException retryWithLongerTimeout) {
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                }
+            }
         }
     }
 
@@ -1923,7 +1926,7 @@
                                    LONG_DELAY_MS, MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>(),
                                    new FailingThreadFactory());
-        try {
+        try (PoolCleaner cleaner = cleaner(e)) {
             final int TASKS = 100;
             final CountDownLatch done = new CountDownLatch(TASKS);
             for (int k = 0; k < TASKS; ++k)
@@ -1932,8 +1935,6 @@
                         done.countDown();
                     }});
             assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
-        } finally {
-            joinPool(e);
         }
     }
 
@@ -1945,21 +1946,22 @@
             new ThreadPoolExecutor(2, 2,
                                    1000, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        assertFalse(p.allowsCoreThreadTimeOut());
-        joinPool(p);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.allowsCoreThreadTimeOut());
+        }
     }
 
     /**
      * allowCoreThreadTimeOut(true) causes idle threads to time out
      */
     public void testAllowCoreThreadTimeOut_true() throws Exception {
-        long coreThreadTimeOut = SHORT_DELAY_MS;
+        long keepAliveTime = timeoutMillis();
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(2, 10,
-                                   coreThreadTimeOut, MILLISECONDS,
+                                   keepAliveTime, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             p.allowCoreThreadTimeOut(true);
             p.execute(new CheckedRunnable() {
                 public void realRun() {
@@ -1967,15 +1969,13 @@
                     assertEquals(1, p.getPoolSize());
                 }});
             await(threadStarted);
-            delay(coreThreadTimeOut);
+            delay(keepAliveTime);
             long startTime = System.nanoTime();
             while (p.getPoolSize() > 0
                    && millisElapsedSince(startTime) < LONG_DELAY_MS)
                 Thread.yield();
             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
             assertEquals(0, p.getPoolSize());
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -1983,23 +1983,21 @@
      * allowCoreThreadTimeOut(false) causes idle threads not to time out
      */
     public void testAllowCoreThreadTimeOut_false() throws Exception {
-        long coreThreadTimeOut = SHORT_DELAY_MS;
+        long keepAliveTime = timeoutMillis();
         final ThreadPoolExecutor p =
             new ThreadPoolExecutor(2, 10,
-                                   coreThreadTimeOut, MILLISECONDS,
+                                   keepAliveTime, MILLISECONDS,
                                    new ArrayBlockingQueue<Runnable>(10));
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
             p.allowCoreThreadTimeOut(false);
             p.execute(new CheckedRunnable() {
                 public void realRun() throws InterruptedException {
                     threadStarted.countDown();
                     assertTrue(p.getPoolSize() >= 1);
                 }});
-            delay(2 * coreThreadTimeOut);
+            delay(2 * keepAliveTime);
             assertTrue(p.getPoolSize() >= 1);
-        } finally {
-            joinPool(p);
         }
     }
 
@@ -2015,9 +2013,10 @@
                 done.countDown();
             }};
         final ThreadPoolExecutor p =
-            new ThreadPoolExecutor(1, 30, 60, TimeUnit.SECONDS,
+            new ThreadPoolExecutor(1, 30,
+                                   60, SECONDS,
                                    new ArrayBlockingQueue(30));
-        try {
+        try (PoolCleaner cleaner = cleaner(p)) {
             for (int i = 0; i < nTasks; ++i) {
                 for (;;) {
                     try {
@@ -2029,8 +2028,43 @@
             }
             // enough time to run all tasks
             assertTrue(done.await(nTasks * SHORT_DELAY_MS, MILLISECONDS));
-        } finally {
-            joinPool(p);
+        }
+    }
+
+    /**
+     * get(cancelled task) throws CancellationException
+     */
+    public void testGet_cancelled() throws Exception {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ExecutorService e =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new LinkedBlockingQueue<Runnable>());
+        try (PoolCleaner cleaner = cleaner(e, done)) {
+            final CountDownLatch blockerStarted = new CountDownLatch(1);
+            final List<Future<?>> futures = new ArrayList<>();
+            for (int i = 0; i < 2; i++) {
+                Runnable r = new CheckedRunnable() { public void realRun()
+                                                         throws Throwable {
+                    blockerStarted.countDown();
+                    assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
+                }};
+                futures.add(e.submit(r));
+            }
+            await(blockerStarted);
+            for (Future<?> future : futures) future.cancel(false);
+            for (Future<?> future : futures) {
+                try {
+                    future.get();
+                    shouldThrow();
+                } catch (CancellationException success) {}
+                try {
+                    future.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {}
+                assertTrue(future.isCancelled());
+                assertTrue(future.isDone());
+            }
         }
     }
 
diff --git a/jsr166-tests/src/test/java/jsr166/ThreadTest.java b/jsr166-tests/src/test/java/jsr166/ThreadTest.java
index 27f22ca..e69b422 100644
--- a/jsr166-tests/src/test/java/jsr166/ThreadTest.java
+++ b/jsr166-tests/src/test/java/jsr166/ThreadTest.java
@@ -19,7 +19,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(ThreadTest.class);
     // }
 
     static class MyHandler implements Thread.UncaughtExceptionHandler {
@@ -57,8 +57,7 @@
         // default uncaught exception handler installed by the framework.
         //
         // assertEquals(null, Thread.getDefaultUncaughtExceptionHandler());
-
-        // failure due to securityException is OK.
+        // failure due to SecurityException is OK.
         // Would be nice to explicitly test both ways, but cannot yet.
         Thread.UncaughtExceptionHandler defaultHandler
             = Thread.getDefaultUncaughtExceptionHandler();
diff --git a/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java b/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java
index 2c9529b..b21fa7d 100644
--- a/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java
+++ b/jsr166-tests/src/test/java/jsr166/TimeUnitTest.java
@@ -30,7 +30,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(TimeUnitTest.class);
     // }
 
     // (loops to 88888 check increments at all time divisions.)
@@ -433,8 +433,8 @@
      * a deserialized serialized unit is the same instance
      */
     public void testSerialization() throws Exception {
-        TimeUnit x = MILLISECONDS;
-        assertSame(x, serialClone(x));
+        for (TimeUnit x : TimeUnit.values())
+            assertSame(x, serialClone(x));
     }
 
 }
diff --git a/jsr166-tests/src/test/java/jsr166/TreeMapTest.java b/jsr166-tests/src/test/java/jsr166/TreeMapTest.java
index afc73de..e445609 100644
--- a/jsr166-tests/src/test/java/jsr166/TreeMapTest.java
+++ b/jsr166-tests/src/test/java/jsr166/TreeMapTest.java
@@ -29,7 +29,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(TreeMapTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/TreeSetTest.java b/jsr166-tests/src/test/java/jsr166/TreeSetTest.java
index a935637..c3093f6 100644
--- a/jsr166-tests/src/test/java/jsr166/TreeSetTest.java
+++ b/jsr166-tests/src/test/java/jsr166/TreeSetTest.java
@@ -29,7 +29,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(TreeSetTest.class);
     // }
 
     static class MyReverseComparator implements Comparator {
@@ -50,7 +50,7 @@
     private TreeSet<Integer> populatedSet(int n) {
         TreeSet<Integer> q = new TreeSet<Integer>();
         assertTrue(q.isEmpty());
-        for (int i = n-1; i >= 0; i -= 2)
+        for (int i = n - 1; i >= 0; i -= 2)
             assertTrue(q.add(new Integer(i)));
         for (int i = (n & 1); i < n; i += 2)
             assertTrue(q.add(new Integer(i)));
@@ -96,8 +96,7 @@
      */
     public void testConstructor4() {
         try {
-            Integer[] ints = new Integer[SIZE];
-            new TreeSet(Arrays.asList(ints));
+            new TreeSet(Arrays.asList(new Integer[SIZE]));
             shouldThrow();
         } catch (NullPointerException success) {}
     }
@@ -106,10 +105,10 @@
      * Initializing from Collection with some null elements throws NPE
      */
     public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
         try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE-1; ++i)
-                ints[i] = new Integer(i);
             new TreeSet(Arrays.asList(ints));
             shouldThrow();
         } catch (NullPointerException success) {}
@@ -138,7 +137,7 @@
         for (int i = 0; i < SIZE; ++i)
             ints[i] = new Integer(i);
         q.addAll(Arrays.asList(ints));
-        for (int i = SIZE-1; i >= 0; --i)
+        for (int i = SIZE - 1; i >= 0; --i)
             assertEquals(ints[i], q.pollFirst());
     }
 
@@ -162,7 +161,7 @@
     public void testSize() {
         TreeSet q = populatedSet(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.pollFirst();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -242,7 +241,7 @@
     public void testAddAll3() {
         TreeSet q = new TreeSet();
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
+        for (int i = 0; i < SIZE - 1; ++i)
             ints[i] = new Integer(i);
         try {
             q.addAll(Arrays.asList(ints));
@@ -257,7 +256,7 @@
         Integer[] empty = new Integer[0];
         Integer[] ints = new Integer[SIZE];
         for (int i = 0; i < SIZE; ++i)
-            ints[i] = new Integer(SIZE-1-i);
+            ints[i] = new Integer(SIZE - 1 - i);
         TreeSet q = new TreeSet();
         assertFalse(q.addAll(Arrays.asList(empty)));
         assertTrue(q.addAll(Arrays.asList(ints)));
@@ -281,7 +280,7 @@
      */
     public void testPollLast() {
         TreeSet q = populatedSet(SIZE);
-        for (int i = SIZE-1; i >= 0; --i) {
+        for (int i = SIZE - 1; i >= 0; --i) {
             assertEquals(i, q.pollLast());
         }
         assertNull(q.pollFirst());
@@ -296,14 +295,14 @@
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertTrue(q.contains(i-1));
+            assertTrue(q.contains(i - 1));
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertFalse(q.remove(i+1));
-            assertFalse(q.contains(i+1));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
         }
         assertTrue(q.isEmpty());
     }
@@ -362,7 +361,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.pollFirst();
         }
     }
@@ -375,7 +374,7 @@
             TreeSet q = populatedSet(SIZE);
             TreeSet p = populatedSet(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.pollFirst());
                 assertFalse(q.contains(x));
@@ -909,18 +908,18 @@
                 else if (element > max)
                     return -1;
                 int result = bs.nextSetBit(element);
-                return result > max ? -1 : result;
+                return (result > max) ? -1 : result;
             }
             int higherAscending(int element) {
                 return ceilingAscending(element + 1);
             }
             private int firstAscending() {
                 int result = ceilingAscending(min);
-                return result > max ? -1 : result;
+                return (result > max) ? -1 : result;
             }
             private int lastAscending() {
                 int result = floorAscending(max);
-                return result < min ? -1 : result;
+                return (result < min) ? -1 : result;
             }
         }
         ReferenceSet rs = new ReferenceSet();
@@ -981,7 +980,7 @@
     }
 
     static boolean eq(Integer i, int j) {
-        return i == null ? j == -1 : i == j;
+        return (i == null) ? j == -1 : i == j;
     }
 
 }
diff --git a/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java b/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java
index 18a9e37..09b809e 100644
--- a/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java
+++ b/jsr166-tests/src/test/java/jsr166/TreeSubMapTest.java
@@ -27,7 +27,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(TreeSubMapTest.class);
     // }
 
     /**
diff --git a/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java b/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java
index 5398c4e..31403be 100644
--- a/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java
+++ b/jsr166-tests/src/test/java/jsr166/TreeSubSetTest.java
@@ -25,7 +25,7 @@
     //     main(suite(), args);
     // }
     // public static Test suite() {
-    //     return new TestSuite(...);
+    //     return new TestSuite(TreeSubSetTest.class);
     // }
 
     static class MyReverseComparator implements Comparator {
@@ -42,7 +42,7 @@
         TreeSet<Integer> q = new TreeSet<Integer>();
         assertTrue(q.isEmpty());
 
-        for (int i = n-1; i >= 0; i -= 2)
+        for (int i = n - 1; i >= 0; i -= 2)
             assertTrue(q.add(new Integer(i)));
         for (int i = (n & 1); i < n; i += 2)
             assertTrue(q.add(new Integer(i)));
@@ -124,7 +124,7 @@
     public void testSize() {
         NavigableSet q = populatedSet(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.pollFirst();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -203,8 +203,8 @@
     public void testAddAll3() {
         NavigableSet q = set0();
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
-            ints[i] = new Integer(i+SIZE);
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i + SIZE);
         try {
             q.addAll(Arrays.asList(ints));
             shouldThrow();
@@ -218,7 +218,7 @@
         Integer[] empty = new Integer[0];
         Integer[] ints = new Integer[SIZE];
         for (int i = 0; i < SIZE; ++i)
-            ints[i] = new Integer(SIZE-1- i);
+            ints[i] = new Integer(SIZE - 1 - i);
         NavigableSet q = set0();
         assertFalse(q.addAll(Arrays.asList(empty)));
         assertTrue(q.addAll(Arrays.asList(ints)));
@@ -246,14 +246,14 @@
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertTrue(q.contains(i-1));
+            assertTrue(q.contains(i - 1));
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.contains(i));
             assertTrue(q.remove(i));
             assertFalse(q.contains(i));
-            assertFalse(q.remove(i+1));
-            assertFalse(q.contains(i+1));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
         }
         assertTrue(q.isEmpty());
     }
@@ -312,7 +312,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.pollFirst();
         }
     }
@@ -325,7 +325,7 @@
             NavigableSet q = populatedSet(SIZE);
             NavigableSet p = populatedSet(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.pollFirst());
                 assertFalse(q.contains(x));
@@ -620,7 +620,7 @@
     public void testDescendingSize() {
         NavigableSet q = populatedSet(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             q.pollFirst();
         }
         for (int i = 0; i < SIZE; ++i) {
@@ -688,8 +688,8 @@
     public void testDescendingAddAll3() {
         NavigableSet q = dset0();
         Integer[] ints = new Integer[SIZE];
-        for (int i = 0; i < SIZE-1; ++i)
-            ints[i] = new Integer(i+SIZE);
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i + SIZE);
         try {
             q.addAll(Arrays.asList(ints));
             shouldThrow();
@@ -703,7 +703,7 @@
         Integer[] empty = new Integer[0];
         Integer[] ints = new Integer[SIZE];
         for (int i = 0; i < SIZE; ++i)
-            ints[i] = new Integer(SIZE-1- i);
+            ints[i] = new Integer(SIZE - 1 - i);
         NavigableSet q = dset0();
         assertFalse(q.addAll(Arrays.asList(empty)));
         assertTrue(q.addAll(Arrays.asList(ints)));
@@ -732,7 +732,7 @@
         }
         for (int i = 0; i < SIZE; i += 2) {
             assertTrue(q.remove(new Integer(i)));
-            assertFalse(q.remove(new Integer(i+1)));
+            assertFalse(q.remove(new Integer(i + 1)));
         }
         assertTrue(q.isEmpty());
     }
@@ -791,7 +791,7 @@
                 assertTrue(changed);
 
             assertTrue(q.containsAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             p.pollFirst();
         }
     }
@@ -804,7 +804,7 @@
             NavigableSet q = populatedSet(SIZE);
             NavigableSet p = populatedSet(i);
             assertTrue(q.removeAll(p));
-            assertEquals(SIZE-i, q.size());
+            assertEquals(SIZE - i, q.size());
             for (int j = 0; j < i; ++j) {
                 Integer x = (Integer)(p.pollFirst());
                 assertFalse(q.contains(x));
diff --git a/luni/src/main/java/java/util/concurrent/AbstractExecutorService.java b/luni/src/main/java/java/util/concurrent/AbstractExecutorService.java
index f444b29..213baf2 100644
--- a/luni/src/main/java/java/util/concurrent/AbstractExecutorService.java
+++ b/luni/src/main/java/java/util/concurrent/AbstractExecutorService.java
@@ -6,7 +6,12 @@
 
 package java.util.concurrent;
 
-import java.util.*;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
 
 /**
  * Provides default implementations of {@link ExecutorService}
@@ -23,7 +28,7 @@
  * <p><b>Extension example</b>. Here is a sketch of a class
  * that customizes {@link ThreadPoolExecutor} to use
  * a {@code CustomTask} class instead of the default {@code FutureTask}:
- *  <pre> {@code
+ * <pre> {@code
  * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
  *
  *   static class CustomTask<V> implements RunnableFuture<V> {...}
@@ -118,7 +123,7 @@
         int ntasks = tasks.size();
         if (ntasks == 0)
             throw new IllegalArgumentException();
-        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
+        ArrayList<Future<T>> futures = new ArrayList<>(ntasks);
         ExecutorCompletionService<T> ecs =
             new ExecutorCompletionService<T>(this);
 
@@ -151,7 +156,7 @@
                     else if (active == 0)
                         break;
                     else if (timed) {
-                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
+                        f = ecs.poll(nanos, NANOSECONDS);
                         if (f == null)
                             throw new TimeoutException();
                         nanos = deadline - System.nanoTime();
@@ -176,8 +181,7 @@
             throw ee;
 
         } finally {
-            for (int i = 0, size = futures.size(); i < size; i++)
-                futures.get(i).cancel(true);
+            cancelAll(futures);
         }
     }
 
@@ -201,8 +205,7 @@
         throws InterruptedException {
         if (tasks == null)
             throw new NullPointerException();
-        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
-        boolean done = false;
+        ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
         try {
             for (Callable<T> t : tasks) {
                 RunnableFuture<T> f = newTaskFor(t);
@@ -212,19 +215,15 @@
             for (int i = 0, size = futures.size(); i < size; i++) {
                 Future<T> f = futures.get(i);
                 if (!f.isDone()) {
-                    try {
-                        f.get();
-                    } catch (CancellationException ignore) {
-                    } catch (ExecutionException ignore) {
-                    }
+                    try { f.get(); }
+                    catch (CancellationException ignore) {}
+                    catch (ExecutionException ignore) {}
                 }
             }
-            done = true;
             return futures;
-        } finally {
-            if (!done)
-                for (int i = 0, size = futures.size(); i < size; i++)
-                    futures.get(i).cancel(true);
+        } catch (Throwable t) {
+            cancelAll(futures);
+            throw t;
         }
     }
 
@@ -233,47 +232,52 @@
         throws InterruptedException {
         if (tasks == null)
             throw new NullPointerException();
-        long nanos = unit.toNanos(timeout);
-        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
-        boolean done = false;
-        try {
+        final long nanos = unit.toNanos(timeout);
+        final long deadline = System.nanoTime() + nanos;
+        ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
+        int j = 0;
+        timedOut: try {
             for (Callable<T> t : tasks)
                 futures.add(newTaskFor(t));
 
-            final long deadline = System.nanoTime() + nanos;
             final int size = futures.size();
 
             // Interleave time checks and calls to execute in case
             // executor doesn't have any/much parallelism.
             for (int i = 0; i < size; i++) {
+                if (((i == 0) ? nanos : deadline - System.nanoTime()) <= 0L)
+                    break timedOut;
                 execute((Runnable)futures.get(i));
-                nanos = deadline - System.nanoTime();
-                if (nanos <= 0L)
-                    return futures;
             }
 
-            for (int i = 0; i < size; i++) {
-                Future<T> f = futures.get(i);
+            for (; j < size; j++) {
+                Future<T> f = futures.get(j);
                 if (!f.isDone()) {
-                    if (nanos <= 0L)
-                        return futures;
-                    try {
-                        f.get(nanos, TimeUnit.NANOSECONDS);
-                    } catch (CancellationException ignore) {
-                    } catch (ExecutionException ignore) {
-                    } catch (TimeoutException toe) {
-                        return futures;
+                    try { f.get(deadline - System.nanoTime(), NANOSECONDS); }
+                    catch (CancellationException ignore) {}
+                    catch (ExecutionException ignore) {}
+                    catch (TimeoutException timedOut) {
+                        break timedOut;
                     }
-                    nanos = deadline - System.nanoTime();
                 }
             }
-            done = true;
             return futures;
-        } finally {
-            if (!done)
-                for (int i = 0, size = futures.size(); i < size; i++)
-                    futures.get(i).cancel(true);
+        } catch (Throwable t) {
+            cancelAll(futures);
+            throw t;
         }
+        // Timed out before all the tasks could be completed; cancel remaining
+        cancelAll(futures, j);
+        return futures;
     }
 
+    private static <T> void cancelAll(ArrayList<Future<T>> futures) {
+        cancelAll(futures, 0);
+    }
+
+    /** Cancels all futures with index at least j. */
+    private static <T> void cancelAll(ArrayList<Future<T>> futures, int j) {
+        for (int size = futures.size(); j < size; j++)
+            futures.get(j).cancel(true);
+    }
 }
diff --git a/luni/src/main/java/java/util/concurrent/ArrayBlockingQueue.java b/luni/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
index 9dca1b3..3183c01 100644
--- a/luni/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
+++ b/luni/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
@@ -7,11 +7,14 @@
 package java.util.concurrent;
 
 import java.lang.ref.WeakReference;
-import java.util.Arrays;
 import java.util.AbstractQueue;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Spliterator;
+import java.util.Spliterators;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -92,7 +95,7 @@
      * are known not to be any.  Allows queue operations to update
      * iterator state.
      */
-    transient Itrs itrs = null;
+    transient Itrs itrs;
 
     // Internal helper methods
 
@@ -237,10 +240,8 @@
         try {
             int i = 0;
             try {
-                for (E e : c) {
-                    if (e == null) throw new NullPointerException();
-                    items[i++] = e;
-                }
+                for (E e : c)
+                    items[i++] = Objects.requireNonNull(e);
             } catch (ArrayIndexOutOfBoundsException ex) {
                 throw new IllegalArgumentException();
             }
@@ -276,7 +277,7 @@
      * @throws NullPointerException if the specified element is null
      */
     public boolean offer(E e) {
-        if (e == null) throw new NullPointerException();
+        Objects.requireNonNull(e);
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
@@ -299,7 +300,7 @@
      * @throws NullPointerException {@inheritDoc}
      */
     public void put(E e) throws InterruptedException {
-        if (e == null) throw new NullPointerException();
+        Objects.requireNonNull(e);
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
         try {
@@ -322,13 +323,13 @@
     public boolean offer(E e, long timeout, TimeUnit unit)
         throws InterruptedException {
 
-        if (e == null) throw new NullPointerException();
+        Objects.requireNonNull(e);
         long nanos = unit.toNanos(timeout);
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
         try {
             while (count == items.length) {
-                if (nanos <= 0)
+                if (nanos <= 0L)
                     return false;
                 nanos = notFull.awaitNanos(nanos);
             }
@@ -367,7 +368,7 @@
         lock.lockInterruptibly();
         try {
             while (count == 0) {
-                if (nanos <= 0)
+                if (nanos <= 0L)
                     return null;
                 nanos = notEmpty.awaitNanos(nanos);
             }
@@ -584,27 +585,7 @@
     }
 
     public String toString() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            int k = count;
-            if (k == 0)
-                return "[]";
-
-            final Object[] items = this.items;
-            StringBuilder sb = new StringBuilder();
-            sb.append('[');
-            for (int i = takeIndex; ; ) {
-                Object e = items[i];
-                sb.append(e == this ? "(this Collection)" : e);
-                if (--k == 0)
-                    return sb.append(']').toString();
-                sb.append(',').append(' ');
-                if (++i == items.length) i = 0;
-            }
-        } finally {
-            lock.unlock();
-        }
+        return Helpers.collectionToString(this);
     }
 
     /**
@@ -612,12 +593,12 @@
      * The queue will be empty after this call returns.
      */
     public void clear() {
-        final Object[] items = this.items;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
             int k = count;
             if (k > 0) {
+                final Object[] items = this.items;
                 final int putIndex = this.putIndex;
                 int i = takeIndex;
                 do {
@@ -653,7 +634,7 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c, int maxElements) {
-        if (c == null) throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         if (maxElements <= 0)
@@ -1333,4 +1314,27 @@
 //         }
     }
 
+    /**
+     * Returns a {@link Spliterator} over the elements in this queue.
+     *
+     * <p>The returned spliterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+     *
+     * @implNote
+     * The {@code Spliterator} implements {@code trySplit} to permit limited
+     * parallelism.
+     *
+     * @return a {@code Spliterator} over the elements in this queue
+     * @since 1.8
+     */
+    public Spliterator<E> spliterator() {
+        return Spliterators.spliterator
+            (this, (Spliterator.ORDERED |
+                    Spliterator.NONNULL |
+                    Spliterator.CONCURRENT));
+    }
+
 }
diff --git a/luni/src/main/java/java/util/concurrent/BlockingDeque.java b/luni/src/main/java/java/util/concurrent/BlockingDeque.java
index b1437cc..b52f719 100644
--- a/luni/src/main/java/java/util/concurrent/BlockingDeque.java
+++ b/luni/src/main/java/java/util/concurrent/BlockingDeque.java
@@ -6,7 +6,13 @@
 
 package java.util.concurrent;
 
-import java.util.*;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+// BEGIN android-note
+// fixed framework docs link to "Collection#optional"
+// END android-note
 
 /**
  * A {@link Deque} that additionally supports blocking operations that wait
@@ -22,7 +28,6 @@
  * and the fourth blocks for only a given maximum time limit before giving
  * up.  These methods are summarized in the following table:
  *
- * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
  * <caption>Summary of BlockingDeque methods</caption>
  *  <tr>
@@ -98,7 +103,6 @@
  * {@code BlockingQueue} interface are precisely equivalent to
  * {@code BlockingDeque} methods as indicated in the following table:
  *
- * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
  * <caption>Comparison of BlockingQueue and BlockingDeque methods</caption>
  *  <tr>
@@ -169,7 +173,7 @@
  *
  * @since 1.6
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this deque
  */
 public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> {
     /*
@@ -375,9 +379,9 @@
      * @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>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean removeFirstOccurrence(Object o);
 
@@ -393,9 +397,9 @@
      * @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>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean removeLastOccurrence(Object o);
 
@@ -570,9 +574,9 @@
      * @return {@code true} if this deque changed as a result of the call
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this deque
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean remove(Object o);
 
@@ -585,18 +589,18 @@
      * @return {@code true} if this deque contains the specified element
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this deque
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
-    public boolean contains(Object o);
+    boolean contains(Object o);
 
     /**
      * Returns the number of elements in this deque.
      *
      * @return the number of elements in this deque
      */
-    public int size();
+    int size();
 
     /**
      * Returns an iterator over the elements in this deque in proper sequence.
diff --git a/luni/src/main/java/java/util/concurrent/BlockingQueue.java b/luni/src/main/java/java/util/concurrent/BlockingQueue.java
index 33d83b7..2a56179 100644
--- a/luni/src/main/java/java/util/concurrent/BlockingQueue.java
+++ b/luni/src/main/java/java/util/concurrent/BlockingQueue.java
@@ -10,7 +10,8 @@
 import java.util.Queue;
 
 // BEGIN android-note
-// removed link to collections framework docs
+// removed link to collections framework docs from header
+// fixed framework docs link to "Collection#optional"
 // END android-note
 
 /**
@@ -28,7 +29,6 @@
  * and the fourth blocks for only a given maximum time limit before giving
  * up.  These methods are summarized in the following table:
  *
- * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
  * <caption>Summary of BlockingQueue methods</caption>
  *  <tr>
@@ -103,7 +103,7 @@
  * Usage example, based on a typical producer-consumer scenario.
  * Note that a {@code BlockingQueue} can safely be used with multiple
  * producers and multiple consumers.
- *  <pre> {@code
+ * <pre> {@code
  * class Producer implements Runnable {
  *   private final BlockingQueue queue;
  *   Producer(BlockingQueue q) { queue = q; }
@@ -147,7 +147,7 @@
  *
  * @since 1.5
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public interface BlockingQueue<E> extends Queue<E> {
     /**
@@ -275,9 +275,9 @@
      * @return {@code true} if this queue changed as a result of the call
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this queue
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean remove(Object o);
 
@@ -290,11 +290,11 @@
      * @return {@code true} if this queue contains the specified element
      * @throws ClassCastException if the class of the specified element
      *         is incompatible with this queue
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
-    public boolean contains(Object o);
+    boolean contains(Object o);
 
     /**
      * Removes all available elements from this queue and adds them
diff --git a/luni/src/main/java/java/util/concurrent/Callable.java b/luni/src/main/java/java/util/concurrent/Callable.java
index a3b3883..a22ec50 100644
--- a/luni/src/main/java/java/util/concurrent/Callable.java
+++ b/luni/src/main/java/java/util/concurrent/Callable.java
@@ -25,6 +25,7 @@
  * @author Doug Lea
  * @param <V> the result type of method {@code call}
  */
+@FunctionalInterface
 public interface Callable<V> {
     /**
      * Computes a result, or throws an exception if unable to do so.
diff --git a/luni/src/main/java/java/util/concurrent/CompletableFuture.java b/luni/src/main/java/java/util/concurrent/CompletableFuture.java
new file mode 100644
index 0000000..8383a68
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/CompletableFuture.java
@@ -0,0 +1,2770 @@
+/*
+ * 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.concurrent.locks.LockSupport;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+/**
+ * A {@link Future} that may be explicitly completed (setting its
+ * 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},
+ * {@link #completeExceptionally completeExceptionally}, or
+ * {@link #cancel cancel}
+ * a CompletableFuture, only one of them succeeds.
+ *
+ * <p>In addition to these and related methods for directly
+ * manipulating status and results, CompletableFuture implements
+ * interface {@link CompletionStage} with the following policies: <ul>
+ *
+ * <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>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 created to run each task).
+ * To simplify monitoring, debugging,
+ * and tracking, all generated asynchronous tasks are instances of the
+ * marker interface {@link AsynchronousCompletionTask}.  Operations
+ * with time-delays can use adapter methods defined in this class, for
+ * example: {@code supplyAsync(supplier, delayedExecutor(timeout,
+ * timeUnit))}.  To support methods with delays and timeouts, this
+ * class maintains at most one daemon thread for triggering and
+ * cancelling actions, not for running them.
+ *
+ * <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.
+ *
+ * </ul>
+ *
+ * <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())}. Method
+ * {@link #isCompletedExceptionally} can be used to determine if a
+ * CompletableFuture completed in any exceptional fashion.
+ *
+ * <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.  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.
+ * </ul>
+ *
+ * <p>Arguments used to pass a completion result (that is, for
+ * parameters of type {@code T}) for methods accepting them may be
+ * null, but passing a null value for any other parameter will result
+ * in a {@link NullPointerException} being thrown.
+ *
+ * @author Doug Lea
+ * @since 1.8
+ * @param <T> The result type returned by this future's {@code join}
+ * and {@code get} methods
+ */
+public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
+
+    /*
+     * Overview:
+     *
+     * A CompletableFuture may have dependent completion actions,
+     * collected in a linked stack. It atomically completes by CASing
+     * a result field, and then pops off and runs those actions. This
+     * applies across normal vs exceptional outcomes, sync vs async
+     * actions, binary triggers, and various forms of completions.
+     *
+     * Non-nullness of field result (set via CAS) indicates done.  An
+     * AltResult is used to box null as a result, as well as to hold
+     * exceptions.  Using a single field makes completion simple to
+     * detect and trigger.  Encoding and decoding is straightforward
+     * but adds to the sprawl of trapping and associating exceptions
+     * with targets.  Minor simplifications rely on (static) NIL (to
+     * box null results) being the only AltResult with a null
+     * exception field, so we don't usually need explicit comparisons.
+     * Even though some of the generics casts are unchecked (see
+     * SuppressWarnings annotations), they are placed to be
+     * appropriate even if checked.
+     *
+     * Dependent actions are represented by Completion objects linked
+     * as Treiber stacks headed by field "stack". There are Completion
+     * classes for each kind of action, grouped into single-input
+     * (UniCompletion), two-input (BiCompletion), projected
+     * (BiCompletions using either (not both) of two inputs), shared
+     * (CoCompletion, used by the second of two sources), zero-input
+     * source actions, and Signallers that unblock waiters. Class
+     * Completion extends ForkJoinTask to enable async execution
+     * (adding no space overhead because we exploit its "tag" methods
+     * to maintain claims). It is also declared as Runnable to allow
+     * usage with arbitrary executors.
+     *
+     * Support for each kind of CompletionStage relies on a separate
+     * class, along with two CompletableFuture methods:
+     *
+     * * A Completion class with name X corresponding to function,
+     *   prefaced with "Uni", "Bi", or "Or". Each class contains
+     *   fields for source(s), actions, and dependent. They are
+     *   boringly similar, differing from others only with respect to
+     *   underlying functional forms. We do this so that users don't
+     *   encounter layers of adapters in common usages.
+     *
+     * * Boolean CompletableFuture method x(...) (for example
+     *   uniApply) takes all of the arguments needed to check that an
+     *   action is triggerable, and then either runs the action or
+     *   arranges its async execution by executing its Completion
+     *   argument, if present. The method returns true if known to be
+     *   complete.
+     *
+     * * Completion method tryFire(int mode) invokes the associated x
+     *   method with its held arguments, and on success cleans up.
+     *   The mode argument allows tryFire to be called twice (SYNC,
+     *   then ASYNC); the first to screen and trap exceptions while
+     *   arranging to execute, and the second when called from a
+     *   task. (A few classes are not used async so take slightly
+     *   different forms.)  The claim() callback suppresses function
+     *   invocation if already claimed by another thread.
+     *
+     * * CompletableFuture method xStage(...) is called from a public
+     *   stage method of CompletableFuture x. It screens user
+     *   arguments and invokes and/or creates the stage object.  If
+     *   not async and x is already complete, the action is run
+     *   immediately.  Otherwise a Completion c is created, pushed to
+     *   x's stack (unless done), and started or triggered via
+     *   c.tryFire.  This also covers races possible if x completes
+     *   while pushing.  Classes with two inputs (for example BiApply)
+     *   deal with races across both while pushing actions.  The
+     *   second completion is a CoCompletion pointing to the first,
+     *   shared so that at most one performs the action.  The
+     *   multiple-arity methods allOf and anyOf do this pairwise to
+     *   form trees of completions.
+     *
+     * Note that the generic type parameters of methods vary according
+     * to whether "this" is a source, dependent, or completion.
+     *
+     * Method postComplete is called upon completion unless the target
+     * is guaranteed not to be observable (i.e., not yet returned or
+     * linked). Multiple threads can call postComplete, which
+     * atomically pops each dependent action, and tries to trigger it
+     * via method tryFire, in NESTED mode.  Triggering can propagate
+     * recursively, so NESTED mode returns its completed dependent (if
+     * one exists) for further processing by its caller (see method
+     * postFire).
+     *
+     * Blocking methods get() and join() rely on Signaller Completions
+     * that wake up waiting threads.  The mechanics are similar to
+     * Treiber stack wait-nodes used in FutureTask, Phaser, and
+     * SynchronousQueue. See their internal documentation for
+     * algorithmic details.
+     *
+     * Without precautions, CompletableFutures would be prone to
+     * garbage accumulation as chains of Completions build up, each
+     * pointing back to its sources. So we null out fields as soon as
+     * possible.  The screening checks needed anyway harmlessly ignore
+     * null arguments that may have been obtained during races with
+     * threads nulling out fields.  We also try to unlink fired
+     * Completions from stacks that might never be popped (see method
+     * postFire).  Completion fields need not be declared as final or
+     * volatile because they are only visible to other threads upon
+     * safe publication.
+     */
+
+    volatile Object result;       // Either the result or boxed AltResult
+    volatile Completion stack;    // Top of Treiber stack of dependent actions
+
+    final boolean internalComplete(Object r) { // CAS from null to r
+        return U.compareAndSwapObject(this, RESULT, null, r);
+    }
+
+    final boolean casStack(Completion cmp, Completion val) {
+        return U.compareAndSwapObject(this, STACK, cmp, val);
+    }
+
+    /** Returns true if successfully pushed c onto stack. */
+    final boolean tryPushStack(Completion c) {
+        Completion h = stack;
+        lazySetNext(c, h);
+        return U.compareAndSwapObject(this, STACK, h, c);
+    }
+
+    /** Unconditionally pushes c onto stack, retrying if necessary. */
+    final void pushStack(Completion c) {
+        do {} while (!tryPushStack(c));
+    }
+
+    /* ------------- Encoding and decoding outcomes -------------- */
+
+    static final class AltResult { // See above
+        final Throwable ex;        // null only for NIL
+        AltResult(Throwable x) { this.ex = x; }
+    }
+
+    /** The encoding of the null value. */
+    static final AltResult NIL = new AltResult(null);
+
+    /** Completes with the null value, unless already completed. */
+    final boolean completeNull() {
+        return U.compareAndSwapObject(this, RESULT, null,
+                                      NIL);
+    }
+
+    /** Returns the encoding of the given non-exceptional value. */
+    final Object encodeValue(T t) {
+        return (t == null) ? NIL : t;
+    }
+
+    /** Completes with a non-exceptional result, unless already completed. */
+    final boolean completeValue(T t) {
+        return U.compareAndSwapObject(this, RESULT, null,
+                                      (t == null) ? NIL : t);
+    }
+
+    /**
+     * Returns the encoding of the given (non-null) exception as a
+     * wrapped CompletionException unless it is one already.
+     */
+    static AltResult encodeThrowable(Throwable x) {
+        return new AltResult((x instanceof CompletionException) ? x :
+                             new CompletionException(x));
+    }
+
+    /** Completes with an exceptional result, unless already completed. */
+    final boolean completeThrowable(Throwable x) {
+        return U.compareAndSwapObject(this, RESULT, null,
+                                      encodeThrowable(x));
+    }
+
+    /**
+     * Returns the encoding of the given (non-null) exception as a
+     * wrapped CompletionException unless it is one already.  May
+     * return the given Object r (which must have been the result of a
+     * source future) if it is equivalent, i.e. if this is a simple
+     * relay of an existing CompletionException.
+     */
+    static Object encodeThrowable(Throwable x, Object r) {
+        if (!(x instanceof CompletionException))
+            x = new CompletionException(x);
+        else if (r instanceof AltResult && x == ((AltResult)r).ex)
+            return r;
+        return new AltResult(x);
+    }
+
+    /**
+     * Completes with the given (non-null) exceptional result as a
+     * wrapped CompletionException unless it is one already, unless
+     * already completed.  May complete with the given Object r
+     * (which must have been the result of a source future) if it is
+     * equivalent, i.e. if this is a simple propagation of an
+     * existing CompletionException.
+     */
+    final boolean completeThrowable(Throwable x, Object r) {
+        return U.compareAndSwapObject(this, RESULT, null,
+                                      encodeThrowable(x, r));
+    }
+
+    /**
+     * Returns the encoding of the given arguments: if the exception
+     * is non-null, encodes as AltResult.  Otherwise uses the given
+     * value, boxed as NIL if null.
+     */
+    Object encodeOutcome(T t, Throwable x) {
+        return (x == null) ? (t == null) ? NIL : t : encodeThrowable(x);
+    }
+
+    /**
+     * Returns the encoding of a copied outcome; if exceptional,
+     * rewraps as a CompletionException, else returns argument.
+     */
+    static Object encodeRelay(Object r) {
+        Throwable x;
+        return (((r instanceof AltResult) &&
+                 (x = ((AltResult)r).ex) != null &&
+                 !(x instanceof CompletionException)) ?
+                new AltResult(new CompletionException(x)) : r);
+    }
+
+    /**
+     * Completes with r or a copy of r, unless already completed.
+     * If exceptional, r is first coerced to a CompletionException.
+     */
+    final boolean completeRelay(Object r) {
+        return U.compareAndSwapObject(this, RESULT, null,
+                                      encodeRelay(r));
+    }
+
+    /**
+     * Reports result using Future.get conventions.
+     */
+    private static <T> T reportGet(Object r)
+        throws InterruptedException, ExecutionException {
+        if (r == null) // by convention below, null means interrupted
+            throw new InterruptedException();
+        if (r instanceof AltResult) {
+            Throwable x, cause;
+            if ((x = ((AltResult)r).ex) == null)
+                return null;
+            if (x instanceof CancellationException)
+                throw (CancellationException)x;
+            if ((x instanceof CompletionException) &&
+                (cause = x.getCause()) != null)
+                x = cause;
+            throw new ExecutionException(x);
+        }
+        @SuppressWarnings("unchecked") T t = (T) r;
+        return t;
+    }
+
+    /**
+     * Decodes outcome to return result or throw unchecked exception.
+     */
+    private static <T> T reportJoin(Object r) {
+        if (r instanceof AltResult) {
+            Throwable x;
+            if ((x = ((AltResult)r).ex) == null)
+                return null;
+            if (x instanceof CancellationException)
+                throw (CancellationException)x;
+            if (x instanceof CompletionException)
+                throw (CompletionException)x;
+            throw new CompletionException(x);
+        }
+        @SuppressWarnings("unchecked") T t = (T) r;
+        return t;
+    }
+
+    /* ------------- Async task preliminaries -------------- */
+
+    /**
+     * A marker interface identifying asynchronous tasks produced by
+     * {@code async} methods. This may be useful for monitoring,
+     * debugging, and tracking asynchronous activities.
+     *
+     * @since 1.8
+     */
+    public static interface AsynchronousCompletionTask {
+    }
+
+    private static final boolean USE_COMMON_POOL =
+        (ForkJoinPool.getCommonPoolParallelism() > 1);
+
+    /**
+     * Default executor -- ForkJoinPool.commonPool() unless it cannot
+     * support parallelism.
+     */
+    private static final Executor ASYNC_POOL = USE_COMMON_POOL ?
+        ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
+
+    /** Fallback if ForkJoinPool.commonPool() cannot support parallelism */
+    static final class ThreadPerTaskExecutor implements Executor {
+        public void execute(Runnable r) { new Thread(r).start(); }
+    }
+
+    /**
+     * Null-checks user executor argument, and translates uses of
+     * commonPool to ASYNC_POOL in case parallelism disabled.
+     */
+    static Executor screenExecutor(Executor e) {
+        if (!USE_COMMON_POOL && e == ForkJoinPool.commonPool())
+            return ASYNC_POOL;
+        if (e == null) throw new NullPointerException();
+        return e;
+    }
+
+    // Modes for Completion.tryFire. Signedness matters.
+    static final int SYNC   =  0;
+    static final int ASYNC  =  1;
+    static final int NESTED = -1;
+
+    /**
+     * Spins before blocking in waitingGet
+     */
+    static final int SPINS = (Runtime.getRuntime().availableProcessors() > 1 ?
+                              1 << 8 : 0);
+
+    /* ------------- Base Completion classes and operations -------------- */
+
+    @SuppressWarnings("serial")
+    abstract static class Completion extends ForkJoinTask<Void>
+        implements Runnable, AsynchronousCompletionTask {
+        volatile Completion next;      // Treiber stack link
+
+        /**
+         * Performs completion action if triggered, returning a
+         * dependent that may need propagation, if one exists.
+         *
+         * @param mode SYNC, ASYNC, or NESTED
+         */
+        abstract CompletableFuture<?> tryFire(int mode);
+
+        /** Returns true if possibly still triggerable. Used by cleanStack. */
+        abstract boolean isLive();
+
+        public final void run()                { tryFire(ASYNC); }
+        public final boolean exec()            { tryFire(ASYNC); return false; }
+        public final Void getRawResult()       { return null; }
+        public final void setRawResult(Void v) {}
+    }
+
+    static void lazySetNext(Completion c, Completion next) {
+        U.putOrderedObject(c, NEXT, next);
+    }
+
+    /**
+     * Pops and tries to trigger all reachable dependents.  Call only
+     * when known to be done.
+     */
+    final void postComplete() {
+        /*
+         * On each step, variable f holds current dependents to pop
+         * and run.  It is extended along only one path at a time,
+         * pushing others to avoid unbounded recursion.
+         */
+        CompletableFuture<?> f = this; Completion h;
+        while ((h = f.stack) != null ||
+               (f != this && (h = (f = this).stack) != null)) {
+            CompletableFuture<?> d; Completion t;
+            if (f.casStack(h, t = h.next)) {
+                if (t != null) {
+                    if (f != this) {
+                        pushStack(h);
+                        continue;
+                    }
+                    h.next = null;    // detach
+                }
+                f = (d = h.tryFire(NESTED)) == null ? this : d;
+            }
+        }
+    }
+
+    /** Traverses stack and unlinks dead Completions. */
+    final void cleanStack() {
+        for (Completion p = null, q = stack; q != null;) {
+            Completion s = q.next;
+            if (q.isLive()) {
+                p = q;
+                q = s;
+            }
+            else if (p == null) {
+                casStack(q, s);
+                q = stack;
+            }
+            else {
+                p.next = s;
+                if (p.isLive())
+                    q = s;
+                else {
+                    p = null;  // restart
+                    q = stack;
+                }
+            }
+        }
+    }
+
+    /* ------------- One-input Completions -------------- */
+
+    /** A Completion with a source, dependent, and executor. */
+    @SuppressWarnings("serial")
+    abstract static class UniCompletion<T,V> extends Completion {
+        Executor executor;                 // executor to use (null if none)
+        CompletableFuture<V> dep;          // the dependent to complete
+        CompletableFuture<T> src;          // source for action
+
+        UniCompletion(Executor executor, CompletableFuture<V> dep,
+                      CompletableFuture<T> src) {
+            this.executor = executor; this.dep = dep; this.src = src;
+        }
+
+        /**
+         * Returns true if action can be run. Call only when known to
+         * be triggerable. Uses FJ tag bit to ensure that only one
+         * thread claims ownership.  If async, starts as task -- a
+         * later call to tryFire will run action.
+         */
+        final boolean claim() {
+            Executor e = executor;
+            if (compareAndSetForkJoinTaskTag((short)0, (short)1)) {
+                if (e == null)
+                    return true;
+                executor = null; // disable
+                e.execute(this);
+            }
+            return false;
+        }
+
+        final boolean isLive() { return dep != null; }
+    }
+
+    /** Pushes the given completion (if it exists) unless done. */
+    final void push(UniCompletion<?,?> c) {
+        if (c != null) {
+            while (result == null && !tryPushStack(c))
+                lazySetNext(c, null); // clear on failure
+        }
+    }
+
+    /**
+     * Post-processing by dependent after successful UniCompletion
+     * tryFire.  Tries to clean stack of source a, and then either runs
+     * postComplete or returns this to caller, depending on mode.
+     */
+    final CompletableFuture<T> postFire(CompletableFuture<?> a, int mode) {
+        if (a != null && a.stack != null) {
+            if (mode < 0 || a.result == null)
+                a.cleanStack();
+            else
+                a.postComplete();
+        }
+        if (result != null && stack != null) {
+            if (mode < 0)
+                return this;
+            else
+                postComplete();
+        }
+        return null;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniApply<T,V> extends UniCompletion<T,V> {
+        Function<? super T,? extends V> fn;
+        UniApply(Executor executor, CompletableFuture<V> dep,
+                 CompletableFuture<T> src,
+                 Function<? super T,? extends V> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniApply(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final <S> boolean uniApply(CompletableFuture<S> a,
+                               Function<? super S,? extends T> f,
+                               UniApply<S,T> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") S s = (S) r;
+                completeValue(f.apply(s));
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <V> CompletableFuture<V> uniApplyStage(
+        Executor e, Function<? super T,? extends V> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<V> d = newIncompleteFuture();
+        if (e != null || !d.uniApply(this, f, null)) {
+            UniApply<T,V> c = new UniApply<T,V>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniAccept<T> extends UniCompletion<T,Void> {
+        Consumer<? super T> fn;
+        UniAccept(Executor executor, CompletableFuture<Void> dep,
+                  CompletableFuture<T> src, Consumer<? super T> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniAccept(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final <S> boolean uniAccept(CompletableFuture<S> a,
+                                Consumer<? super S> f, UniAccept<S> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") S s = (S) r;
+                f.accept(s);
+                completeNull();
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private CompletableFuture<Void> uniAcceptStage(Executor e,
+                                                   Consumer<? super T> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<Void> d = newIncompleteFuture();
+        if (e != null || !d.uniAccept(this, f, null)) {
+            UniAccept<T> c = new UniAccept<T>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniRun<T> extends UniCompletion<T,Void> {
+        Runnable fn;
+        UniRun(Executor executor, CompletableFuture<Void> dep,
+               CompletableFuture<T> src, Runnable fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniRun(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final boolean uniRun(CompletableFuture<?> a, Runnable f, UniRun<?> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        if (result == null) {
+            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
+                completeThrowable(x, r);
+            else
+                try {
+                    if (c != null && !c.claim())
+                        return false;
+                    f.run();
+                    completeNull();
+                } catch (Throwable ex) {
+                    completeThrowable(ex);
+                }
+        }
+        return true;
+    }
+
+    private CompletableFuture<Void> uniRunStage(Executor e, Runnable f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<Void> d = newIncompleteFuture();
+        if (e != null || !d.uniRun(this, f, null)) {
+            UniRun<T> c = new UniRun<T>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniWhenComplete<T> extends UniCompletion<T,T> {
+        BiConsumer<? super T, ? super Throwable> fn;
+        UniWhenComplete(Executor executor, CompletableFuture<T> dep,
+                        CompletableFuture<T> src,
+                        BiConsumer<? super T, ? super Throwable> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<T> tryFire(int mode) {
+            CompletableFuture<T> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniWhenComplete(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final boolean uniWhenComplete(CompletableFuture<T> a,
+                                  BiConsumer<? super T,? super Throwable> f,
+                                  UniWhenComplete<T> c) {
+        Object r; T t; Throwable x = null;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult) {
+                    x = ((AltResult)r).ex;
+                    t = null;
+                } else {
+                    @SuppressWarnings("unchecked") T tr = (T) r;
+                    t = tr;
+                }
+                f.accept(t, x);
+                if (x == null) {
+                    internalComplete(r);
+                    return true;
+                }
+            } catch (Throwable ex) {
+                if (x == null)
+                    x = ex;
+                else if (x != ex)
+                    x.addSuppressed(ex);
+            }
+            completeThrowable(x, r);
+        }
+        return true;
+    }
+
+    private CompletableFuture<T> uniWhenCompleteStage(
+        Executor e, BiConsumer<? super T, ? super Throwable> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<T> d = newIncompleteFuture();
+        if (e != null || !d.uniWhenComplete(this, f, null)) {
+            UniWhenComplete<T> c = new UniWhenComplete<T>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniHandle<T,V> extends UniCompletion<T,V> {
+        BiFunction<? super T, Throwable, ? extends V> fn;
+        UniHandle(Executor executor, CompletableFuture<V> dep,
+                  CompletableFuture<T> src,
+                  BiFunction<? super T, Throwable, ? extends V> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniHandle(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final <S> boolean uniHandle(CompletableFuture<S> a,
+                                BiFunction<? super S, Throwable, ? extends T> f,
+                                UniHandle<S,T> c) {
+        Object r; S s; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult) {
+                    x = ((AltResult)r).ex;
+                    s = null;
+                } else {
+                    x = null;
+                    @SuppressWarnings("unchecked") S ss = (S) r;
+                    s = ss;
+                }
+                completeValue(f.apply(s, x));
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <V> CompletableFuture<V> uniHandleStage(
+        Executor e, BiFunction<? super T, Throwable, ? extends V> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<V> d = newIncompleteFuture();
+        if (e != null || !d.uniHandle(this, f, null)) {
+            UniHandle<T,V> c = new UniHandle<T,V>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniExceptionally<T> extends UniCompletion<T,T> {
+        Function<? super Throwable, ? extends T> fn;
+        UniExceptionally(CompletableFuture<T> dep, CompletableFuture<T> src,
+                         Function<? super Throwable, ? extends T> fn) {
+            super(null, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<T> tryFire(int mode) { // never ASYNC
+            // assert mode != ASYNC;
+            CompletableFuture<T> d; CompletableFuture<T> a;
+            if ((d = dep) == null || !d.uniExceptionally(a = src, fn, this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final boolean uniExceptionally(CompletableFuture<T> a,
+                                   Function<? super Throwable, ? extends T> f,
+                                   UniExceptionally<T> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        if (result == null) {
+            try {
+                if (r instanceof AltResult && (x = ((AltResult)r).ex) != null) {
+                    if (c != null && !c.claim())
+                        return false;
+                    completeValue(f.apply(x));
+                } else
+                    internalComplete(r);
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private CompletableFuture<T> uniExceptionallyStage(
+        Function<Throwable, ? extends T> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<T> d = newIncompleteFuture();
+        if (!d.uniExceptionally(this, f, null)) {
+            UniExceptionally<T> c = new UniExceptionally<T>(d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniRelay<T> extends UniCompletion<T,T> { // for Compose
+        UniRelay(CompletableFuture<T> dep, CompletableFuture<T> src) {
+            super(null, dep, src);
+        }
+        final CompletableFuture<T> tryFire(int mode) {
+            CompletableFuture<T> d; CompletableFuture<T> a;
+            if ((d = dep) == null || !d.uniRelay(a = src))
+                return null;
+            src = null; dep = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final boolean uniRelay(CompletableFuture<T> a) {
+        Object r;
+        if (a == null || (r = a.result) == null)
+            return false;
+        if (result == null) // no need to claim
+            completeRelay(r);
+        return true;
+    }
+
+    private CompletableFuture<T> uniCopyStage() {
+        Object r;
+        CompletableFuture<T> d = newIncompleteFuture();
+        if ((r = result) != null)
+            d.completeRelay(r);
+        else {
+            UniRelay<T> c = new UniRelay<T>(d, this);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    private MinimalStage<T> uniAsMinimalStage() {
+        Object r;
+        if ((r = result) != null)
+            return new MinimalStage<T>(encodeRelay(r));
+        MinimalStage<T> d = new MinimalStage<T>();
+        UniRelay<T> c = new UniRelay<T>(d, this);
+        push(c);
+        c.tryFire(SYNC);
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniCompose<T,V> extends UniCompletion<T,V> {
+        Function<? super T, ? extends CompletionStage<V>> fn;
+        UniCompose(Executor executor, CompletableFuture<V> dep,
+                   CompletableFuture<T> src,
+                   Function<? super T, ? extends CompletionStage<V>> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniCompose(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final <S> boolean uniCompose(
+        CompletableFuture<S> a,
+        Function<? super S, ? extends CompletionStage<T>> f,
+        UniCompose<S,T> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") S s = (S) r;
+                CompletableFuture<T> g = f.apply(s).toCompletableFuture();
+                if (g.result == null || !uniRelay(g)) {
+                    UniRelay<T> copy = new UniRelay<T>(this, g);
+                    g.push(copy);
+                    copy.tryFire(SYNC);
+                    if (result == null)
+                        return false;
+                }
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <V> CompletableFuture<V> uniComposeStage(
+        Executor e, Function<? super T, ? extends CompletionStage<V>> f) {
+        if (f == null) throw new NullPointerException();
+        Object r, s; Throwable x;
+        CompletableFuture<V> d = newIncompleteFuture();
+        if (e == null && (r = result) != null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    d.result = encodeThrowable(x, r);
+                    return d;
+                }
+                r = null;
+            }
+            try {
+                @SuppressWarnings("unchecked") T t = (T) r;
+                CompletableFuture<V> g = f.apply(t).toCompletableFuture();
+                if ((s = g.result) != null)
+                    d.completeRelay(s);
+                else {
+                    UniRelay<V> c = new UniRelay<V>(d, g);
+                    g.push(c);
+                    c.tryFire(SYNC);
+                }
+                return d;
+            } catch (Throwable ex) {
+                d.result = encodeThrowable(ex);
+                return d;
+            }
+        }
+        UniCompose<T,V> c = new UniCompose<T,V>(e, d, this, f);
+        push(c);
+        c.tryFire(SYNC);
+        return d;
+    }
+
+    /* ------------- Two-input Completions -------------- */
+
+    /** A Completion for an action with two sources */
+    @SuppressWarnings("serial")
+    abstract static class BiCompletion<T,U,V> extends UniCompletion<T,V> {
+        CompletableFuture<U> snd; // second source for action
+        BiCompletion(Executor executor, CompletableFuture<V> dep,
+                     CompletableFuture<T> src, CompletableFuture<U> snd) {
+            super(executor, dep, src); this.snd = snd;
+        }
+    }
+
+    /** A Completion delegating to a BiCompletion */
+    @SuppressWarnings("serial")
+    static final class CoCompletion extends Completion {
+        BiCompletion<?,?,?> base;
+        CoCompletion(BiCompletion<?,?,?> base) { this.base = base; }
+        final CompletableFuture<?> tryFire(int mode) {
+            BiCompletion<?,?,?> c; CompletableFuture<?> d;
+            if ((c = base) == null || (d = c.tryFire(mode)) == null)
+                return null;
+            base = null; // detach
+            return d;
+        }
+        final boolean isLive() {
+            BiCompletion<?,?,?> c;
+            return (c = base) != null && c.dep != null;
+        }
+    }
+
+    /** Pushes completion to this and b unless both done. */
+    final void bipush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
+        if (c != null) {
+            Object r;
+            while ((r = result) == null && !tryPushStack(c))
+                lazySetNext(c, null); // clear on failure
+            if (b != null && b != this && b.result == null) {
+                Completion q = (r != null) ? c : new CoCompletion(c);
+                while (b.result == null && !b.tryPushStack(q))
+                    lazySetNext(q, null); // clear on failure
+            }
+        }
+    }
+
+    /** Post-processing after successful BiCompletion tryFire. */
+    final CompletableFuture<T> postFire(CompletableFuture<?> a,
+                                        CompletableFuture<?> b, int mode) {
+        if (b != null && b.stack != null) { // clean second source
+            if (mode < 0 || b.result == null)
+                b.cleanStack();
+            else
+                b.postComplete();
+        }
+        return postFire(a, mode);
+    }
+
+    @SuppressWarnings("serial")
+    static final class BiApply<T,U,V> extends BiCompletion<T,U,V> {
+        BiFunction<? super T,? super U,? extends V> fn;
+        BiApply(Executor executor, CompletableFuture<V> dep,
+                CompletableFuture<T> src, CompletableFuture<U> snd,
+                BiFunction<? super T,? super U,? extends V> fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.biApply(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final <R,S> boolean biApply(CompletableFuture<R> a,
+                                CompletableFuture<S> b,
+                                BiFunction<? super R,? super S,? extends T> f,
+                                BiApply<R,S,T> c) {
+        Object r, s; Throwable x;
+        if (a == null || (r = a.result) == null ||
+            b == null || (s = b.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            if (s instanceof AltResult) {
+                if ((x = ((AltResult)s).ex) != null) {
+                    completeThrowable(x, s);
+                    break tryComplete;
+                }
+                s = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") R rr = (R) r;
+                @SuppressWarnings("unchecked") S ss = (S) s;
+                completeValue(f.apply(rr, ss));
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <U,V> CompletableFuture<V> biApplyStage(
+        Executor e, CompletionStage<U> o,
+        BiFunction<? super T,? super U,? extends V> f) {
+        CompletableFuture<U> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<V> d = newIncompleteFuture();
+        if (e != null || !d.biApply(this, b, f, null)) {
+            BiApply<T,U,V> c = new BiApply<T,U,V>(e, d, this, b, f);
+            bipush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class BiAccept<T,U> extends BiCompletion<T,U,Void> {
+        BiConsumer<? super T,? super U> fn;
+        BiAccept(Executor executor, CompletableFuture<Void> dep,
+                 CompletableFuture<T> src, CompletableFuture<U> snd,
+                 BiConsumer<? super T,? super U> fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.biAccept(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final <R,S> boolean biAccept(CompletableFuture<R> a,
+                                 CompletableFuture<S> b,
+                                 BiConsumer<? super R,? super S> f,
+                                 BiAccept<R,S> c) {
+        Object r, s; Throwable x;
+        if (a == null || (r = a.result) == null ||
+            b == null || (s = b.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            if (s instanceof AltResult) {
+                if ((x = ((AltResult)s).ex) != null) {
+                    completeThrowable(x, s);
+                    break tryComplete;
+                }
+                s = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") R rr = (R) r;
+                @SuppressWarnings("unchecked") S ss = (S) s;
+                f.accept(rr, ss);
+                completeNull();
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <U> CompletableFuture<Void> biAcceptStage(
+        Executor e, CompletionStage<U> o,
+        BiConsumer<? super T,? super U> f) {
+        CompletableFuture<U> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<Void> d = newIncompleteFuture();
+        if (e != null || !d.biAccept(this, b, f, null)) {
+            BiAccept<T,U> c = new BiAccept<T,U>(e, d, this, b, f);
+            bipush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class BiRun<T,U> extends BiCompletion<T,U,Void> {
+        Runnable fn;
+        BiRun(Executor executor, CompletableFuture<Void> dep,
+              CompletableFuture<T> src,
+              CompletableFuture<U> snd,
+              Runnable fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.biRun(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final boolean biRun(CompletableFuture<?> a, CompletableFuture<?> b,
+                        Runnable f, BiRun<?,?> c) {
+        Object r, s; Throwable x;
+        if (a == null || (r = a.result) == null ||
+            b == null || (s = b.result) == null || f == null)
+            return false;
+        if (result == null) {
+            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
+                completeThrowable(x, r);
+            else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
+                completeThrowable(x, s);
+            else
+                try {
+                    if (c != null && !c.claim())
+                        return false;
+                    f.run();
+                    completeNull();
+                } catch (Throwable ex) {
+                    completeThrowable(ex);
+                }
+        }
+        return true;
+    }
+
+    private CompletableFuture<Void> biRunStage(Executor e, CompletionStage<?> o,
+                                               Runnable f) {
+        CompletableFuture<?> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<Void> d = newIncompleteFuture();
+        if (e != null || !d.biRun(this, b, f, null)) {
+            BiRun<T,?> c = new BiRun<>(e, d, this, b, f);
+            bipush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class BiRelay<T,U> extends BiCompletion<T,U,Void> { // for And
+        BiRelay(CompletableFuture<Void> dep,
+                CompletableFuture<T> src,
+                CompletableFuture<U> snd) {
+            super(null, dep, src, snd);
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null || !d.biRelay(a = src, b = snd))
+                return null;
+            src = null; snd = null; dep = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    boolean biRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
+        Object r, s; Throwable x;
+        if (a == null || (r = a.result) == null ||
+            b == null || (s = b.result) == null)
+            return false;
+        if (result == null) {
+            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
+                completeThrowable(x, r);
+            else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
+                completeThrowable(x, s);
+            else
+                completeNull();
+        }
+        return true;
+    }
+
+    /** Recursively constructs a tree of completions. */
+    static CompletableFuture<Void> andTree(CompletableFuture<?>[] cfs,
+                                           int lo, int hi) {
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        if (lo > hi) // empty
+            d.result = NIL;
+        else {
+            CompletableFuture<?> a, b;
+            int mid = (lo + hi) >>> 1;
+            if ((a = (lo == mid ? cfs[lo] :
+                      andTree(cfs, lo, mid))) == null ||
+                (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
+                      andTree(cfs, mid+1, hi))) == null)
+                throw new NullPointerException();
+            if (!d.biRelay(a, b)) {
+                BiRelay<?,?> c = new BiRelay<>(d, a, b);
+                a.bipush(b, c);
+                c.tryFire(SYNC);
+            }
+        }
+        return d;
+    }
+
+    /* ------------- Projected (Ored) BiCompletions -------------- */
+
+    /** Pushes completion to this and b unless either done. */
+    final void orpush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
+        if (c != null) {
+            while ((b == null || b.result == null) && result == null) {
+                if (tryPushStack(c)) {
+                    if (b != null && b != this && b.result == null) {
+                        Completion q = new CoCompletion(c);
+                        while (result == null && b.result == null &&
+                               !b.tryPushStack(q))
+                            lazySetNext(q, null); // clear on failure
+                    }
+                    break;
+                }
+                lazySetNext(c, null); // clear on failure
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class OrApply<T,U extends T,V> extends BiCompletion<T,U,V> {
+        Function<? super T,? extends V> fn;
+        OrApply(Executor executor, CompletableFuture<V> dep,
+                CompletableFuture<T> src,
+                CompletableFuture<U> snd,
+                Function<? super T,? extends V> fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.orApply(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final <R,S extends R> boolean orApply(CompletableFuture<R> a,
+                                          CompletableFuture<S> b,
+                                          Function<? super R, ? extends T> f,
+                                          OrApply<R,S,T> c) {
+        Object r; Throwable x;
+        if (a == null || b == null ||
+            ((r = a.result) == null && (r = b.result) == null) || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult) {
+                    if ((x = ((AltResult)r).ex) != null) {
+                        completeThrowable(x, r);
+                        break tryComplete;
+                    }
+                    r = null;
+                }
+                @SuppressWarnings("unchecked") R rr = (R) r;
+                completeValue(f.apply(rr));
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <U extends T,V> CompletableFuture<V> orApplyStage(
+        Executor e, CompletionStage<U> o,
+        Function<? super T, ? extends V> f) {
+        CompletableFuture<U> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<V> d = newIncompleteFuture();
+        if (e != null || !d.orApply(this, b, f, null)) {
+            OrApply<T,U,V> c = new OrApply<T,U,V>(e, d, this, b, f);
+            orpush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class OrAccept<T,U extends T> extends BiCompletion<T,U,Void> {
+        Consumer<? super T> fn;
+        OrAccept(Executor executor, CompletableFuture<Void> dep,
+                 CompletableFuture<T> src,
+                 CompletableFuture<U> snd,
+                 Consumer<? super T> fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.orAccept(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final <R,S extends R> boolean orAccept(CompletableFuture<R> a,
+                                           CompletableFuture<S> b,
+                                           Consumer<? super R> f,
+                                           OrAccept<R,S> c) {
+        Object r; Throwable x;
+        if (a == null || b == null ||
+            ((r = a.result) == null && (r = b.result) == null) || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult) {
+                    if ((x = ((AltResult)r).ex) != null) {
+                        completeThrowable(x, r);
+                        break tryComplete;
+                    }
+                    r = null;
+                }
+                @SuppressWarnings("unchecked") R rr = (R) r;
+                f.accept(rr);
+                completeNull();
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <U extends T> CompletableFuture<Void> orAcceptStage(
+        Executor e, CompletionStage<U> o, Consumer<? super T> f) {
+        CompletableFuture<U> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<Void> d = newIncompleteFuture();
+        if (e != null || !d.orAccept(this, b, f, null)) {
+            OrAccept<T,U> c = new OrAccept<T,U>(e, d, this, b, f);
+            orpush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class OrRun<T,U> extends BiCompletion<T,U,Void> {
+        Runnable fn;
+        OrRun(Executor executor, CompletableFuture<Void> dep,
+              CompletableFuture<T> src,
+              CompletableFuture<U> snd,
+              Runnable fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.orRun(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final boolean orRun(CompletableFuture<?> a, CompletableFuture<?> b,
+                        Runnable f, OrRun<?,?> c) {
+        Object r; Throwable x;
+        if (a == null || b == null ||
+            ((r = a.result) == null && (r = b.result) == null) || f == null)
+            return false;
+        if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
+                    completeThrowable(x, r);
+                else {
+                    f.run();
+                    completeNull();
+                }
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private CompletableFuture<Void> orRunStage(Executor e, CompletionStage<?> o,
+                                               Runnable f) {
+        CompletableFuture<?> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<Void> d = newIncompleteFuture();
+        if (e != null || !d.orRun(this, b, f, null)) {
+            OrRun<T,?> c = new OrRun<>(e, d, this, b, f);
+            orpush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class OrRelay<T,U> extends BiCompletion<T,U,Object> { // for Or
+        OrRelay(CompletableFuture<Object> dep, CompletableFuture<T> src,
+                CompletableFuture<U> snd) {
+            super(null, dep, src, snd);
+        }
+        final CompletableFuture<Object> tryFire(int mode) {
+            CompletableFuture<Object> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null || !d.orRelay(a = src, b = snd))
+                return null;
+            src = null; snd = null; dep = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final boolean orRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
+        Object r;
+        if (a == null || b == null ||
+            ((r = a.result) == null && (r = b.result) == null))
+            return false;
+        if (result == null)
+            completeRelay(r);
+        return true;
+    }
+
+    /** Recursively constructs a tree of completions. */
+    static CompletableFuture<Object> orTree(CompletableFuture<?>[] cfs,
+                                            int lo, int hi) {
+        CompletableFuture<Object> d = new CompletableFuture<Object>();
+        if (lo <= hi) {
+            CompletableFuture<?> a, b;
+            int mid = (lo + hi) >>> 1;
+            if ((a = (lo == mid ? cfs[lo] :
+                      orTree(cfs, lo, mid))) == null ||
+                (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
+                      orTree(cfs, mid+1, hi))) == null)
+                throw new NullPointerException();
+            if (!d.orRelay(a, b)) {
+                OrRelay<?,?> c = new OrRelay<>(d, a, b);
+                a.orpush(b, c);
+                c.tryFire(SYNC);
+            }
+        }
+        return d;
+    }
+
+    /* ------------- Zero-input Async forms -------------- */
+
+    @SuppressWarnings("serial")
+    static final class AsyncSupply<T> extends ForkJoinTask<Void>
+        implements Runnable, AsynchronousCompletionTask {
+        CompletableFuture<T> dep; Supplier<? extends T> fn;
+        AsyncSupply(CompletableFuture<T> dep, Supplier<? extends T> fn) {
+            this.dep = dep; this.fn = fn;
+        }
+
+        public final Void getRawResult() { return null; }
+        public final void setRawResult(Void v) {}
+        public final boolean exec() { run(); return true; }
+
+        public void run() {
+            CompletableFuture<T> d; Supplier<? extends T> f;
+            if ((d = dep) != null && (f = fn) != null) {
+                dep = null; fn = null;
+                if (d.result == null) {
+                    try {
+                        d.completeValue(f.get());
+                    } catch (Throwable ex) {
+                        d.completeThrowable(ex);
+                    }
+                }
+                d.postComplete();
+            }
+        }
+    }
+
+    static <U> CompletableFuture<U> asyncSupplyStage(Executor e,
+                                                     Supplier<U> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<U> d = new CompletableFuture<U>();
+        e.execute(new AsyncSupply<U>(d, f));
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class AsyncRun extends ForkJoinTask<Void>
+        implements Runnable, AsynchronousCompletionTask {
+        CompletableFuture<Void> dep; Runnable fn;
+        AsyncRun(CompletableFuture<Void> dep, Runnable fn) {
+            this.dep = dep; this.fn = fn;
+        }
+
+        public final Void getRawResult() { return null; }
+        public final void setRawResult(Void v) {}
+        public final boolean exec() { run(); return true; }
+
+        public void run() {
+            CompletableFuture<Void> d; Runnable f;
+            if ((d = dep) != null && (f = fn) != null) {
+                dep = null; fn = null;
+                if (d.result == null) {
+                    try {
+                        f.run();
+                        d.completeNull();
+                    } catch (Throwable ex) {
+                        d.completeThrowable(ex);
+                    }
+                }
+                d.postComplete();
+            }
+        }
+    }
+
+    static CompletableFuture<Void> asyncRunStage(Executor e, Runnable f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        e.execute(new AsyncRun(d, f));
+        return d;
+    }
+
+    /* ------------- Signallers -------------- */
+
+    /**
+     * Completion for recording and releasing a waiting thread.  This
+     * class implements ManagedBlocker to avoid starvation when
+     * blocking actions pile up in ForkJoinPools.
+     */
+    @SuppressWarnings("serial")
+    static final class Signaller extends Completion
+        implements ForkJoinPool.ManagedBlocker {
+        long nanos;                    // remaining wait time if timed
+        final long deadline;           // non-zero if timed
+        final boolean interruptible;
+        boolean interrupted;
+        volatile Thread thread;
+
+        Signaller(boolean interruptible, long nanos, long deadline) {
+            this.thread = Thread.currentThread();
+            this.interruptible = interruptible;
+            this.nanos = nanos;
+            this.deadline = deadline;
+        }
+        final CompletableFuture<?> tryFire(int ignore) {
+            Thread w; // no need to atomically claim
+            if ((w = thread) != null) {
+                thread = null;
+                LockSupport.unpark(w);
+            }
+            return null;
+        }
+        public boolean isReleasable() {
+            if (Thread.interrupted())
+                interrupted = true;
+            return ((interrupted && interruptible) ||
+                    (deadline != 0L &&
+                     (nanos <= 0L ||
+                      (nanos = deadline - System.nanoTime()) <= 0L)) ||
+                    thread == null);
+        }
+        public boolean block() {
+            while (!isReleasable()) {
+                if (deadline == 0L)
+                    LockSupport.park(this);
+                else
+                    LockSupport.parkNanos(this, nanos);
+            }
+            return true;
+        }
+        final boolean isLive() { return thread != null; }
+    }
+
+    /**
+     * Returns raw result after waiting, or null if interruptible and
+     * interrupted.
+     */
+    private Object waitingGet(boolean interruptible) {
+        Signaller q = null;
+        boolean queued = false;
+        int spins = SPINS;
+        Object r;
+        while ((r = result) == null) {
+            if (spins > 0) {
+                if (ThreadLocalRandom.nextSecondarySeed() >= 0)
+                    --spins;
+            }
+            else if (q == null)
+                q = new Signaller(interruptible, 0L, 0L);
+            else if (!queued)
+                queued = tryPushStack(q);
+            else {
+                try {
+                    ForkJoinPool.managedBlock(q);
+                } catch (InterruptedException ie) { // currently cannot happen
+                    q.interrupted = true;
+                }
+                if (q.interrupted && interruptible)
+                    break;
+            }
+        }
+        if (q != null) {
+            q.thread = null;
+            if (q.interrupted) {
+                if (interruptible)
+                    cleanStack();
+                else
+                    Thread.currentThread().interrupt();
+            }
+        }
+        if (r != null)
+            postComplete();
+        return r;
+    }
+
+    /**
+     * Returns raw result after waiting, or null if interrupted, or
+     * throws TimeoutException on timeout.
+     */
+    private Object timedGet(long nanos) throws TimeoutException {
+        if (Thread.interrupted())
+            return null;
+        if (nanos > 0L) {
+            long d = System.nanoTime() + nanos;
+            long deadline = (d == 0L) ? 1L : d; // avoid 0
+            Signaller q = null;
+            boolean queued = false;
+            Object r;
+            while ((r = result) == null) { // similar to untimed, without spins
+                if (q == null)
+                    q = new Signaller(true, nanos, deadline);
+                else if (!queued)
+                    queued = tryPushStack(q);
+                else if (q.nanos <= 0L)
+                    break;
+                else {
+                    try {
+                        ForkJoinPool.managedBlock(q);
+                    } catch (InterruptedException ie) {
+                        q.interrupted = true;
+                    }
+                    if (q.interrupted)
+                        break;
+                }
+            }
+            if (q != null)
+                q.thread = null;
+            if (r != null)
+                postComplete();
+            else
+                cleanStack();
+            if (r != null || (q != null && q.interrupted))
+                return r;
+        }
+        throw new TimeoutException();
+    }
+
+    /* ------------- public methods -------------- */
+
+    /**
+     * Creates a new incomplete CompletableFuture.
+     */
+    public CompletableFuture() {
+    }
+
+    /**
+     * Creates a new complete CompletableFuture with given encoded result.
+     */
+    CompletableFuture(Object r) {
+        this.result = r;
+    }
+
+    /**
+     * Returns a new CompletableFuture that is asynchronously completed
+     * by a task running in the {@link ForkJoinPool#commonPool()} with
+     * the value obtained by calling the given Supplier.
+     *
+     * @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) {
+        return asyncSupplyStage(ASYNC_POOL, supplier);
+    }
+
+    /**
+     * Returns a new CompletableFuture that is asynchronously completed
+     * by a task running in the given executor with the value obtained
+     * by calling the given Supplier.
+     *
+     * @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,
+                                                       Executor executor) {
+        return asyncSupplyStage(screenExecutor(executor), supplier);
+    }
+
+    /**
+     * Returns a new CompletableFuture that is asynchronously completed
+     * by a task running in the {@link ForkJoinPool#commonPool()} after
+     * it runs the given action.
+     *
+     * @param runnable the action to run before completing the
+     * returned CompletableFuture
+     * @return the new CompletableFuture
+     */
+    public static CompletableFuture<Void> runAsync(Runnable runnable) {
+        return asyncRunStage(ASYNC_POOL, runnable);
+    }
+
+    /**
+     * Returns a new CompletableFuture that is asynchronously completed
+     * by a task running in the given executor after it runs the given
+     * action.
+     *
+     * @param runnable the action to run before completing the
+     * returned CompletableFuture
+     * @param executor the executor to use for asynchronous execution
+     * @return the new CompletableFuture
+     */
+    public static CompletableFuture<Void> runAsync(Runnable runnable,
+                                                   Executor executor) {
+        return asyncRunStage(screenExecutor(executor), runnable);
+    }
+
+    /**
+     * Returns a new CompletableFuture that is already completed with
+     * 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) {
+        return new CompletableFuture<U>((value == null) ? NIL : value);
+    }
+
+    /**
+     * Returns {@code true} if completed in any fashion: normally,
+     * exceptionally, or via cancellation.
+     *
+     * @return {@code true} if completed
+     */
+    public boolean isDone() {
+        return result != null;
+    }
+
+    /**
+     * Waits if necessary for this future to complete, and then
+     * returns its result.
+     *
+     * @return the result value
+     * @throws CancellationException if this future was cancelled
+     * @throws ExecutionException if this future completed exceptionally
+     * @throws InterruptedException if the current thread was interrupted
+     * while waiting
+     */
+    public T get() throws InterruptedException, ExecutionException {
+        Object r;
+        return reportGet((r = result) == null ? waitingGet(true) : r);
+    }
+
+    /**
+     * Waits if necessary for at most the given time for this future
+     * to complete, and then returns its result, if available.
+     *
+     * @param timeout the maximum time to wait
+     * @param unit the time unit of the timeout argument
+     * @return the result value
+     * @throws CancellationException if this future was cancelled
+     * @throws ExecutionException if this future completed exceptionally
+     * @throws InterruptedException if the current thread was interrupted
+     * while waiting
+     * @throws TimeoutException if the wait timed out
+     */
+    public T get(long timeout, TimeUnit unit)
+        throws InterruptedException, ExecutionException, TimeoutException {
+        Object r;
+        long nanos = unit.toNanos(timeout);
+        return reportGet((r = result) == null ? timedGet(nanos) : r);
+    }
+
+    /**
+     * Returns the result value when complete, or throws an
+     * (unchecked) exception if completed exceptionally. To better
+     * conform with the use of common functional forms, if a
+     * computation involved in the completion of this
+     * CompletableFuture threw an exception, this method throws an
+     * (unchecked) {@link CompletionException} with the underlying
+     * exception as its cause.
+     *
+     * @return the result value
+     * @throws CancellationException if the computation was cancelled
+     * @throws CompletionException if this future completed
+     * exceptionally or a completion computation threw an exception
+     */
+    public T join() {
+        Object r;
+        return reportJoin((r = result) == null ? waitingGet(false) : r);
+    }
+
+    /**
+     * Returns the result value (or throws any encountered exception)
+     * if completed, else returns the given valueIfAbsent.
+     *
+     * @param valueIfAbsent the value to return if not completed
+     * @return the result value, if completed, else the given valueIfAbsent
+     * @throws CancellationException if the computation was cancelled
+     * @throws CompletionException if this future completed
+     * exceptionally or a completion computation threw an exception
+     */
+    public T getNow(T valueIfAbsent) {
+        Object r;
+        return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
+    }
+
+    /**
+     * If not already completed, sets the value returned by {@link
+     * #get()} and related methods to the given value.
+     *
+     * @param value the result value
+     * @return {@code true} if this invocation caused this CompletableFuture
+     * to transition to a completed state, else {@code false}
+     */
+    public boolean complete(T value) {
+        boolean triggered = completeValue(value);
+        postComplete();
+        return triggered;
+    }
+
+    /**
+     * If not already completed, causes invocations of {@link #get()}
+     * and related methods to throw the given exception.
+     *
+     * @param ex the exception
+     * @return {@code true} if this invocation caused this CompletableFuture
+     * to transition to a completed state, else {@code false}
+     */
+    public boolean completeExceptionally(Throwable ex) {
+        if (ex == null) throw new NullPointerException();
+        boolean triggered = internalComplete(new AltResult(ex));
+        postComplete();
+        return triggered;
+    }
+
+    public <U> CompletableFuture<U> thenApply(
+        Function<? super T,? extends U> fn) {
+        return uniApplyStage(null, fn);
+    }
+
+    public <U> CompletableFuture<U> thenApplyAsync(
+        Function<? super T,? extends U> fn) {
+        return uniApplyStage(defaultExecutor(), fn);
+    }
+
+    public <U> CompletableFuture<U> thenApplyAsync(
+        Function<? super T,? extends U> fn, Executor executor) {
+        return uniApplyStage(screenExecutor(executor), fn);
+    }
+
+    public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
+        return uniAcceptStage(null, action);
+    }
+
+    public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) {
+        return uniAcceptStage(defaultExecutor(), action);
+    }
+
+    public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,
+                                                   Executor executor) {
+        return uniAcceptStage(screenExecutor(executor), action);
+    }
+
+    public CompletableFuture<Void> thenRun(Runnable action) {
+        return uniRunStage(null, action);
+    }
+
+    public CompletableFuture<Void> thenRunAsync(Runnable action) {
+        return uniRunStage(defaultExecutor(), action);
+    }
+
+    public CompletableFuture<Void> thenRunAsync(Runnable action,
+                                                Executor executor) {
+        return uniRunStage(screenExecutor(executor), action);
+    }
+
+    public <U,V> CompletableFuture<V> thenCombine(
+        CompletionStage<? extends U> other,
+        BiFunction<? super T,? super U,? extends V> fn) {
+        return biApplyStage(null, other, fn);
+    }
+
+    public <U,V> CompletableFuture<V> thenCombineAsync(
+        CompletionStage<? extends U> other,
+        BiFunction<? super T,? super U,? extends V> fn) {
+        return biApplyStage(defaultExecutor(), other, fn);
+    }
+
+    public <U,V> CompletableFuture<V> thenCombineAsync(
+        CompletionStage<? extends U> other,
+        BiFunction<? super T,? super U,? extends V> fn, Executor executor) {
+        return biApplyStage(screenExecutor(executor), other, fn);
+    }
+
+    public <U> CompletableFuture<Void> thenAcceptBoth(
+        CompletionStage<? extends U> other,
+        BiConsumer<? super T, ? super U> action) {
+        return biAcceptStage(null, other, action);
+    }
+
+    public <U> CompletableFuture<Void> thenAcceptBothAsync(
+        CompletionStage<? extends U> other,
+        BiConsumer<? super T, ? super U> action) {
+        return biAcceptStage(defaultExecutor(), other, action);
+    }
+
+    public <U> CompletableFuture<Void> thenAcceptBothAsync(
+        CompletionStage<? extends U> other,
+        BiConsumer<? super T, ? super U> action, Executor executor) {
+        return biAcceptStage(screenExecutor(executor), other, action);
+    }
+
+    public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,
+                                                Runnable action) {
+        return biRunStage(null, other, action);
+    }
+
+    public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,
+                                                     Runnable action) {
+        return biRunStage(defaultExecutor(), other, action);
+    }
+
+    public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,
+                                                     Runnable action,
+                                                     Executor executor) {
+        return biRunStage(screenExecutor(executor), other, action);
+    }
+
+    public <U> CompletableFuture<U> applyToEither(
+        CompletionStage<? extends T> other, Function<? super T, U> fn) {
+        return orApplyStage(null, other, fn);
+    }
+
+    public <U> CompletableFuture<U> applyToEitherAsync(
+        CompletionStage<? extends T> other, Function<? super T, U> fn) {
+        return orApplyStage(defaultExecutor(), other, fn);
+    }
+
+    public <U> CompletableFuture<U> applyToEitherAsync(
+        CompletionStage<? extends T> other, Function<? super T, U> fn,
+        Executor executor) {
+        return orApplyStage(screenExecutor(executor), other, fn);
+    }
+
+    public CompletableFuture<Void> acceptEither(
+        CompletionStage<? extends T> other, Consumer<? super T> action) {
+        return orAcceptStage(null, other, action);
+    }
+
+    public CompletableFuture<Void> acceptEitherAsync(
+        CompletionStage<? extends T> other, Consumer<? super T> action) {
+        return orAcceptStage(defaultExecutor(), other, action);
+    }
+
+    public CompletableFuture<Void> acceptEitherAsync(
+        CompletionStage<? extends T> other, Consumer<? super T> action,
+        Executor executor) {
+        return orAcceptStage(screenExecutor(executor), other, action);
+    }
+
+    public CompletableFuture<Void> runAfterEither(CompletionStage<?> other,
+                                                  Runnable action) {
+        return orRunStage(null, other, action);
+    }
+
+    public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
+                                                       Runnable action) {
+        return orRunStage(defaultExecutor(), other, action);
+    }
+
+    public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
+                                                       Runnable action,
+                                                       Executor executor) {
+        return orRunStage(screenExecutor(executor), other, action);
+    }
+
+    public <U> CompletableFuture<U> thenCompose(
+        Function<? super T, ? extends CompletionStage<U>> fn) {
+        return uniComposeStage(null, fn);
+    }
+
+    public <U> CompletableFuture<U> thenComposeAsync(
+        Function<? super T, ? extends CompletionStage<U>> fn) {
+        return uniComposeStage(defaultExecutor(), fn);
+    }
+
+    public <U> CompletableFuture<U> thenComposeAsync(
+        Function<? super T, ? extends CompletionStage<U>> fn,
+        Executor executor) {
+        return uniComposeStage(screenExecutor(executor), fn);
+    }
+
+    public CompletableFuture<T> whenComplete(
+        BiConsumer<? super T, ? super Throwable> action) {
+        return uniWhenCompleteStage(null, action);
+    }
+
+    public CompletableFuture<T> whenCompleteAsync(
+        BiConsumer<? super T, ? super Throwable> action) {
+        return uniWhenCompleteStage(defaultExecutor(), action);
+    }
+
+    public CompletableFuture<T> whenCompleteAsync(
+        BiConsumer<? super T, ? super Throwable> action, Executor executor) {
+        return uniWhenCompleteStage(screenExecutor(executor), action);
+    }
+
+    public <U> CompletableFuture<U> handle(
+        BiFunction<? super T, Throwable, ? extends U> fn) {
+        return uniHandleStage(null, fn);
+    }
+
+    public <U> CompletableFuture<U> handleAsync(
+        BiFunction<? super T, Throwable, ? extends U> fn) {
+        return uniHandleStage(defaultExecutor(), fn);
+    }
+
+    public <U> CompletableFuture<U> handleAsync(
+        BiFunction<? super T, Throwable, ? extends U> fn, Executor executor) {
+        return uniHandleStage(screenExecutor(executor), fn);
+    }
+
+    /**
+     * 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
+     * function of the exception triggering this CompletableFuture's
+     * 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
+     * exceptionally
+     * @return the new CompletableFuture
+     */
+    public CompletableFuture<T> exceptionally(
+        Function<Throwable, ? extends T> fn) {
+        return uniExceptionallyStage(fn);
+    }
+
+
+    /* ------------- Arbitrary-arity constructions -------------- */
+
+    /**
+     * Returns a new CompletableFuture that is completed when all of
+     * the given CompletableFutures complete.  If any of the given
+     * CompletableFutures complete exceptionally, then the returned
+     * CompletableFuture also does so, with a CompletionException
+     * holding this exception as its cause.  Otherwise, the results,
+     * if any, of the given CompletableFutures are not reflected in
+     * the returned CompletableFuture, but may be obtained by
+     * inspecting them individually. If no CompletableFutures are
+     * provided, returns a CompletableFuture completed with the value
+     * {@code null}.
+     *
+     * <p>Among the applications of this method is to await completion
+     * of a set of independent CompletableFutures before continuing a
+     * program, as in: {@code CompletableFuture.allOf(c1, c2,
+     * c3).join();}.
+     *
+     * @param cfs the CompletableFutures
+     * @return a new CompletableFuture that is completed when all of the
+     * given CompletableFutures complete
+     * @throws NullPointerException if the array or any of its elements are
+     * {@code null}
+     */
+    public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) {
+        return andTree(cfs, 0, cfs.length - 1);
+    }
+
+    /**
+     * Returns a new CompletableFuture that is completed when any of
+     * the given CompletableFutures complete, with the same result.
+     * Otherwise, if it completed exceptionally, the returned
+     * CompletableFuture also does so, with a CompletionException
+     * holding this exception as its cause.  If no CompletableFutures
+     * are provided, returns an incomplete CompletableFuture.
+     *
+     * @param cfs the CompletableFutures
+     * @return a new CompletableFuture that is completed with the
+     * result or exception of any of the given CompletableFutures when
+     * one completes
+     * @throws NullPointerException if the array or any of its elements are
+     * {@code null}
+     */
+    public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
+        return orTree(cfs, 0, cfs.length - 1);
+    }
+
+    /* ------------- Control and status methods -------------- */
+
+    /**
+     * If not already completed, completes this CompletableFuture with
+     * a {@link CancellationException}. Dependent CompletableFutures
+     * that have not already completed will also complete
+     * exceptionally, with a {@link CompletionException} caused by
+     * this {@code CancellationException}.
+     *
+     * @param mayInterruptIfRunning this value has no effect in this
+     * implementation because interrupts are not used to control
+     * processing.
+     *
+     * @return {@code true} if this task is now cancelled
+     */
+    public boolean cancel(boolean mayInterruptIfRunning) {
+        boolean cancelled = (result == null) &&
+            internalComplete(new AltResult(new CancellationException()));
+        postComplete();
+        return cancelled || isCancelled();
+    }
+
+    /**
+     * Returns {@code true} if this CompletableFuture was cancelled
+     * before it completed normally.
+     *
+     * @return {@code true} if this CompletableFuture was cancelled
+     * before it completed normally
+     */
+    public boolean isCancelled() {
+        Object r;
+        return ((r = result) instanceof AltResult) &&
+            (((AltResult)r).ex instanceof CancellationException);
+    }
+
+    /**
+     * 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
+     * error recovery actions, and even in such situations may result
+     * in ongoing dependent completions using established versus
+     * overwritten outcomes.
+     *
+     * @param value the completion value
+     */
+    public void obtrudeValue(T value) {
+        result = (value == null) ? NIL : value;
+        postComplete();
+    }
+
+    /**
+     * Forcibly causes subsequent invocations of method {@link #get()}
+     * and related methods to throw the given exception, whether or
+     * not already completed. This method is designed for use only in
+     * error recovery actions, and even in such situations may result
+     * in ongoing dependent completions using established versus
+     * overwritten outcomes.
+     *
+     * @param ex the exception
+     * @throws NullPointerException if the exception is null
+     */
+    public void obtrudeException(Throwable ex) {
+        if (ex == null) throw new NullPointerException();
+        result = new AltResult(ex);
+        postComplete();
+    }
+
+    /**
+     * Returns the estimated number of CompletableFutures whose
+     * completions are awaiting completion of this CompletableFuture.
+     * This method is designed for use in monitoring system state, not
+     * for synchronization control.
+     *
+     * @return the number of dependent CompletableFutures
+     */
+    public int getNumberOfDependents() {
+        int count = 0;
+        for (Completion p = stack; p != null; p = p.next)
+            ++count;
+        return count;
+    }
+
+    /**
+     * Returns a string identifying this CompletableFuture, as well as
+     * its completion state.  The state, in brackets, contains the
+     * String {@code "Completed Normally"} or the String {@code
+     * "Completed Exceptionally"}, or the String {@code "Not
+     * completed"} followed by the number of CompletableFutures
+     * dependent upon its completion, if any.
+     *
+     * @return a string identifying this CompletableFuture, as well as its state
+     */
+    public String toString() {
+        Object r = result;
+        int count = 0; // avoid call to getNumberOfDependents in case disabled
+        for (Completion p = stack; p != null; p = p.next)
+            ++count;
+        return super.toString() +
+            ((r == null) ?
+             ((count == 0) ?
+              "[Not completed]" :
+              "[Not completed, " + count + " dependents]") :
+             (((r instanceof AltResult) && ((AltResult)r).ex != null) ?
+              "[Completed exceptionally]" :
+              "[Completed normally]"));
+    }
+
+    // jdk9 additions
+
+    /**
+     * Returns a new incomplete CompletableFuture of the type to be
+     * returned by a CompletionStage method. Subclasses should
+     * normally override this method to return an instance of the same
+     * class as this CompletableFuture. The default implementation
+     * returns an instance of class CompletableFuture.
+     *
+     * @param <U> the type of the value
+     * @return a new CompletableFuture
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public <U> CompletableFuture<U> newIncompleteFuture() {
+        return new CompletableFuture<U>();
+    }
+
+    /**
+     * Returns the default Executor used for async methods that do not
+     * specify an Executor. This class uses the {@link
+     * ForkJoinPool#commonPool()} if it supports more than one
+     * parallel thread, or else an Executor using one thread per async
+     * task.  This method may be overridden in subclasses to return
+     * an Executor that provides at least one independent thread.
+     *
+     * @return the executor
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public Executor defaultExecutor() {
+        return ASYNC_POOL;
+    }
+
+    /**
+     * Returns a new CompletableFuture that is completed normally with
+     * the same value as this CompletableFuture when it completes
+     * normally. If this CompletableFuture completes exceptionally,
+     * then the returned CompletableFuture completes exceptionally
+     * with a CompletionException with this exception as cause. The
+     * behavior is equivalent to {@code thenApply(x -> x)}. This
+     * method may be useful as a form of "defensive copying", to
+     * prevent clients from completing, while still being able to
+     * arrange dependent actions.
+     *
+     * @return the new CompletableFuture
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public CompletableFuture<T> copy() {
+        return uniCopyStage();
+    }
+
+    /**
+     * Returns a new CompletionStage that is completed normally with
+     * the same value as this CompletableFuture when it completes
+     * normally, and cannot be independently completed or otherwise
+     * used in ways not defined by the methods of interface {@link
+     * CompletionStage}.  If this CompletableFuture completes
+     * exceptionally, then the returned CompletionStage completes
+     * exceptionally with a CompletionException with this exception as
+     * cause.
+     *
+     * @return the new CompletionStage
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public CompletionStage<T> minimalCompletionStage() {
+        return uniAsMinimalStage();
+    }
+
+    /**
+     * Completes this CompletableFuture with the result of
+     * the given Supplier function invoked from an asynchronous
+     * task using the given executor.
+     *
+     * @param supplier a function returning the value to be used
+     * to complete this CompletableFuture
+     * @param executor the executor to use for asynchronous execution
+     * @return this CompletableFuture
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public CompletableFuture<T> completeAsync(Supplier<? extends T> supplier,
+                                              Executor executor) {
+        if (supplier == null || executor == null)
+            throw new NullPointerException();
+        executor.execute(new AsyncSupply<T>(this, supplier));
+        return this;
+    }
+
+    /**
+     * Completes this CompletableFuture with the result of the given
+     * Supplier function invoked from an asynchronous task using the
+     * default executor.
+     *
+     * @param supplier a function returning the value to be used
+     * to complete this CompletableFuture
+     * @return this CompletableFuture
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public CompletableFuture<T> completeAsync(Supplier<? extends T> supplier) {
+        return completeAsync(supplier, defaultExecutor());
+    }
+
+    /**
+     * Exceptionally completes this CompletableFuture with
+     * a {@link TimeoutException} if not otherwise completed
+     * before the given timeout.
+     *
+     * @param timeout how long to wait before completing exceptionally
+     *        with a TimeoutException, in units of {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code timeout} parameter
+     * @return this CompletableFuture
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public CompletableFuture<T> orTimeout(long timeout, TimeUnit unit) {
+        if (unit == null)
+            throw new NullPointerException();
+        if (result == null)
+            whenComplete(new Canceller(Delayer.delay(new Timeout(this),
+                                                     timeout, unit)));
+        return this;
+    }
+
+    /**
+     * Completes this CompletableFuture with the given value if not
+     * otherwise completed before the given timeout.
+     *
+     * @param value the value to use upon timeout
+     * @param timeout how long to wait before completing normally
+     *        with the given value, in units of {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code timeout} parameter
+     * @return this CompletableFuture
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public CompletableFuture<T> completeOnTimeout(T value, long timeout,
+                                                  TimeUnit unit) {
+        if (unit == null)
+            throw new NullPointerException();
+        if (result == null)
+            whenComplete(new Canceller(Delayer.delay(
+                                           new DelayedCompleter<T>(this, value),
+                                           timeout, unit)));
+        return this;
+    }
+
+    /**
+     * Returns a new Executor that submits a task to the given base
+     * executor after the given delay (or no delay if non-positive).
+     * Each delay commences upon invocation of the returned executor's
+     * {@code execute} method.
+     *
+     * @param delay how long to delay, in units of {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code delay} parameter
+     * @param executor the base executor
+     * @return the new delayed executor
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public static Executor delayedExecutor(long delay, TimeUnit unit,
+                                           Executor executor) {
+        if (unit == null || executor == null)
+            throw new NullPointerException();
+        return new DelayedExecutor(delay, unit, executor);
+    }
+
+    /**
+     * Returns a new Executor that submits a task to the default
+     * executor after the given delay (or no delay if non-positive).
+     * Each delay commences upon invocation of the returned executor's
+     * {@code execute} method.
+     *
+     * @param delay how long to delay, in units of {@code unit}
+     * @param unit a {@code TimeUnit} determining how to interpret the
+     *        {@code delay} parameter
+     * @return the new delayed executor
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public static Executor delayedExecutor(long delay, TimeUnit unit) {
+        if (unit == null)
+            throw new NullPointerException();
+        return new DelayedExecutor(delay, unit, ASYNC_POOL);
+    }
+
+    /**
+     * Returns a new CompletionStage that is already completed with
+     * the given value and supports only those methods in
+     * interface {@link CompletionStage}.
+     *
+     * @param value the value
+     * @param <U> the type of the value
+     * @return the completed CompletionStage
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public static <U> CompletionStage<U> completedStage(U value) {
+        return new MinimalStage<U>((value == null) ? NIL : value);
+    }
+
+    /**
+     * Returns a new CompletableFuture that is already completed
+     * exceptionally with the given exception.
+     *
+     * @param ex the exception
+     * @param <U> the type of the value
+     * @return the exceptionally completed CompletableFuture
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public static <U> CompletableFuture<U> failedFuture(Throwable ex) {
+        if (ex == null) throw new NullPointerException();
+        return new CompletableFuture<U>(new AltResult(ex));
+    }
+
+    /**
+     * Returns a new CompletionStage that is already completed
+     * exceptionally with the given exception and supports only those
+     * methods in interface {@link CompletionStage}.
+     *
+     * @param ex the exception
+     * @param <U> the type of the value
+     * @return the exceptionally completed CompletionStage
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    public static <U> CompletionStage<U> failedStage(Throwable ex) {
+        if (ex == null) throw new NullPointerException();
+        return new MinimalStage<U>(new AltResult(ex));
+    }
+
+    /**
+     * Singleton delay scheduler, used only for starting and
+     * cancelling tasks.
+     */
+    static final class Delayer {
+        static ScheduledFuture<?> delay(Runnable command, long delay,
+                                        TimeUnit unit) {
+            return delayer.schedule(command, delay, unit);
+        }
+
+        static final class DaemonThreadFactory implements ThreadFactory {
+            public Thread newThread(Runnable r) {
+                Thread t = new Thread(r);
+                t.setDaemon(true);
+                t.setName("CompletableFutureDelayScheduler");
+                return t;
+            }
+        }
+
+        static final ScheduledThreadPoolExecutor delayer;
+        static {
+            (delayer = new ScheduledThreadPoolExecutor(
+                1, new DaemonThreadFactory())).
+                setRemoveOnCancelPolicy(true);
+        }
+    }
+
+    // Little class-ified lambdas to better support monitoring
+
+    static final class DelayedExecutor implements Executor {
+        final long delay;
+        final TimeUnit unit;
+        final Executor executor;
+        DelayedExecutor(long delay, TimeUnit unit, Executor executor) {
+            this.delay = delay; this.unit = unit; this.executor = executor;
+        }
+        public void execute(Runnable r) {
+            Delayer.delay(new TaskSubmitter(executor, r), delay, unit);
+        }
+    }
+
+    /** Action to submit user task */
+    static final class TaskSubmitter implements Runnable {
+        final Executor executor;
+        final Runnable action;
+        TaskSubmitter(Executor executor, Runnable action) {
+            this.executor = executor;
+            this.action = action;
+        }
+        public void run() { executor.execute(action); }
+    }
+
+    /** Action to completeExceptionally on timeout */
+    static final class Timeout implements Runnable {
+        final CompletableFuture<?> f;
+        Timeout(CompletableFuture<?> f) { this.f = f; }
+        public void run() {
+            if (f != null && !f.isDone())
+                f.completeExceptionally(new TimeoutException());
+        }
+    }
+
+    /** Action to complete on timeout */
+    static final class DelayedCompleter<U> implements Runnable {
+        final CompletableFuture<U> f;
+        final U u;
+        DelayedCompleter(CompletableFuture<U> f, U u) { this.f = f; this.u = u; }
+        public void run() {
+            if (f != null)
+                f.complete(u);
+        }
+    }
+
+    /** Action to cancel unneeded timeouts */
+    static final class Canceller implements BiConsumer<Object, Throwable> {
+        final Future<?> f;
+        Canceller(Future<?> f) { this.f = f; }
+        public void accept(Object ignore, Throwable ex) {
+            if (ex == null && f != null && !f.isDone())
+                f.cancel(false);
+        }
+    }
+
+    /**
+     * A subclass that just throws UOE for most non-CompletionStage methods.
+     */
+    static final class MinimalStage<T> extends CompletableFuture<T> {
+        MinimalStage() { }
+        MinimalStage(Object r) { super(r); }
+        @Override public <U> CompletableFuture<U> newIncompleteFuture() {
+            return new MinimalStage<U>(); }
+        @Override public T get() {
+            throw new UnsupportedOperationException(); }
+        @Override public T get(long timeout, TimeUnit unit) {
+            throw new UnsupportedOperationException(); }
+        @Override public T getNow(T valueIfAbsent) {
+            throw new UnsupportedOperationException(); }
+        @Override public T join() {
+            throw new UnsupportedOperationException(); }
+        @Override public boolean complete(T value) {
+            throw new UnsupportedOperationException(); }
+        @Override public boolean completeExceptionally(Throwable ex) {
+            throw new UnsupportedOperationException(); }
+        @Override public boolean cancel(boolean mayInterruptIfRunning) {
+            throw new UnsupportedOperationException(); }
+        @Override public void obtrudeValue(T value) {
+            throw new UnsupportedOperationException(); }
+        @Override public void obtrudeException(Throwable ex) {
+            throw new UnsupportedOperationException(); }
+        @Override public boolean isDone() {
+            throw new UnsupportedOperationException(); }
+        @Override public boolean isCancelled() {
+            throw new UnsupportedOperationException(); }
+        @Override public boolean isCompletedExceptionally() {
+            throw new UnsupportedOperationException(); }
+        @Override public int getNumberOfDependents() {
+            throw new UnsupportedOperationException(); }
+        @Override public CompletableFuture<T> completeAsync
+            (Supplier<? extends T> supplier, Executor executor) {
+            throw new UnsupportedOperationException(); }
+        @Override public CompletableFuture<T> completeAsync
+            (Supplier<? extends T> supplier) {
+            throw new UnsupportedOperationException(); }
+        @Override public CompletableFuture<T> orTimeout
+            (long timeout, TimeUnit unit) {
+            throw new UnsupportedOperationException(); }
+        @Override public CompletableFuture<T> completeOnTimeout
+            (T value, long timeout, TimeUnit unit) {
+            throw new UnsupportedOperationException(); }
+    }
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long RESULT;
+    private static final long STACK;
+    private static final long NEXT;
+    static {
+        try {
+            RESULT = U.objectFieldOffset
+                (CompletableFuture.class.getDeclaredField("result"));
+            STACK = U.objectFieldOffset
+                (CompletableFuture.class.getDeclaredField("stack"));
+            NEXT = U.objectFieldOffset
+                (Completion.class.getDeclaredField("next"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+
+        // Reduce the risk of rare disastrous classloading in first call to
+        // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
+        Class<?> ensureLoaded = LockSupport.class;
+    }
+}
diff --git a/luni/src/main/java/java/util/concurrent/CompletionException.java b/luni/src/main/java/java/util/concurrent/CompletionException.java
new file mode 100644
index 0000000..9b905d2
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/CompletionException.java
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+/**
+ * Exception thrown when an error or other exception is encountered
+ * in the course of completing a result or task.
+ *
+ * @since 1.8
+ * @author Doug Lea
+ */
+public class CompletionException extends RuntimeException {
+    private static final long serialVersionUID = 7830266012832686185L;
+
+    /**
+     * Constructs a {@code CompletionException} with no detail message.
+     * The cause is not initialized, and may subsequently be
+     * initialized by a call to {@link #initCause(Throwable) initCause}.
+     */
+    protected CompletionException() { }
+
+    /**
+     * Constructs a {@code CompletionException} with the specified detail
+     * message. The cause is not initialized, and may subsequently be
+     * initialized by a call to {@link #initCause(Throwable) initCause}.
+     *
+     * @param message the detail message
+     */
+    protected CompletionException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a {@code CompletionException} with the specified detail
+     * message and cause.
+     *
+     * @param  message the detail message
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method)
+     */
+    public CompletionException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a {@code CompletionException} with the specified cause.
+     * The detail message is set to {@code (cause == null ? null :
+     * cause.toString())} (which typically contains the class and
+     * detail message of {@code cause}).
+     *
+     * @param  cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method)
+     */
+    public CompletionException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/luni/src/main/java/java/util/concurrent/CompletionStage.java b/luni/src/main/java/java/util/concurrent/CompletionStage.java
new file mode 100644
index 0000000..ccb1aa4
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/CompletionStage.java
@@ -0,0 +1,840 @@
+/*
+ * 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.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * 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:
+ * <pre> {@code
+ * stage.thenApply(x -> square(x))
+ *      .thenAccept(x -> System.out.print(x))
+ *      .thenRun(() -> System.out.println());}</pre>
+ *
+ * An additional form (<em>compose</em>) allows the construction of
+ * computation pipelines from functions returning completion stages.
+ *
+ * <p>Any argument to a stage's computation is the outcome of a
+ * triggering stage's computation.
+ *
+ * <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>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 ({@link #handle handle} and {@link
+ * #whenComplete whenComplete}) support unconditional computation
+ * whether the triggering stage completed normally or exceptionally.
+ * Method {@link #exceptionally exceptionally} supports computation
+ * only when the triggering stage completes exceptionally, computing a
+ * replacement result, similarly to the java {@code catch} keyword.
+ * 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 completes exceptionally with this
+ * exception unless the source stage also completed exceptionally, in
+ * which case the exceptional completion from the source stage is
+ * given preference and propagated to the dependent stage.
+ *
+ * </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>Method form {@link #handle handle} is the most general way of
+ * creating a continuation stage, unconditionally performing a
+ * computation that is given both the result and exception (if any) of
+ * the triggering CompletionStage, and computing an arbitrary result.
+ * Method {@link #whenComplete whenComplete} is similar, but preserves
+ * the result of the triggering stage instead of computing a new one.
+ * Because a stage's normal result may be {@code null}, both methods
+ * should have a computation structured thus:
+ *
+ * <pre>{@code (result, exception) -> {
+ *   if (exception == null) {
+ *     // triggering stage completed normally
+ *   } else {
+ *     // triggering stage completed exceptionally
+ *   }
+ * }}</pre>
+ *
+ * <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.
+     *
+     * <p>This method is analogous to
+     * {@link java.util.Optional#map Optional.map} and
+     * TODO(streams): make a link to java.util.stream.Stream#map Stream.map.
+     *
+     * <p>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 both 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 both 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 both complete normally, is executed using this
+     * stage's default asynchronous execution facility, 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> thenAcceptBothAsync
+        (CompletionStage<? extends U> other,
+         BiConsumer<? super T, ? super U> action);
+
+    /**
+     * Returns a new CompletionStage that, when this and the other
+     * given stage both complete normally, is executed using the
+     * supplied executor, 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 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 both 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 both 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 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 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 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> runAfterEitherAsync
+        (CompletionStage<?> other,
+         Runnable action,
+         Executor executor);
+
+    /**
+     * Returns a new CompletionStage that is completed with the same
+     * value as the CompletionStage returned by the given function.
+     *
+     * <p>When this stage completes normally, the given function is
+     * invoked with this stage's result as the argument, returning
+     * another CompletionStage.  When that stage completes normally,
+     * the CompletionStage returned by this method is completed with
+     * the same value.
+     *
+     * <p>To ensure progress, the supplied function must arrange
+     * eventual completion of its result.
+     *
+     * <p>This method is analogous to
+     * {@link java.util.Optional#flatMap Optional.flatMap} and
+     * TODO(streams): make a link to java.util.stream.Stream#flatMap Stream.flatMap.
+     *
+     * <p>See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param fn the function to use to compute another CompletionStage
+     * @param <U> the type of the returned CompletionStage's result
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> thenCompose
+        (Function<? super T, ? extends CompletionStage<U>> fn);
+
+    /**
+     * Returns a new CompletionStage that is completed with the same
+     * value as the CompletionStage returned by the given function,
+     * executed using this stage's default asynchronous execution
+     * facility.
+     *
+     * <p>When this stage completes normally, the given function is
+     * invoked with this stage's result as the argument, returning
+     * another CompletionStage.  When that stage completes normally,
+     * the CompletionStage returned by this method is completed with
+     * the same value.
+     *
+     * <p>To ensure progress, the supplied function must arrange
+     * eventual completion of its result.
+     *
+     * <p>See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param fn the function to use to compute another CompletionStage
+     * @param <U> the type of the returned CompletionStage's result
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> thenComposeAsync
+        (Function<? super T, ? extends CompletionStage<U>> fn);
+
+    /**
+     * Returns a new CompletionStage that is completed with the same
+     * value as the CompletionStage returned by the given function,
+     * executed using the supplied Executor.
+     *
+     * <p>When this stage completes normally, the given function is
+     * invoked with this stage's result as the argument, returning
+     * another CompletionStage.  When that stage completes normally,
+     * the CompletionStage returned by this method is completed with
+     * the same value.
+     *
+     * <p>To ensure progress, the supplied function must arrange
+     * eventual completion of its result.
+     *
+     * <p>See the {@link CompletionStage} documentation for rules
+     * covering exceptional completion.
+     *
+     * @param fn the function to use to compute another CompletionStage
+     * @param executor the executor to use for asynchronous execution
+     * @param <U> the type of the returned CompletionStage's result
+     * @return the new CompletionStage
+     */
+    public <U> CompletionStage<U> thenComposeAsync
+        (Function<? super T, ? extends CompletionStage<U>> fn,
+         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.
+     *
+     * <p>When this stage is complete, the given function is invoked
+     * with the result (or {@code null} if none) and the exception (or
+     * {@code null} if none) of this stage as arguments, and the
+     * function's result is used to complete the returned stage.
+     *
+     * @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.
+     *
+     * <p>When this stage is complete, the given function is invoked
+     * with the result (or {@code null} if none) and the exception (or
+     * {@code null} if none) of this stage as arguments, and the
+     * function's result is used to complete the returned stage.
+     *
+     * @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.
+     *
+     * <p>When this stage is complete, the given function is invoked
+     * with the result (or {@code null} if none) and the exception (or
+     * {@code null} if none) of this stage as arguments, and the
+     * function's result is used to complete the returned stage.
+     *
+     * @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 new CompletionStage with the same result or exception as
+     * this stage, that executes the given action when this stage completes.
+     *
+     * <p>When this stage is complete, the given action is invoked
+     * with the result (or {@code null} if none) and the exception (or
+     * {@code null} if none) of this stage as arguments.  The returned
+     * stage is completed when the action returns.
+     *
+     * <p>Unlike method {@link #handle handle},
+     * this method is not designed to translate completion outcomes,
+     * so the supplied action should not throw an exception. However,
+     * if it does, the following rules apply: if this stage completed
+     * normally but the supplied action throws an exception, then the
+     * returned stage completes exceptionally with the supplied
+     * action's exception. Or, if this stage completed exceptionally
+     * and the supplied action throws an exception, then the returned
+     * stage completes exceptionally with this stage's exception.
+     *
+     * @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, that executes the given action using this stage's
+     * default asynchronous execution facility when this stage completes.
+     *
+     * <p>When this stage is complete, the given action is invoked with the
+     * result (or {@code null} if none) and the exception (or {@code null}
+     * if none) of this stage as arguments.  The returned stage is completed
+     * when the action returns.
+     *
+     * <p>Unlike method {@link #handleAsync(BiFunction) handleAsync},
+     * this method is not designed to translate completion outcomes,
+     * so the supplied action should not throw an exception. However,
+     * if it does, the following rules apply: If this stage completed
+     * normally but the supplied action throws an exception, then the
+     * returned stage completes exceptionally with the supplied
+     * action's exception. Or, if this stage completed exceptionally
+     * and the supplied action throws an exception, then the returned
+     * stage completes exceptionally with this stage's exception.
+     *
+     * @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, that executes the given action using the supplied
+     * Executor when this stage completes.
+     *
+     * <p>When this stage is complete, the given action is invoked with the
+     * result (or {@code null} if none) and the exception (or {@code null}
+     * if none) of this stage as arguments.  The returned stage is completed
+     * when the action returns.
+     *
+     * <p>Unlike method {@link #handleAsync(BiFunction,Executor) handleAsync},
+     * this method is not designed to translate completion outcomes,
+     * so the supplied action should not throw an exception. However,
+     * if it does, the following rules apply: If this stage completed
+     * normally but the supplied action throws an exception, then the
+     * returned stage completes exceptionally with the supplied
+     * action's exception. Or, if this stage completed exceptionally
+     * and the supplied action throws an exception, then the returned
+     * stage completes exceptionally with this stage's exception.
+     *
+     * @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
+     * 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 {@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();
+
+}
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
index 3ed54cf..b4fa8aa 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java
@@ -13,7 +13,6 @@
 import java.util.AbstractMap;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.ConcurrentModificationException;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -21,14 +20,29 @@
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.Spliterator;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.LockSupport;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.Function;
+import java.util.function.IntBinaryOperator;
+import java.util.function.LongBinaryOperator;
+import java.util.function.Predicate;
+import java.util.function.ToDoubleBiFunction;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntBiFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongBiFunction;
+import java.util.function.ToLongFunction;
+// TODO(streams):
+//import java.util.stream.Stream;
 
 // BEGIN android-note
 // removed link to collections framework docs
-// removed links to hidden api
 // END android-note
 
 /**
@@ -52,14 +66,14 @@
  * that key reporting the updated value.)  For aggregate operations
  * such as {@code putAll} and {@code clear}, concurrent retrievals may
  * reflect insertion or removal of only some entries.  Similarly,
- * Iterators and Enumerations return elements reflecting the state of
- * the hash table at some point at or since the creation of the
+ * Iterators, Spliterators and Enumerations return elements reflecting the
+ * state of the hash table at some point at or since the creation of the
  * iterator/enumeration.  They do <em>not</em> throw {@link
- * ConcurrentModificationException}.  However, iterators are designed
- * to be used by only one thread at a time.  Bear in mind that the
- * results of aggregate status methods including {@code size}, {@code
- * isEmpty}, and {@code containsValue} are typically useful only when
- * a map is not undergoing concurrent updates in other threads.
+ * java.util.ConcurrentModificationException ConcurrentModificationException}.
+ * However, iterators are designed to be used by only one thread at a time.
+ * Bear in mind that the results of aggregate status methods including
+ * {@code size}, {@code isEmpty}, and {@code containsValue} are typically
+ * useful only when a map is not undergoing concurrent updates in other threads.
  * Otherwise the results of these methods reflect transient states
  * that may be adequate for monitoring or estimation purposes, but not
  * for program control.
@@ -86,6 +100,19 @@
  * hash table. To ameliorate impact, when keys are {@link Comparable},
  * this class may use comparison order among keys to help break ties.
  *
+ * <p>A {@link Set} projection of a ConcurrentHashMap may be created
+ * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed
+ * (using {@link #keySet(Object)} when only keys are of interest, and the
+ * mapped values are (perhaps transiently) not used or all take the
+ * same mapping value.
+ *
+ * <p>A ConcurrentHashMap can be used as a scalable frequency map (a
+ * form of histogram or multiset) by using {@link
+ * java.util.concurrent.atomic.LongAdder} values and initializing via
+ * {@link #computeIfAbsent computeIfAbsent}. For example, to add a count
+ * to a {@code ConcurrentHashMap<String,LongAdder> freqs}, you can use
+ * {@code freqs.computeIfAbsent(key, k -> new LongAdder()).increment();}
+ *
  * <p>This class and its views and iterators implement all of the
  * <em>optional</em> methods of the {@link Map} and {@link Iterator}
  * interfaces.
@@ -93,15 +120,121 @@
  * <p>Like {@link Hashtable} but unlike {@link HashMap}, this class
  * does <em>not</em> allow {@code null} to be used as a key or value.
  *
+ * <p>ConcurrentHashMaps support a set of sequential and parallel bulk
+ * operations that, unlike most (TODO(streams): link to Stream) methods, are designed
+ * to be safely, and often sensibly, applied even with maps that are
+ * being concurrently updated by other threads; for example, when
+ * computing a snapshot summary of the values in a shared registry.
+ * There are three kinds of operation, each with four forms, accepting
+ * functions with keys, values, entries, and (key, value) pairs as
+ * arguments and/or return values. Because the elements of a
+ * ConcurrentHashMap are not ordered in any particular way, and may be
+ * processed in different orders in different parallel executions, the
+ * correctness of supplied functions should not depend on any
+ * ordering, or on any other objects or values that may transiently
+ * change while computation is in progress; and except for forEach
+ * actions, should ideally be side-effect-free. Bulk operations on
+ * {@link java.util.Map.Entry} objects do not support method {@code
+ * setValue}.
+ *
+ * <ul>
+ * <li>forEach: Performs a given action on each element.
+ * A variant form applies a given transformation on each element
+ * before performing the action.
+ *
+ * <li>search: Returns the first available non-null result of
+ * applying a given function on each element; skipping further
+ * search when a result is found.
+ *
+ * <li>reduce: Accumulates each element.  The supplied reduction
+ * function cannot rely on ordering (more formally, it should be
+ * both associative and commutative).  There are five variants:
+ *
+ * <ul>
+ *
+ * <li>Plain reductions. (There is not a form of this method for
+ * (key, value) function arguments since there is no corresponding
+ * return type.)
+ *
+ * <li>Mapped reductions that accumulate the results of a given
+ * function applied to each element.
+ *
+ * <li>Reductions to scalar doubles, longs, and ints, using a
+ * given basis value.
+ *
+ * </ul>
+ * </ul>
+ *
+ * <p>These bulk operations accept a {@code parallelismThreshold}
+ * argument. Methods proceed sequentially if the current map size is
+ * estimated to be less than the given threshold. Using a value of
+ * {@code Long.MAX_VALUE} suppresses all parallelism.  Using a value
+ * of {@code 1} results in maximal parallelism by partitioning into
+ * enough subtasks to fully utilize the {@link
+ * ForkJoinPool#commonPool()} that is used for all parallel
+ * computations. Normally, you would initially choose one of these
+ * extreme values, and then measure performance of using in-between
+ * values that trade off overhead versus throughput.
+ *
+ * <p>The concurrency properties of bulk operations follow
+ * from those of ConcurrentHashMap: Any non-null result returned
+ * from {@code get(key)} and related access methods bears a
+ * happens-before relation with the associated insertion or
+ * update.  The result of any bulk operation reflects the
+ * composition of these per-element relations (but is not
+ * necessarily atomic with respect to the map as a whole unless it
+ * is somehow known to be quiescent).  Conversely, because keys
+ * and values in the map are never null, null serves as a reliable
+ * atomic indicator of the current lack of any result.  To
+ * maintain this property, null serves as an implicit basis for
+ * all non-scalar reduction operations. For the double, long, and
+ * int versions, the basis should be one that, when combined with
+ * any other value, returns that other value (more formally, it
+ * should be the identity element for the reduction). Most common
+ * reductions have these properties; for example, computing a sum
+ * with basis 0 or a minimum with basis MAX_VALUE.
+ *
+ * <p>Search and transformation functions provided as arguments
+ * should similarly return null to indicate the lack of any result
+ * (in which case it is not used). In the case of mapped
+ * reductions, this also enables transformations to serve as
+ * filters, returning null (or, in the case of primitive
+ * specializations, the identity basis) if the element should not
+ * be combined. You can create compound transformations and
+ * filterings by composing them yourself under this "null means
+ * there is nothing there now" rule before using them in search or
+ * reduce operations.
+ *
+ * <p>Methods accepting and/or returning Entry arguments maintain
+ * key-value associations. They may be useful for example when
+ * finding the key for the greatest value. Note that "plain" Entry
+ * arguments can be supplied using {@code new
+ * AbstractMap.SimpleEntry(k,v)}.
+ *
+ * <p>Bulk operations may complete abruptly, throwing an
+ * exception encountered in the application of a supplied
+ * function. Bear in mind when handling such exceptions that other
+ * concurrently executing functions could also have thrown
+ * exceptions, or would have done so if the first exception had
+ * not occurred.
+ *
+ * <p>Speedups for parallel compared to sequential forms are common
+ * but not guaranteed.  Parallel operations involving brief functions
+ * on small maps may execute more slowly than sequential forms if the
+ * underlying work to parallelize the computation is more expensive
+ * than the computation itself.  Similarly, parallelization may not
+ * lead to much actual parallelism if all processors are busy
+ * performing unrelated tasks.
+ *
+ * <p>All arguments to all task methods must be non-null.
+ *
  * @since 1.5
  * @author Doug Lea
  * @param <K> the type of keys maintained by this map
  * @param <V> the type of mapped values
  */
-// android-note: removed documentation about hidden newKeySet and newKeySet(int) APIs.
-// android-note: Added "extends AbstractMap<K, V>.
-public class ConcurrentHashMap<K,V> extends AbstractMap<K, V>
-        implements ConcurrentMap<K,V>, Serializable {
+public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
+    implements ConcurrentMap<K,V>, Serializable {
     private static final long serialVersionUID = 7249069246763182397L;
 
     /*
@@ -316,7 +449,7 @@
      *
      * Maintaining API and serialization compatibility with previous
      * versions of this class introduces several oddities. Mainly: We
-     * leave untouched but unused constructor arguments refering to
+     * leave untouched but unused constructor arguments referring to
      * concurrencyLevel. We accept a loadFactor constructor argument,
      * but apply it only to initial table capacity (which is the only
      * time that we can guarantee to honor it.) We also declare an
@@ -335,7 +468,6 @@
      * bulk operations.
      */
 
-
     /* ---------------- Constants -------------- */
 
     /**
@@ -412,7 +544,7 @@
      * The number of bits used for generation stamp in sizeCtl.
      * Must be at least 6 for 32bit arrays.
      */
-    private static int RESIZE_STAMP_BITS = 16;
+    private static final int RESIZE_STAMP_BITS = 16;
 
     /**
      * The maximum number of threads that can help resize.
@@ -428,19 +560,28 @@
     /*
      * Encodings for Node hash fields. See above for explanation.
      */
-    static final int MOVED     = 0x8fffffff; // (-1) hash for forwarding nodes
-    static final int TREEBIN   = 0x80000000; // hash for roots of trees
-    static final int RESERVED  = 0x80000001; // hash for transient reservations
+    static final int MOVED     = -1; // hash for forwarding nodes
+    static final int TREEBIN   = -2; // hash for roots of trees
+    static final int RESERVED  = -3; // hash for transient reservations
     static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash
 
     /** Number of CPUS, to place bounds on some sizings */
     static final int NCPU = Runtime.getRuntime().availableProcessors();
 
-    /** For serialization compatibility. */
+    /**
+     * Serialized pseudo-fields, provided only for jdk7 compatibility.
+     * @serialField segments Segment[]
+     *   The segments, each of which is a specialized hash table.
+     * @serialField segmentMask int
+     *   Mask value for indexing into segments. The upper bits of a
+     *   key's hash code are used to choose the segment.
+     * @serialField segmentShift int
+     *   Shift value for indexing within segments.
+     */
     private static final ObjectStreamField[] serialPersistentFields = {
         new ObjectStreamField("segments", Segment[].class),
         new ObjectStreamField("segmentMask", Integer.TYPE),
-        new ObjectStreamField("segmentShift", Integer.TYPE)
+        new ObjectStreamField("segmentShift", Integer.TYPE),
     };
 
     /* ---------------- Nodes -------------- */
@@ -457,7 +598,7 @@
         final int hash;
         final K key;
         volatile V val;
-        Node<K,V> next;
+        volatile Node<K,V> next;
 
         Node(int hash, K key, V val, Node<K,V> next) {
             this.hash = hash;
@@ -466,10 +607,12 @@
             this.next = next;
         }
 
-        public final K getKey()       { return key; }
-        public final V getValue()     { return val; }
-        public final int hashCode()   { return key.hashCode() ^ val.hashCode(); }
-        public final String toString(){ return key + "=" + val; }
+        public final K getKey()     { return key; }
+        public final V getValue()   { return val; }
+        public final int hashCode() { return key.hashCode() ^ val.hashCode(); }
+        public final String toString() {
+            return Helpers.mapEntryToString(key, val);
+        }
         public final V setValue(V value) {
             throw new UnsupportedOperationException();
         }
@@ -582,8 +725,9 @@
      * errors by users, these checks must operate on local variables,
      * which accounts for some odd-looking inline assignments below.
      * Note that calls to setTabAt always occur within locked regions,
-     * and so do not need full volatile semantics, but still require
-     * ordering to maintain concurrent readability.
+     * and so in principle require only release ordering, not
+     * full volatile semantics, but are currently coded as volatile
+     * writes to be conservative.
      */
 
     @SuppressWarnings("unchecked")
@@ -597,7 +741,7 @@
     }
 
     static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) {
-        U.putOrderedObject(tab, ((long)i << ASHIFT) + ABASE, v);
+        U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
     }
 
     /* ---------------- Fields -------------- */
@@ -892,6 +1036,8 @@
                                     p.val = value;
                             }
                         }
+                        else if (f instanceof ReservationNode)
+                            throw new IllegalStateException("Recursive update");
                     }
                 }
                 if (binCount != 0) {
@@ -994,6 +1140,8 @@
                                 }
                             }
                         }
+                        else if (f instanceof ReservationNode)
+                            throw new IllegalStateException("Recursive update");
                     }
                 }
                 if (validated) {
@@ -1054,16 +1202,15 @@
      * operations.  It does not support the {@code add} or
      * {@code addAll} operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's iterators and spliterators are
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}.
      *
      * @return the set view
      */
-    // android-note : changed KeySetView<K,V> to Set<K> to maintain API compatibility.
-    public Set<K> keySet() {
+    public KeySetView<K,V> keySet() {
         KeySetView<K,V> ks;
         return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null));
     }
@@ -1078,11 +1225,11 @@
      * {@code retainAll}, and {@code clear} operations.  It does not
      * support the {@code add} or {@code addAll} operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's iterators and spliterators are
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT}
+     * and {@link Spliterator#NONNULL}.
      *
      * @return the collection view
      */
@@ -1100,11 +1247,11 @@
      * {@code removeAll}, {@code retainAll}, and {@code clear}
      * operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's iterators and spliterators are
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}.
      *
      * @return the set view
      */
@@ -1202,7 +1349,7 @@
 
     /**
      * Stripped-down version of helper class used in previous version,
-     * declared for the sake of serialization compatibility
+     * declared for the sake of serialization compatibility.
      */
     static class Segment<K,V> extends ReentrantLock implements Serializable {
         private static final long serialVersionUID = 2249069246763182397L;
@@ -1214,9 +1361,10 @@
      * Saves the state of the {@code ConcurrentHashMap} instance to a
      * stream (i.e., serializes it).
      * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData
-     * the key (Object) and value (Object)
-     * for each key-value mapping, followed by a null pair.
+     * the serialized fields, followed by the key (Object) and value
+     * (Object) for each key-value mapping, followed by a null pair.
      * The key-value mappings are emitted in no particular order.
      */
     private void writeObject(java.io.ObjectOutputStream s)
@@ -1231,7 +1379,8 @@
         }
         int segmentShift = 32 - sshift;
         int segmentMask = ssize - 1;
-        @SuppressWarnings("unchecked") Segment<K,V>[] segments = (Segment<K,V>[])
+        @SuppressWarnings("unchecked")
+        Segment<K,V>[] segments = (Segment<K,V>[])
             new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
         for (int i = 0; i < segments.length; ++i)
             segments[i] = new Segment<K,V>(LOAD_FACTOR);
@@ -1251,12 +1400,14 @@
         }
         s.writeObject(null);
         s.writeObject(null);
-        segments = null; // throw away
     }
 
     /**
      * Reconstitutes the instance from a stream (that is, deserializes it).
      * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
@@ -1272,8 +1423,10 @@
         long size = 0L;
         Node<K,V> p = null;
         for (;;) {
-            @SuppressWarnings("unchecked") K k = (K) s.readObject();
-            @SuppressWarnings("unchecked") V v = (V) s.readObject();
+            @SuppressWarnings("unchecked")
+            K k = (K) s.readObject();
+            @SuppressWarnings("unchecked")
+            V v = (V) s.readObject();
             if (k != null && v != null) {
                 p = new Node<K,V>(spread(k.hashCode()), k, v, p);
                 ++size;
@@ -1292,7 +1445,7 @@
                 n = tableSizeFor(sz + (sz >>> 1) + 1);
             }
             @SuppressWarnings("unchecked")
-                Node<K,V>[] tab = (Node<K,V>[])new Node<?,?>[n];
+            Node<K,V>[] tab = (Node<K,V>[])new Node<?,?>[n];
             int mask = n - 1;
             long added = 0L;
             while (p != null) {
@@ -1400,17 +1553,544 @@
             throw new NullPointerException();
         return replaceNode(key, value, null);
     }
+
+    // Overrides of JDK8+ Map extension method defaults
+
+    /**
+     * Returns the value to which the specified key is mapped, or the
+     * given default value if this map contains no mapping for the
+     * key.
+     *
+     * @param key the key whose associated value is to be returned
+     * @param defaultValue the value to return if this map contains
+     * no mapping for the given key
+     * @return the mapping for the key, if present; else the default value
+     * @throws NullPointerException if the specified key is null
+     */
+    public V getOrDefault(Object key, V defaultValue) {
+        V v;
+        return (v = get(key)) == null ? defaultValue : v;
+    }
+
+    public void forEach(BiConsumer<? super K, ? super V> action) {
+        if (action == null) throw new NullPointerException();
+        Node<K,V>[] t;
+        if ((t = table) != null) {
+            Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+            for (Node<K,V> p; (p = it.advance()) != null; ) {
+                action.accept(p.key, p.val);
+            }
+        }
+    }
+
+    public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
+        if (function == null) throw new NullPointerException();
+        Node<K,V>[] t;
+        if ((t = table) != null) {
+            Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+            for (Node<K,V> p; (p = it.advance()) != null; ) {
+                V oldValue = p.val;
+                for (K key = p.key;;) {
+                    V newValue = function.apply(key, oldValue);
+                    if (newValue == null)
+                        throw new NullPointerException();
+                    if (replaceNode(key, newValue, oldValue) != null ||
+                        (oldValue = get(key)) == null)
+                        break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Helper method for EntrySetView.removeIf.
+     */
+    boolean removeEntryIf(Predicate<? super Entry<K,V>> function) {
+        if (function == null) throw new NullPointerException();
+        Node<K,V>[] t;
+        boolean removed = false;
+        if ((t = table) != null) {
+            Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+            for (Node<K,V> p; (p = it.advance()) != null; ) {
+                K k = p.key;
+                V v = p.val;
+                Map.Entry<K,V> e = new AbstractMap.SimpleImmutableEntry<>(k, v);
+                if (function.test(e) && replaceNode(k, null, v) != null)
+                    removed = true;
+            }
+        }
+        return removed;
+    }
+
+    /**
+     * Helper method for ValuesView.removeIf.
+     */
+    boolean removeValueIf(Predicate<? super V> function) {
+        if (function == null) throw new NullPointerException();
+        Node<K,V>[] t;
+        boolean removed = false;
+        if ((t = table) != null) {
+            Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+            for (Node<K,V> p; (p = it.advance()) != null; ) {
+                K k = p.key;
+                V v = p.val;
+                if (function.test(v) && replaceNode(k, null, v) != null)
+                    removed = true;
+            }
+        }
+        return removed;
+    }
+
+    /**
+     * If the specified key is not already associated with a value,
+     * attempts to compute its value using the given mapping function
+     * and enters it into this map unless {@code null}.  The entire
+     * method invocation is performed atomically, so the function is
+     * applied at most once per key.  Some attempted update operations
+     * on this map by other threads may be blocked while computation
+     * is in progress, so the computation should be short and simple,
+     * and must not attempt to update any other mappings of this map.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param mappingFunction the function to compute a value
+     * @return the current (existing or computed) value associated with
+     *         the specified key, or null if the computed value is null
+     * @throws NullPointerException if the specified key or mappingFunction
+     *         is null
+     * @throws IllegalStateException if the computation detectably
+     *         attempts a recursive update to this map that would
+     *         otherwise never complete
+     * @throws RuntimeException or Error if the mappingFunction does so,
+     *         in which case the mapping is left unestablished
+     */
+    public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
+        if (key == null || mappingFunction == null)
+            throw new NullPointerException();
+        int h = spread(key.hashCode());
+        V val = null;
+        int binCount = 0;
+        for (Node<K,V>[] tab = table;;) {
+            Node<K,V> f; int n, i, fh;
+            if (tab == null || (n = tab.length) == 0)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
+                Node<K,V> r = new ReservationNode<K,V>();
+                synchronized (r) {
+                    if (casTabAt(tab, i, null, r)) {
+                        binCount = 1;
+                        Node<K,V> node = null;
+                        try {
+                            if ((val = mappingFunction.apply(key)) != null)
+                                node = new Node<K,V>(h, key, val, null);
+                        } finally {
+                            setTabAt(tab, i, node);
+                        }
+                    }
+                }
+                if (binCount != 0)
+                    break;
+            }
+            else if ((fh = f.hash) == MOVED)
+                tab = helpTransfer(tab, f);
+            else {
+                boolean added = false;
+                synchronized (f) {
+                    if (tabAt(tab, i) == f) {
+                        if (fh >= 0) {
+                            binCount = 1;
+                            for (Node<K,V> e = f;; ++binCount) {
+                                K ek;
+                                if (e.hash == h &&
+                                    ((ek = e.key) == key ||
+                                     (ek != null && key.equals(ek)))) {
+                                    val = e.val;
+                                    break;
+                                }
+                                Node<K,V> pred = e;
+                                if ((e = e.next) == null) {
+                                    if ((val = mappingFunction.apply(key)) != null) {
+                                        if (pred.next != null)
+                                            throw new IllegalStateException("Recursive update");
+                                        added = true;
+                                        pred.next = new Node<K,V>(h, key, val, null);
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                        else if (f instanceof TreeBin) {
+                            binCount = 2;
+                            TreeBin<K,V> t = (TreeBin<K,V>)f;
+                            TreeNode<K,V> r, p;
+                            if ((r = t.root) != null &&
+                                (p = r.findTreeNode(h, key, null)) != null)
+                                val = p.val;
+                            else if ((val = mappingFunction.apply(key)) != null) {
+                                added = true;
+                                t.putTreeVal(h, key, val);
+                            }
+                        }
+                        else if (f instanceof ReservationNode)
+                            throw new IllegalStateException("Recursive update");
+                    }
+                }
+                if (binCount != 0) {
+                    if (binCount >= TREEIFY_THRESHOLD)
+                        treeifyBin(tab, i);
+                    if (!added)
+                        return val;
+                    break;
+                }
+            }
+        }
+        if (val != null)
+            addCount(1L, binCount);
+        return val;
+    }
+
+    /**
+     * If the value for the specified key is present, attempts to
+     * compute a new mapping given the key and its current mapped
+     * value.  The entire method invocation is performed atomically.
+     * Some attempted update operations on this map by other threads
+     * may be blocked while computation is in progress, so the
+     * computation should be short and simple, and must not attempt to
+     * update any other mappings of this map.
+     *
+     * @param key key with which a value may be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key or remappingFunction
+     *         is null
+     * @throws IllegalStateException if the computation detectably
+     *         attempts a recursive update to this map that would
+     *         otherwise never complete
+     * @throws RuntimeException or Error if the remappingFunction does so,
+     *         in which case the mapping is unchanged
+     */
+    public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        int h = spread(key.hashCode());
+        V val = null;
+        int delta = 0;
+        int binCount = 0;
+        for (Node<K,V>[] tab = table;;) {
+            Node<K,V> f; int n, i, fh;
+            if (tab == null || (n = tab.length) == 0)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (n - 1) & h)) == null)
+                break;
+            else if ((fh = f.hash) == MOVED)
+                tab = helpTransfer(tab, f);
+            else {
+                synchronized (f) {
+                    if (tabAt(tab, i) == f) {
+                        if (fh >= 0) {
+                            binCount = 1;
+                            for (Node<K,V> e = f, pred = null;; ++binCount) {
+                                K ek;
+                                if (e.hash == h &&
+                                    ((ek = e.key) == key ||
+                                     (ek != null && key.equals(ek)))) {
+                                    val = remappingFunction.apply(key, e.val);
+                                    if (val != null)
+                                        e.val = val;
+                                    else {
+                                        delta = -1;
+                                        Node<K,V> en = e.next;
+                                        if (pred != null)
+                                            pred.next = en;
+                                        else
+                                            setTabAt(tab, i, en);
+                                    }
+                                    break;
+                                }
+                                pred = e;
+                                if ((e = e.next) == null)
+                                    break;
+                            }
+                        }
+                        else if (f instanceof TreeBin) {
+                            binCount = 2;
+                            TreeBin<K,V> t = (TreeBin<K,V>)f;
+                            TreeNode<K,V> r, p;
+                            if ((r = t.root) != null &&
+                                (p = r.findTreeNode(h, key, null)) != null) {
+                                val = remappingFunction.apply(key, p.val);
+                                if (val != null)
+                                    p.val = val;
+                                else {
+                                    delta = -1;
+                                    if (t.removeTreeNode(p))
+                                        setTabAt(tab, i, untreeify(t.first));
+                                }
+                            }
+                        }
+                        else if (f instanceof ReservationNode)
+                            throw new IllegalStateException("Recursive update");
+                    }
+                }
+                if (binCount != 0)
+                    break;
+            }
+        }
+        if (delta != 0)
+            addCount((long)delta, binCount);
+        return val;
+    }
+
+    /**
+     * Attempts to compute a mapping for the specified key and its
+     * current mapped value (or {@code null} if there is no current
+     * mapping). The entire method invocation is performed atomically.
+     * Some attempted update operations on this map by other threads
+     * may be blocked while computation is in progress, so the
+     * computation should be short and simple, and must not attempt to
+     * update any other mappings of this Map.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key or remappingFunction
+     *         is null
+     * @throws IllegalStateException if the computation detectably
+     *         attempts a recursive update to this map that would
+     *         otherwise never complete
+     * @throws RuntimeException or Error if the remappingFunction does so,
+     *         in which case the mapping is unchanged
+     */
+    public V compute(K key,
+                     BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        int h = spread(key.hashCode());
+        V val = null;
+        int delta = 0;
+        int binCount = 0;
+        for (Node<K,V>[] tab = table;;) {
+            Node<K,V> f; int n, i, fh;
+            if (tab == null || (n = tab.length) == 0)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
+                Node<K,V> r = new ReservationNode<K,V>();
+                synchronized (r) {
+                    if (casTabAt(tab, i, null, r)) {
+                        binCount = 1;
+                        Node<K,V> node = null;
+                        try {
+                            if ((val = remappingFunction.apply(key, null)) != null) {
+                                delta = 1;
+                                node = new Node<K,V>(h, key, val, null);
+                            }
+                        } finally {
+                            setTabAt(tab, i, node);
+                        }
+                    }
+                }
+                if (binCount != 0)
+                    break;
+            }
+            else if ((fh = f.hash) == MOVED)
+                tab = helpTransfer(tab, f);
+            else {
+                synchronized (f) {
+                    if (tabAt(tab, i) == f) {
+                        if (fh >= 0) {
+                            binCount = 1;
+                            for (Node<K,V> e = f, pred = null;; ++binCount) {
+                                K ek;
+                                if (e.hash == h &&
+                                    ((ek = e.key) == key ||
+                                     (ek != null && key.equals(ek)))) {
+                                    val = remappingFunction.apply(key, e.val);
+                                    if (val != null)
+                                        e.val = val;
+                                    else {
+                                        delta = -1;
+                                        Node<K,V> en = e.next;
+                                        if (pred != null)
+                                            pred.next = en;
+                                        else
+                                            setTabAt(tab, i, en);
+                                    }
+                                    break;
+                                }
+                                pred = e;
+                                if ((e = e.next) == null) {
+                                    val = remappingFunction.apply(key, null);
+                                    if (val != null) {
+                                        if (pred.next != null)
+                                            throw new IllegalStateException("Recursive update");
+                                        delta = 1;
+                                        pred.next =
+                                            new Node<K,V>(h, key, val, null);
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                        else if (f instanceof TreeBin) {
+                            binCount = 1;
+                            TreeBin<K,V> t = (TreeBin<K,V>)f;
+                            TreeNode<K,V> r, p;
+                            if ((r = t.root) != null)
+                                p = r.findTreeNode(h, key, null);
+                            else
+                                p = null;
+                            V pv = (p == null) ? null : p.val;
+                            val = remappingFunction.apply(key, pv);
+                            if (val != null) {
+                                if (p != null)
+                                    p.val = val;
+                                else {
+                                    delta = 1;
+                                    t.putTreeVal(h, key, val);
+                                }
+                            }
+                            else if (p != null) {
+                                delta = -1;
+                                if (t.removeTreeNode(p))
+                                    setTabAt(tab, i, untreeify(t.first));
+                            }
+                        }
+                        else if (f instanceof ReservationNode)
+                            throw new IllegalStateException("Recursive update");
+                    }
+                }
+                if (binCount != 0) {
+                    if (binCount >= TREEIFY_THRESHOLD)
+                        treeifyBin(tab, i);
+                    break;
+                }
+            }
+        }
+        if (delta != 0)
+            addCount((long)delta, binCount);
+        return val;
+    }
+
+    /**
+     * If the specified key is not already associated with a
+     * (non-null) value, associates it with the given value.
+     * Otherwise, replaces the value with the results of the given
+     * remapping function, or removes if {@code null}. The entire
+     * method invocation is performed atomically.  Some attempted
+     * update operations on this map by other threads may be blocked
+     * while computation is in progress, so the computation should be
+     * short and simple, and must not attempt to update any other
+     * mappings of this Map.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param value the value to use if absent
+     * @param remappingFunction the function to recompute a value if present
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key or the
+     *         remappingFunction is null
+     * @throws RuntimeException or Error if the remappingFunction does so,
+     *         in which case the mapping is unchanged
+     */
+    public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+        if (key == null || value == null || remappingFunction == null)
+            throw new NullPointerException();
+        int h = spread(key.hashCode());
+        V val = null;
+        int delta = 0;
+        int binCount = 0;
+        for (Node<K,V>[] tab = table;;) {
+            Node<K,V> f; int n, i, fh;
+            if (tab == null || (n = tab.length) == 0)
+                tab = initTable();
+            else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
+                if (casTabAt(tab, i, null, new Node<K,V>(h, key, value, null))) {
+                    delta = 1;
+                    val = value;
+                    break;
+                }
+            }
+            else if ((fh = f.hash) == MOVED)
+                tab = helpTransfer(tab, f);
+            else {
+                synchronized (f) {
+                    if (tabAt(tab, i) == f) {
+                        if (fh >= 0) {
+                            binCount = 1;
+                            for (Node<K,V> e = f, pred = null;; ++binCount) {
+                                K ek;
+                                if (e.hash == h &&
+                                    ((ek = e.key) == key ||
+                                     (ek != null && key.equals(ek)))) {
+                                    val = remappingFunction.apply(e.val, value);
+                                    if (val != null)
+                                        e.val = val;
+                                    else {
+                                        delta = -1;
+                                        Node<K,V> en = e.next;
+                                        if (pred != null)
+                                            pred.next = en;
+                                        else
+                                            setTabAt(tab, i, en);
+                                    }
+                                    break;
+                                }
+                                pred = e;
+                                if ((e = e.next) == null) {
+                                    delta = 1;
+                                    val = value;
+                                    pred.next =
+                                        new Node<K,V>(h, key, val, null);
+                                    break;
+                                }
+                            }
+                        }
+                        else if (f instanceof TreeBin) {
+                            binCount = 2;
+                            TreeBin<K,V> t = (TreeBin<K,V>)f;
+                            TreeNode<K,V> r = t.root;
+                            TreeNode<K,V> p = (r == null) ? null :
+                                r.findTreeNode(h, key, null);
+                            val = (p == null) ? value :
+                                remappingFunction.apply(p.val, value);
+                            if (val != null) {
+                                if (p != null)
+                                    p.val = val;
+                                else {
+                                    delta = 1;
+                                    t.putTreeVal(h, key, val);
+                                }
+                            }
+                            else if (p != null) {
+                                delta = -1;
+                                if (t.removeTreeNode(p))
+                                    setTabAt(tab, i, untreeify(t.first));
+                            }
+                        }
+                        else if (f instanceof ReservationNode)
+                            throw new IllegalStateException("Recursive update");
+                    }
+                }
+                if (binCount != 0) {
+                    if (binCount >= TREEIFY_THRESHOLD)
+                        treeifyBin(tab, i);
+                    break;
+                }
+            }
+        }
+        if (delta != 0)
+            addCount((long)delta, binCount);
+        return val;
+    }
+
     // Hashtable legacy methods
 
     /**
-     * Legacy method testing if some key maps into the specified value
-     * in this table.
+     * Tests if some key maps into the specified value in this table.
      *
-     * This method is identical in functionality to
+     * <p>Note that this method is identical in functionality to
      * {@link #containsValue(Object)}, and exists solely to ensure
      * full compatibility with class {@link java.util.Hashtable},
      * which supported this method prior to introduction of the
-     * Java Collections framework.
+     * Java Collections Framework.
      *
      * @param  value a value to search for
      * @return {@code true} if and only if some key maps to the
@@ -1419,11 +2099,7 @@
      *         {@code false} otherwise
      * @throws NullPointerException if the specified value is null
      */
-    // android-note : removed @deprecated tag from javadoc.
     public boolean contains(Object value) {
-        // BEGIN android-note
-        // removed deprecation
-        // END android-note
         return containsValue(value);
     }
 
@@ -1462,8 +2138,6 @@
      *
      * @return the number of mappings
      * @since 1.8
-     *
-     * @hide
      */
     public long mappingCount() {
         long n = sumCount();
@@ -1477,8 +2151,6 @@
      * @param <K> the element type of the returned set
      * @return the new set
      * @since 1.8
-     *
-     * @hide
      */
     public static <K> KeySetView<K,Boolean> newKeySet() {
         return new KeySetView<K,Boolean>
@@ -1496,8 +2168,6 @@
      * @throws IllegalArgumentException if the initial capacity of
      * elements is negative
      * @since 1.8
-     *
-     * @hide
      */
     public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) {
         return new KeySetView<K,Boolean>
@@ -1514,8 +2184,6 @@
      * @param mappedValue the mapped value to use for any additions
      * @return the set view
      * @throws NullPointerException if the mappedValue is null
-     *
-     * @hide
      */
     public KeySetView<K,V> keySet(V mappedValue) {
         if (mappedValue == null)
@@ -1536,25 +2204,34 @@
         }
 
         Node<K,V> find(int h, Object k) {
-            Node<K,V> e; int n;
-            Node<K,V>[] tab = nextTable;
-            if (k != null && tab != null && (n = tab.length) > 0 &&
-                (e = tabAt(tab, (n - 1) & h)) != null) {
-                do {
+            // loop to avoid arbitrarily deep recursion on forwarding nodes
+            outer: for (Node<K,V>[] tab = nextTable;;) {
+                Node<K,V> e; int n;
+                if (k == null || tab == null || (n = tab.length) == 0 ||
+                    (e = tabAt(tab, (n - 1) & h)) == null)
+                    return null;
+                for (;;) {
                     int eh; K ek;
                     if ((eh = e.hash) == h &&
                         ((ek = e.key) == k || (ek != null && k.equals(ek))))
                         return e;
-                    if (eh < 0)
-                        return e.find(h, k);
-                } while ((e = e.next) != null);
+                    if (eh < 0) {
+                        if (e instanceof ForwardingNode) {
+                            tab = ((ForwardingNode<K,V>)e).nextTable;
+                            continue outer;
+                        }
+                        else
+                            return e.find(h, k);
+                    }
+                    if ((e = e.next) == null)
+                        return null;
+                }
             }
-            return null;
         }
     }
 
     /**
-     * A place-holder node used in computeIfAbsent and compute
+     * A place-holder node used in computeIfAbsent and compute.
      */
     static final class ReservationNode<K,V> extends Node<K,V> {
         ReservationNode() {
@@ -1616,14 +2293,13 @@
         CounterCell[] as; long b, s;
         if ((as = counterCells) != null ||
             !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) {
-            CounterHashCode hc; CounterCell a; long v; int m;
+            CounterCell a; long v; int m;
             boolean uncontended = true;
-            if ((hc = threadCounterHashCode.get()) == null ||
-                as == null || (m = as.length - 1) < 0 ||
-                (a = as[m & hc.code]) == null ||
+            if (as == null || (m = as.length - 1) < 0 ||
+                (a = as[ThreadLocalRandom.getProbe() & m]) == null ||
                 !(uncontended =
                   U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) {
-                fullAddCount(x, hc, uncontended);
+                fullAddCount(x, uncontended);
                 return;
             }
             if (check <= 1)
@@ -1704,17 +2380,8 @@
                 break;
             else if (tab == table) {
                 int rs = resizeStamp(n);
-                if (sc < 0) {
-                    Node<K,V>[] nt;
-                    if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
-                        sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
-                        transferIndex <= 0)
-                        break;
-                    if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
-                        transfer(tab, nt);
-                }
-                else if (U.compareAndSwapInt(this, SIZECTL, sc,
-                                             (rs << RESIZE_STAMP_SHIFT) + 2))
+                if (U.compareAndSwapInt(this, SIZECTL, sc,
+                                        (rs << RESIZE_STAMP_SHIFT) + 2))
                     transfer(tab, null);
             }
         }
@@ -1857,6 +2524,112 @@
         }
     }
 
+    /* ---------------- Counter support -------------- */
+
+    /**
+     * A padded cell for distributing counts.  Adapted from LongAdder
+     * and Striped64.  See their internal docs for explanation.
+     */
+    //@jdk.internal.vm.annotation.Contended // android-removed
+    static final class CounterCell {
+        volatile long value;
+        CounterCell(long x) { value = x; }
+    }
+
+    final long sumCount() {
+        CounterCell[] as = counterCells; CounterCell a;
+        long sum = baseCount;
+        if (as != null) {
+            for (int i = 0; i < as.length; ++i) {
+                if ((a = as[i]) != null)
+                    sum += a.value;
+            }
+        }
+        return sum;
+    }
+
+    // See LongAdder version for explanation
+    private final void fullAddCount(long x, boolean wasUncontended) {
+        int h;
+        if ((h = ThreadLocalRandom.getProbe()) == 0) {
+            ThreadLocalRandom.localInit();      // force initialization
+            h = ThreadLocalRandom.getProbe();
+            wasUncontended = true;
+        }
+        boolean collide = false;                // True if last slot nonempty
+        for (;;) {
+            CounterCell[] as; CounterCell a; int n; long v;
+            if ((as = counterCells) != null && (n = as.length) > 0) {
+                if ((a = as[(n - 1) & h]) == null) {
+                    if (cellsBusy == 0) {            // Try to attach new Cell
+                        CounterCell r = new CounterCell(x); // Optimistic create
+                        if (cellsBusy == 0 &&
+                            U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
+                            boolean created = false;
+                            try {               // Recheck under lock
+                                CounterCell[] rs; int m, j;
+                                if ((rs = counterCells) != null &&
+                                    (m = rs.length) > 0 &&
+                                    rs[j = (m - 1) & h] == null) {
+                                    rs[j] = r;
+                                    created = true;
+                                }
+                            } finally {
+                                cellsBusy = 0;
+                            }
+                            if (created)
+                                break;
+                            continue;           // Slot is now non-empty
+                        }
+                    }
+                    collide = false;
+                }
+                else if (!wasUncontended)       // CAS already known to fail
+                    wasUncontended = true;      // Continue after rehash
+                else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))
+                    break;
+                else if (counterCells != as || n >= NCPU)
+                    collide = false;            // At max size or stale
+                else if (!collide)
+                    collide = true;
+                else if (cellsBusy == 0 &&
+                         U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
+                    try {
+                        if (counterCells == as) {// Expand table unless stale
+                            CounterCell[] rs = new CounterCell[n << 1];
+                            for (int i = 0; i < n; ++i)
+                                rs[i] = as[i];
+                            counterCells = rs;
+                        }
+                    } finally {
+                        cellsBusy = 0;
+                    }
+                    collide = false;
+                    continue;                   // Retry with expanded table
+                }
+                h = ThreadLocalRandom.advanceProbe(h);
+            }
+            else if (cellsBusy == 0 && counterCells == as &&
+                     U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
+                boolean init = false;
+                try {                           // Initialize table
+                    if (counterCells == as) {
+                        CounterCell[] rs = new CounterCell[2];
+                        rs[h & 1] = new CounterCell(x);
+                        counterCells = rs;
+                        init = true;
+                    }
+                } finally {
+                    cellsBusy = 0;
+                }
+                if (init)
+                    break;
+            }
+            else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x))
+                break;                          // Fall back on using base
+        }
+    }
+
     /* ---------------- Conversion from/to TreeBins -------------- */
 
     /**
@@ -1864,7 +2637,7 @@
      * too small, in which case resizes instead.
      */
     private final void treeifyBin(Node<K,V>[] tab, int index) {
-        Node<K,V> b; int n, sc;
+        Node<K,V> b; int n;
         if (tab != null) {
             if ((n = tab.length) < MIN_TREEIFY_CAPACITY)
                 tryPresize(n << 1);
@@ -1908,7 +2681,7 @@
     /* ---------------- TreeNodes -------------- */
 
     /**
-     * Nodes for use in TreeBins
+     * Nodes for use in TreeBins.
      */
     static final class TreeNode<K,V> extends Node<K,V> {
         TreeNode<K,V> parent;  // red-black tree links
@@ -1961,7 +2734,6 @@
         }
     }
 
-
     /* ---------------- TreeBins -------------- */
 
     /**
@@ -2028,7 +2800,7 @@
                                   (kc = comparableClassFor(k)) == null) ||
                                  (dir = compareComparables(kc, k, pk)) == 0)
                             dir = tieBreakOrder(k, pk);
-                            TreeNode<K,V> xp = p;
+                        TreeNode<K,V> xp = p;
                         if ((p = (dir <= 0) ? p.left : p.right) == null) {
                             x.parent = xp;
                             if (dir <= 0)
@@ -2106,13 +2878,9 @@
                             p = ((r = root) == null ? null :
                                  r.findTreeNode(h, k, null));
                         } finally {
-
                             Thread w;
-                            int ls;
-                            do {} while (!U.compareAndSwapInt
-                                         (this, LOCKSTATE,
-                                          ls = lockState, ls - READER));
-                            if (ls == (READER|WAITER) && (w = waiter) != null)
+                            if (U.getAndAddInt(this, LOCKSTATE, -READER) ==
+                                (READER|WAITER) && (w = waiter) != null)
                                 LockSupport.unpark(w);
                         }
                         return p;
@@ -2126,10 +2894,6 @@
          * Finds or adds a node.
          * @return null if added
          */
-        /**
-         * Finds or adds a node.
-         * @return null if added
-         */
         final TreeNode<K,V> putTreeVal(int h, K k, V v) {
             Class<?> kc = null;
             boolean searched = false;
@@ -2480,7 +3244,7 @@
         }
 
         /**
-         * Recursive invariant check
+         * Checks invariants recursively for the tree of Nodes rooted at t.
          */
         static <K,V> boolean checkInvariants(TreeNode<K,V> t) {
             TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right,
@@ -2504,15 +3268,13 @@
             return true;
         }
 
-        private static final sun.misc.Unsafe U;
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
         private static final long LOCKSTATE;
         static {
             try {
-                U = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = TreeBin.class;
                 LOCKSTATE = U.objectFieldOffset
-                    (k.getDeclaredField("lockState"));
-            } catch (Exception e) {
+                    (TreeBin.class.getDeclaredField("lockState"));
+            } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
         }
@@ -2727,7 +3489,7 @@
     }
 
     /**
-     * Exported Entry for EntryIterator
+     * Exported Entry for EntryIterator.
      */
     static final class MapEntry<K,V> implements Map.Entry<K,V> {
         final K key; // non-null
@@ -2741,7 +3503,9 @@
         public K getKey()        { return key; }
         public V getValue()      { return val; }
         public int hashCode()    { return key.hashCode() ^ val.hashCode(); }
-        public String toString() { return key + "=" + val; }
+        public String toString() {
+            return Helpers.mapEntryToString(key, val);
+        }
 
         public boolean equals(Object o) {
             Object k, v; Map.Entry<?,?> e;
@@ -2769,6 +3533,866 @@
         }
     }
 
+    static final class KeySpliterator<K,V> extends Traverser<K,V>
+        implements Spliterator<K> {
+        long est;               // size estimate
+        KeySpliterator(Node<K,V>[] tab, int size, int index, int limit,
+                       long est) {
+            super(tab, size, index, limit);
+            this.est = est;
+        }
+
+        public KeySpliterator<K,V> trySplit() {
+            int i, f, h;
+            return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
+                new KeySpliterator<K,V>(tab, baseSize, baseLimit = h,
+                                        f, est >>>= 1);
+        }
+
+        public void forEachRemaining(Consumer<? super K> action) {
+            if (action == null) throw new NullPointerException();
+            for (Node<K,V> p; (p = advance()) != null;)
+                action.accept(p.key);
+        }
+
+        public boolean tryAdvance(Consumer<? super K> action) {
+            if (action == null) throw new NullPointerException();
+            Node<K,V> p;
+            if ((p = advance()) == null)
+                return false;
+            action.accept(p.key);
+            return true;
+        }
+
+        public long estimateSize() { return est; }
+
+        public int characteristics() {
+            return Spliterator.DISTINCT | Spliterator.CONCURRENT |
+                Spliterator.NONNULL;
+        }
+    }
+
+    static final class ValueSpliterator<K,V> extends Traverser<K,V>
+        implements Spliterator<V> {
+        long est;               // size estimate
+        ValueSpliterator(Node<K,V>[] tab, int size, int index, int limit,
+                         long est) {
+            super(tab, size, index, limit);
+            this.est = est;
+        }
+
+        public ValueSpliterator<K,V> trySplit() {
+            int i, f, h;
+            return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
+                new ValueSpliterator<K,V>(tab, baseSize, baseLimit = h,
+                                          f, est >>>= 1);
+        }
+
+        public void forEachRemaining(Consumer<? super V> action) {
+            if (action == null) throw new NullPointerException();
+            for (Node<K,V> p; (p = advance()) != null;)
+                action.accept(p.val);
+        }
+
+        public boolean tryAdvance(Consumer<? super V> action) {
+            if (action == null) throw new NullPointerException();
+            Node<K,V> p;
+            if ((p = advance()) == null)
+                return false;
+            action.accept(p.val);
+            return true;
+        }
+
+        public long estimateSize() { return est; }
+
+        public int characteristics() {
+            return Spliterator.CONCURRENT | Spliterator.NONNULL;
+        }
+    }
+
+    static final class EntrySpliterator<K,V> extends Traverser<K,V>
+        implements Spliterator<Map.Entry<K,V>> {
+        final ConcurrentHashMap<K,V> map; // To export MapEntry
+        long est;               // size estimate
+        EntrySpliterator(Node<K,V>[] tab, int size, int index, int limit,
+                         long est, ConcurrentHashMap<K,V> map) {
+            super(tab, size, index, limit);
+            this.map = map;
+            this.est = est;
+        }
+
+        public EntrySpliterator<K,V> trySplit() {
+            int i, f, h;
+            return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
+                new EntrySpliterator<K,V>(tab, baseSize, baseLimit = h,
+                                          f, est >>>= 1, map);
+        }
+
+        public void forEachRemaining(Consumer<? super Map.Entry<K,V>> action) {
+            if (action == null) throw new NullPointerException();
+            for (Node<K,V> p; (p = advance()) != null; )
+                action.accept(new MapEntry<K,V>(p.key, p.val, map));
+        }
+
+        public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
+            if (action == null) throw new NullPointerException();
+            Node<K,V> p;
+            if ((p = advance()) == null)
+                return false;
+            action.accept(new MapEntry<K,V>(p.key, p.val, map));
+            return true;
+        }
+
+        public long estimateSize() { return est; }
+
+        public int characteristics() {
+            return Spliterator.DISTINCT | Spliterator.CONCURRENT |
+                Spliterator.NONNULL;
+        }
+    }
+
+    // Parallel bulk operations
+
+    /**
+     * Computes initial batch value for bulk tasks. The returned value
+     * is approximately exp2 of the number of times (minus one) to
+     * split task by two before executing leaf action. This value is
+     * faster to compute and more convenient to use as a guide to
+     * splitting than is the depth, since it is used while dividing by
+     * two anyway.
+     */
+    final int batchFor(long b) {
+        long n;
+        if (b == Long.MAX_VALUE || (n = sumCount()) <= 1L || n < b)
+            return 0;
+        int sp = ForkJoinPool.getCommonPoolParallelism() << 2; // slack of 4
+        return (b <= 0L || (n /= b) >= sp) ? sp : (int)n;
+    }
+
+    /**
+     * Performs the given action for each (key, value).
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param action the action
+     * @since 1.8
+     */
+    public void forEach(long parallelismThreshold,
+                        BiConsumer<? super K,? super V> action) {
+        if (action == null) throw new NullPointerException();
+        new ForEachMappingTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             action).invoke();
+    }
+
+    /**
+     * Performs the given action for each non-null transformation
+     * of each (key, value).
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element, or null if there is no transformation (in
+     * which case the action is not applied)
+     * @param action the action
+     * @param <U> the return type of the transformer
+     * @since 1.8
+     */
+    public <U> void forEach(long parallelismThreshold,
+                            BiFunction<? super K, ? super V, ? extends U> transformer,
+                            Consumer<? super U> action) {
+        if (transformer == null || action == null)
+            throw new NullPointerException();
+        new ForEachTransformedMappingTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             transformer, action).invoke();
+    }
+
+    /**
+     * Returns a non-null result from applying the given search
+     * function on each (key, value), or null if none.  Upon
+     * success, further element processing is suppressed and the
+     * results of any other parallel invocations of the search
+     * function are ignored.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param searchFunction a function returning a non-null
+     * result on success, else null
+     * @param <U> the return type of the search function
+     * @return a non-null result from applying the given search
+     * function on each (key, value), or null if none
+     * @since 1.8
+     */
+    public <U> U search(long parallelismThreshold,
+                        BiFunction<? super K, ? super V, ? extends U> searchFunction) {
+        if (searchFunction == null) throw new NullPointerException();
+        return new SearchMappingsTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             searchFunction, new AtomicReference<U>()).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all (key, value) pairs using the given reducer to
+     * combine values, or null if none.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element, or null if there is no transformation (in
+     * which case it is not combined)
+     * @param reducer a commutative associative combining function
+     * @param <U> the return type of the transformer
+     * @return the result of accumulating the given transformation
+     * of all (key, value) pairs
+     * @since 1.8
+     */
+    public <U> U reduce(long parallelismThreshold,
+                        BiFunction<? super K, ? super V, ? extends U> transformer,
+                        BiFunction<? super U, ? super U, ? extends U> reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceMappingsTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all (key, value) pairs using the given reducer to
+     * combine values, and the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all (key, value) pairs
+     * @since 1.8
+     */
+    public double reduceToDouble(long parallelismThreshold,
+                                 ToDoubleBiFunction<? super K, ? super V> transformer,
+                                 double basis,
+                                 DoubleBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceMappingsToDoubleTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all (key, value) pairs using the given reducer to
+     * combine values, and the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all (key, value) pairs
+     * @since 1.8
+     */
+    public long reduceToLong(long parallelismThreshold,
+                             ToLongBiFunction<? super K, ? super V> transformer,
+                             long basis,
+                             LongBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceMappingsToLongTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all (key, value) pairs using the given reducer to
+     * combine values, and the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all (key, value) pairs
+     * @since 1.8
+     */
+    public int reduceToInt(long parallelismThreshold,
+                           ToIntBiFunction<? super K, ? super V> transformer,
+                           int basis,
+                           IntBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceMappingsToIntTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Performs the given action for each key.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param action the action
+     * @since 1.8
+     */
+    public void forEachKey(long parallelismThreshold,
+                           Consumer<? super K> action) {
+        if (action == null) throw new NullPointerException();
+        new ForEachKeyTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             action).invoke();
+    }
+
+    /**
+     * Performs the given action for each non-null transformation
+     * of each key.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element, or null if there is no transformation (in
+     * which case the action is not applied)
+     * @param action the action
+     * @param <U> the return type of the transformer
+     * @since 1.8
+     */
+    public <U> void forEachKey(long parallelismThreshold,
+                               Function<? super K, ? extends U> transformer,
+                               Consumer<? super U> action) {
+        if (transformer == null || action == null)
+            throw new NullPointerException();
+        new ForEachTransformedKeyTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             transformer, action).invoke();
+    }
+
+    /**
+     * Returns a non-null result from applying the given search
+     * function on each key, or null if none. Upon success,
+     * further element processing is suppressed and the results of
+     * any other parallel invocations of the search function are
+     * ignored.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param searchFunction a function returning a non-null
+     * result on success, else null
+     * @param <U> the return type of the search function
+     * @return a non-null result from applying the given search
+     * function on each key, or null if none
+     * @since 1.8
+     */
+    public <U> U searchKeys(long parallelismThreshold,
+                            Function<? super K, ? extends U> searchFunction) {
+        if (searchFunction == null) throw new NullPointerException();
+        return new SearchKeysTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             searchFunction, new AtomicReference<U>()).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating all keys using the given
+     * reducer to combine values, or null if none.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating all keys using the given
+     * reducer to combine values, or null if none
+     * @since 1.8
+     */
+    public K reduceKeys(long parallelismThreshold,
+                        BiFunction<? super K, ? super K, ? extends K> reducer) {
+        if (reducer == null) throw new NullPointerException();
+        return new ReduceKeysTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all keys using the given reducer to combine values, or
+     * null if none.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element, or null if there is no transformation (in
+     * which case it is not combined)
+     * @param reducer a commutative associative combining function
+     * @param <U> the return type of the transformer
+     * @return the result of accumulating the given transformation
+     * of all keys
+     * @since 1.8
+     */
+    public <U> U reduceKeys(long parallelismThreshold,
+                            Function<? super K, ? extends U> transformer,
+         BiFunction<? super U, ? super U, ? extends U> reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceKeysTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all keys using the given reducer to combine values, and
+     * the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all keys
+     * @since 1.8
+     */
+    public double reduceKeysToDouble(long parallelismThreshold,
+                                     ToDoubleFunction<? super K> transformer,
+                                     double basis,
+                                     DoubleBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceKeysToDoubleTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all keys using the given reducer to combine values, and
+     * the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all keys
+     * @since 1.8
+     */
+    public long reduceKeysToLong(long parallelismThreshold,
+                                 ToLongFunction<? super K> transformer,
+                                 long basis,
+                                 LongBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceKeysToLongTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all keys using the given reducer to combine values, and
+     * the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all keys
+     * @since 1.8
+     */
+    public int reduceKeysToInt(long parallelismThreshold,
+                               ToIntFunction<? super K> transformer,
+                               int basis,
+                               IntBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceKeysToIntTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Performs the given action for each value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param action the action
+     * @since 1.8
+     */
+    public void forEachValue(long parallelismThreshold,
+                             Consumer<? super V> action) {
+        if (action == null)
+            throw new NullPointerException();
+        new ForEachValueTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             action).invoke();
+    }
+
+    /**
+     * Performs the given action for each non-null transformation
+     * of each value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element, or null if there is no transformation (in
+     * which case the action is not applied)
+     * @param action the action
+     * @param <U> the return type of the transformer
+     * @since 1.8
+     */
+    public <U> void forEachValue(long parallelismThreshold,
+                                 Function<? super V, ? extends U> transformer,
+                                 Consumer<? super U> action) {
+        if (transformer == null || action == null)
+            throw new NullPointerException();
+        new ForEachTransformedValueTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             transformer, action).invoke();
+    }
+
+    /**
+     * Returns a non-null result from applying the given search
+     * function on each value, or null if none.  Upon success,
+     * further element processing is suppressed and the results of
+     * any other parallel invocations of the search function are
+     * ignored.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param searchFunction a function returning a non-null
+     * result on success, else null
+     * @param <U> the return type of the search function
+     * @return a non-null result from applying the given search
+     * function on each value, or null if none
+     * @since 1.8
+     */
+    public <U> U searchValues(long parallelismThreshold,
+                              Function<? super V, ? extends U> searchFunction) {
+        if (searchFunction == null) throw new NullPointerException();
+        return new SearchValuesTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             searchFunction, new AtomicReference<U>()).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating all values using the
+     * given reducer to combine values, or null if none.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating all values
+     * @since 1.8
+     */
+    public V reduceValues(long parallelismThreshold,
+                          BiFunction<? super V, ? super V, ? extends V> reducer) {
+        if (reducer == null) throw new NullPointerException();
+        return new ReduceValuesTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all values using the given reducer to combine values, or
+     * null if none.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element, or null if there is no transformation (in
+     * which case it is not combined)
+     * @param reducer a commutative associative combining function
+     * @param <U> the return type of the transformer
+     * @return the result of accumulating the given transformation
+     * of all values
+     * @since 1.8
+     */
+    public <U> U reduceValues(long parallelismThreshold,
+                              Function<? super V, ? extends U> transformer,
+                              BiFunction<? super U, ? super U, ? extends U> reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceValuesTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all values using the given reducer to combine values,
+     * and the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all values
+     * @since 1.8
+     */
+    public double reduceValuesToDouble(long parallelismThreshold,
+                                       ToDoubleFunction<? super V> transformer,
+                                       double basis,
+                                       DoubleBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceValuesToDoubleTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all values using the given reducer to combine values,
+     * and the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all values
+     * @since 1.8
+     */
+    public long reduceValuesToLong(long parallelismThreshold,
+                                   ToLongFunction<? super V> transformer,
+                                   long basis,
+                                   LongBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceValuesToLongTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all values using the given reducer to combine values,
+     * and the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all values
+     * @since 1.8
+     */
+    public int reduceValuesToInt(long parallelismThreshold,
+                                 ToIntFunction<? super V> transformer,
+                                 int basis,
+                                 IntBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceValuesToIntTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Performs the given action for each entry.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param action the action
+     * @since 1.8
+     */
+    public void forEachEntry(long parallelismThreshold,
+                             Consumer<? super Map.Entry<K,V>> action) {
+        if (action == null) throw new NullPointerException();
+        new ForEachEntryTask<K,V>(null, batchFor(parallelismThreshold), 0, 0, table,
+                                  action).invoke();
+    }
+
+    /**
+     * Performs the given action for each non-null transformation
+     * of each entry.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element, or null if there is no transformation (in
+     * which case the action is not applied)
+     * @param action the action
+     * @param <U> the return type of the transformer
+     * @since 1.8
+     */
+    public <U> void forEachEntry(long parallelismThreshold,
+                                 Function<Map.Entry<K,V>, ? extends U> transformer,
+                                 Consumer<? super U> action) {
+        if (transformer == null || action == null)
+            throw new NullPointerException();
+        new ForEachTransformedEntryTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             transformer, action).invoke();
+    }
+
+    /**
+     * Returns a non-null result from applying the given search
+     * function on each entry, or null if none.  Upon success,
+     * further element processing is suppressed and the results of
+     * any other parallel invocations of the search function are
+     * ignored.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param searchFunction a function returning a non-null
+     * result on success, else null
+     * @param <U> the return type of the search function
+     * @return a non-null result from applying the given search
+     * function on each entry, or null if none
+     * @since 1.8
+     */
+    public <U> U searchEntries(long parallelismThreshold,
+                               Function<Map.Entry<K,V>, ? extends U> searchFunction) {
+        if (searchFunction == null) throw new NullPointerException();
+        return new SearchEntriesTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             searchFunction, new AtomicReference<U>()).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating all entries using the
+     * given reducer to combine values, or null if none.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating all entries
+     * @since 1.8
+     */
+    public Map.Entry<K,V> reduceEntries(long parallelismThreshold,
+                                        BiFunction<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
+        if (reducer == null) throw new NullPointerException();
+        return new ReduceEntriesTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all entries using the given reducer to combine values,
+     * or null if none.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element, or null if there is no transformation (in
+     * which case it is not combined)
+     * @param reducer a commutative associative combining function
+     * @param <U> the return type of the transformer
+     * @return the result of accumulating the given transformation
+     * of all entries
+     * @since 1.8
+     */
+    public <U> U reduceEntries(long parallelismThreshold,
+                               Function<Map.Entry<K,V>, ? extends U> transformer,
+                               BiFunction<? super U, ? super U, ? extends U> reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceEntriesTask<K,V,U>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all entries using the given reducer to combine values,
+     * and the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all entries
+     * @since 1.8
+     */
+    public double reduceEntriesToDouble(long parallelismThreshold,
+                                        ToDoubleFunction<Map.Entry<K,V>> transformer,
+                                        double basis,
+                                        DoubleBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceEntriesToDoubleTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all entries using the given reducer to combine values,
+     * and the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all entries
+     * @since 1.8
+     */
+    public long reduceEntriesToLong(long parallelismThreshold,
+                                    ToLongFunction<Map.Entry<K,V>> transformer,
+                                    long basis,
+                                    LongBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceEntriesToLongTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+    /**
+     * Returns the result of accumulating the given transformation
+     * of all entries using the given reducer to combine values,
+     * and the given basis as an identity value.
+     *
+     * @param parallelismThreshold the (estimated) number of elements
+     * needed for this operation to be executed in parallel
+     * @param transformer a function returning the transformation
+     * for an element
+     * @param basis the identity (initial default value) for the reduction
+     * @param reducer a commutative associative combining function
+     * @return the result of accumulating the given transformation
+     * of all entries
+     * @since 1.8
+     */
+    public int reduceEntriesToInt(long parallelismThreshold,
+                                  ToIntFunction<Map.Entry<K,V>> transformer,
+                                  int basis,
+                                  IntBinaryOperator reducer) {
+        if (transformer == null || reducer == null)
+            throw new NullPointerException();
+        return new MapReduceEntriesToIntTask<K,V>
+            (null, batchFor(parallelismThreshold), 0, 0, table,
+             null, transformer, basis, reducer).invoke();
+    }
+
+
     /* ----------------Views -------------- */
 
     /**
@@ -2798,30 +4422,30 @@
         // implementations below rely on concrete classes supplying these
         // abstract methods
         /**
-         * Returns a "weakly consistent" iterator that will never
-         * throw {@link ConcurrentModificationException}, and
-         * guarantees to traverse elements as they existed upon
-         * construction of the iterator, and may (but is not
-         * guaranteed to) reflect any modifications subsequent to
-         * construction.
+         * Returns an iterator over the elements in this collection.
+         *
+         * <p>The returned iterator is
+         * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+         *
+         * @return an iterator over the elements in this collection
          */
         public abstract Iterator<E> iterator();
         public abstract boolean contains(Object o);
         public abstract boolean remove(Object o);
 
-        private static final String oomeMsg = "Required array size too large";
+        private static final String OOME_MSG = "Required array size too large";
 
         public final Object[] toArray() {
             long sz = map.mappingCount();
             if (sz > MAX_ARRAY_SIZE)
-                throw new OutOfMemoryError(oomeMsg);
+                throw new OutOfMemoryError(OOME_MSG);
             int n = (int)sz;
             Object[] r = new Object[n];
             int i = 0;
             for (E e : this) {
                 if (i == n) {
                     if (n >= MAX_ARRAY_SIZE)
-                        throw new OutOfMemoryError(oomeMsg);
+                        throw new OutOfMemoryError(OOME_MSG);
                     if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
                         n = MAX_ARRAY_SIZE;
                     else
@@ -2837,7 +4461,7 @@
         public final <T> T[] toArray(T[] a) {
             long sz = map.mappingCount();
             if (sz > MAX_ARRAY_SIZE)
-                throw new OutOfMemoryError(oomeMsg);
+                throw new OutOfMemoryError(OOME_MSG);
             int m = (int)sz;
             T[] r = (a.length >= m) ? a :
                 (T[])java.lang.reflect.Array
@@ -2847,7 +4471,7 @@
             for (E e : this) {
                 if (i == n) {
                     if (n >= MAX_ARRAY_SIZE)
-                        throw new OutOfMemoryError(oomeMsg);
+                        throw new OutOfMemoryError(OOME_MSG);
                     if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
                         n = MAX_ARRAY_SIZE;
                     else
@@ -2901,6 +4525,7 @@
         }
 
         public final boolean removeAll(Collection<?> c) {
+            if (c == null) throw new NullPointerException();
             boolean modified = false;
             for (Iterator<E> it = iterator(); it.hasNext();) {
                 if (c.contains(it.next())) {
@@ -2912,6 +4537,7 @@
         }
 
         public final boolean retainAll(Collection<?> c) {
+            if (c == null) throw new NullPointerException();
             boolean modified = false;
             for (Iterator<E> it = iterator(); it.hasNext();) {
                 if (!c.contains(it.next())) {
@@ -2930,12 +4556,11 @@
      * common value.  This class cannot be directly instantiated.
      * See {@link #keySet() keySet()},
      * {@link #keySet(Object) keySet(V)},
+     * {@link #newKeySet() newKeySet()},
+     * {@link #newKeySet(int) newKeySet(int)}.
      *
      * @since 1.8
-     *
-     * @hide
      */
-    // android-note: removed references to hidden APIs.
     public static class KeySetView<K,V> extends CollectionView<K,V,K>
         implements Set<K>, java.io.Serializable {
         private static final long serialVersionUID = 7249069246763182397L;
@@ -3035,6 +4660,23 @@
                      (containsAll(c) && c.containsAll(this))));
         }
 
+        public Spliterator<K> spliterator() {
+            Node<K,V>[] t;
+            ConcurrentHashMap<K,V> m = map;
+            long n = m.sumCount();
+            int f = (t = m.table) == null ? 0 : t.length;
+            return new KeySpliterator<K,V>(t, f, 0, f, n < 0L ? 0L : n);
+        }
+
+        public void forEach(Consumer<? super K> action) {
+            if (action == null) throw new NullPointerException();
+            Node<K,V>[] t;
+            if ((t = map.table) != null) {
+                Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+                for (Node<K,V> p; (p = it.advance()) != null; )
+                    action.accept(p.key);
+            }
+        }
     }
 
     /**
@@ -3076,6 +4718,27 @@
             throw new UnsupportedOperationException();
         }
 
+        public boolean removeIf(Predicate<? super V> filter) {
+            return map.removeValueIf(filter);
+        }
+
+        public Spliterator<V> spliterator() {
+            Node<K,V>[] t;
+            ConcurrentHashMap<K,V> m = map;
+            long n = m.sumCount();
+            int f = (t = m.table) == null ? 0 : t.length;
+            return new ValueSpliterator<K,V>(t, f, 0, f, n < 0L ? 0L : n);
+        }
+
+        public void forEach(Consumer<? super V> action) {
+            if (action == null) throw new NullPointerException();
+            Node<K,V>[] t;
+            if ((t = map.table) != null) {
+                Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+                for (Node<K,V> p; (p = it.advance()) != null; )
+                    action.accept(p.val);
+            }
+        }
     }
 
     /**
@@ -3128,6 +4791,10 @@
             return added;
         }
 
+        public boolean removeIf(Predicate<? super Entry<K,V>> filter) {
+            return map.removeEntryIf(filter);
+        }
+
         public final int hashCode() {
             int h = 0;
             Node<K,V>[] t;
@@ -3147,181 +4814,1532 @@
                      (containsAll(c) && c.containsAll(this))));
         }
 
-    }
+        public Spliterator<Map.Entry<K,V>> spliterator() {
+            Node<K,V>[] t;
+            ConcurrentHashMap<K,V> m = map;
+            long n = m.sumCount();
+            int f = (t = m.table) == null ? 0 : t.length;
+            return new EntrySpliterator<K,V>(t, f, 0, f, n < 0L ? 0L : n, m);
+        }
 
-
-    /* ---------------- Counters -------------- */
-
-    // Adapted from LongAdder and Striped64.
-    // See their internal docs for explanation.
-
-    // A padded cell for distributing counts
-    static final class CounterCell {
-        volatile long p0, p1, p2, p3, p4, p5, p6;
-        volatile long value;
-        volatile long q0, q1, q2, q3, q4, q5, q6;
-        CounterCell(long x) { value = x; }
-    }
-
-    /**
-     * Holder for the thread-local hash code determining which
-     * CounterCell to use. The code is initialized via the
-     * counterHashCodeGenerator, but may be moved upon collisions.
-     */
-    static final class CounterHashCode {
-        int code;
-    }
-
-    /**
-     * Generates initial value for per-thread CounterHashCodes.
-     */
-    static final AtomicInteger counterHashCodeGenerator = new AtomicInteger();
-
-    /**
-     * Increment for counterHashCodeGenerator. See class ThreadLocal
-     * for explanation.
-     */
-    static final int SEED_INCREMENT = 0x61c88647;
-
-    /**
-     * Per-thread counter hash codes. Shared across all instances.
-     */
-    static final ThreadLocal<CounterHashCode> threadCounterHashCode =
-        new ThreadLocal<CounterHashCode>();
-
-    final long sumCount() {
-        CounterCell[] as = counterCells; CounterCell a;
-        long sum = baseCount;
-        if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null)
-                    sum += a.value;
+        public void forEach(Consumer<? super Map.Entry<K,V>> action) {
+            if (action == null) throw new NullPointerException();
+            Node<K,V>[] t;
+            if ((t = map.table) != null) {
+                Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
+                for (Node<K,V> p; (p = it.advance()) != null; )
+                    action.accept(new MapEntry<K,V>(p.key, p.val, map));
             }
         }
-        return sum;
+
     }
 
-    // See LongAdder version for explanation
-    private final void fullAddCount(long x, CounterHashCode hc,
-                                    boolean wasUncontended) {
-        int h;
-        if (hc == null) {
-            hc = new CounterHashCode();
-            int s = counterHashCodeGenerator.addAndGet(SEED_INCREMENT);
-            h = hc.code = (s == 0) ? 1 : s; // Avoid zero
-            threadCounterHashCode.set(hc);
-        }
-        else
-            h = hc.code;
-        boolean collide = false;                // True if last slot nonempty
-        for (;;) {
-            CounterCell[] as; CounterCell a; int n; long v;
-            if ((as = counterCells) != null && (n = as.length) > 0) {
-                if ((a = as[(n - 1) & h]) == null) {
-                    if (cellsBusy == 0) {            // Try to attach new Cell
-                        CounterCell r = new CounterCell(x); // Optimistic create
-                        if (cellsBusy == 0 &&
-                            U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
-                            boolean created = false;
-                            try {               // Recheck under lock
-                                CounterCell[] rs; int m, j;
-                                if ((rs = counterCells) != null &&
-                                    (m = rs.length) > 0 &&
-                                    rs[j = (m - 1) & h] == null) {
-                                    rs[j] = r;
-                                    created = true;
-                                }
-                            } finally {
-                                cellsBusy = 0;
-                            }
-                            if (created)
-                                break;
-                            continue;           // Slot is now non-empty
-                        }
-                    }
-                    collide = false;
-                }
-                else if (!wasUncontended)       // CAS already known to fail
-                    wasUncontended = true;      // Continue after rehash
-                else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))
-                    break;
-                else if (counterCells != as || n >= NCPU)
-                    collide = false;            // At max size or stale
-                else if (!collide)
-                    collide = true;
-                else if (cellsBusy == 0 &&
-                         U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
-                    try {
-                        if (counterCells == as) {// Expand table unless stale
-                            CounterCell[] rs = new CounterCell[n << 1];
-                            for (int i = 0; i < n; ++i)
-                                rs[i] = as[i];
-                            counterCells = rs;
-                        }
-                    } finally {
-                        cellsBusy = 0;
-                    }
-                    collide = false;
-                    continue;                   // Retry with expanded table
-                }
-                h ^= h << 13;                   // Rehash
-                h ^= h >>> 17;
-                h ^= h << 5;
+    // -------------------------------------------------------
+
+    /**
+     * Base class for bulk tasks. Repeats some fields and code from
+     * class Traverser, because we need to subclass CountedCompleter.
+     */
+    @SuppressWarnings("serial")
+    abstract static class BulkTask<K,V,R> extends CountedCompleter<R> {
+        Node<K,V>[] tab;        // same as Traverser
+        Node<K,V> next;
+        TableStack<K,V> stack, spare;
+        int index;
+        int baseIndex;
+        int baseLimit;
+        final int baseSize;
+        int batch;              // split control
+
+        BulkTask(BulkTask<K,V,?> par, int b, int i, int f, Node<K,V>[] t) {
+            super(par);
+            this.batch = b;
+            this.index = this.baseIndex = i;
+            if ((this.tab = t) == null)
+                this.baseSize = this.baseLimit = 0;
+            else if (par == null)
+                this.baseSize = this.baseLimit = t.length;
+            else {
+                this.baseLimit = f;
+                this.baseSize = par.baseSize;
             }
-            else if (cellsBusy == 0 && counterCells == as &&
-                     U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
-                boolean init = false;
-                try {                           // Initialize table
-                    if (counterCells == as) {
-                        CounterCell[] rs = new CounterCell[2];
-                        rs[h & 1] = new CounterCell(x);
-                        counterCells = rs;
-                        init = true;
-                    }
-                } finally {
-                    cellsBusy = 0;
-                }
-                if (init)
-                    break;
-            }
-            else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x))
-                break;                          // Fall back on using base
         }
-        hc.code = h;                            // Record index for next time
+
+        /**
+         * Same as Traverser version.
+         */
+        final Node<K,V> advance() {
+            Node<K,V> e;
+            if ((e = next) != null)
+                e = e.next;
+            for (;;) {
+                Node<K,V>[] t; int i, n;
+                if (e != null)
+                    return next = e;
+                if (baseIndex >= baseLimit || (t = tab) == null ||
+                    (n = t.length) <= (i = index) || i < 0)
+                    return next = null;
+                if ((e = tabAt(t, i)) != null && e.hash < 0) {
+                    if (e instanceof ForwardingNode) {
+                        tab = ((ForwardingNode<K,V>)e).nextTable;
+                        e = null;
+                        pushState(t, i, n);
+                        continue;
+                    }
+                    else if (e instanceof TreeBin)
+                        e = ((TreeBin<K,V>)e).first;
+                    else
+                        e = null;
+                }
+                if (stack != null)
+                    recoverState(n);
+                else if ((index = i + baseSize) >= n)
+                    index = ++baseIndex;
+            }
+        }
+
+        private void pushState(Node<K,V>[] t, int i, int n) {
+            TableStack<K,V> s = spare;
+            if (s != null)
+                spare = s.next;
+            else
+                s = new TableStack<K,V>();
+            s.tab = t;
+            s.length = n;
+            s.index = i;
+            s.next = stack;
+            stack = s;
+        }
+
+        private void recoverState(int n) {
+            TableStack<K,V> s; int len;
+            while ((s = stack) != null && (index += (len = s.length)) >= n) {
+                n = len;
+                index = s.index;
+                tab = s.tab;
+                s.tab = null;
+                TableStack<K,V> next = s.next;
+                s.next = spare; // save for reuse
+                stack = next;
+                spare = s;
+            }
+            if (s == null && (index += baseSize) >= n)
+                index = ++baseIndex;
+        }
+    }
+
+    /*
+     * Task classes. Coded in a regular but ugly format/style to
+     * simplify checks that each variant differs in the right way from
+     * others. The null screenings exist because compilers cannot tell
+     * that we've already null-checked task arguments, so we force
+     * simplest hoisted bypass to help avoid convoluted traps.
+     */
+    @SuppressWarnings("serial")
+    static final class ForEachKeyTask<K,V>
+        extends BulkTask<K,V,Void> {
+        final Consumer<? super K> action;
+        ForEachKeyTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             Consumer<? super K> action) {
+            super(p, b, i, f, t);
+            this.action = action;
+        }
+        public final void compute() {
+            final Consumer<? super K> action;
+            if ((action = this.action) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    new ForEachKeyTask<K,V>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         action).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null;)
+                    action.accept(p.key);
+                propagateCompletion();
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ForEachValueTask<K,V>
+        extends BulkTask<K,V,Void> {
+        final Consumer<? super V> action;
+        ForEachValueTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             Consumer<? super V> action) {
+            super(p, b, i, f, t);
+            this.action = action;
+        }
+        public final void compute() {
+            final Consumer<? super V> action;
+            if ((action = this.action) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    new ForEachValueTask<K,V>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         action).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null;)
+                    action.accept(p.val);
+                propagateCompletion();
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ForEachEntryTask<K,V>
+        extends BulkTask<K,V,Void> {
+        final Consumer<? super Entry<K,V>> action;
+        ForEachEntryTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             Consumer<? super Entry<K,V>> action) {
+            super(p, b, i, f, t);
+            this.action = action;
+        }
+        public final void compute() {
+            final Consumer<? super Entry<K,V>> action;
+            if ((action = this.action) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    new ForEachEntryTask<K,V>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         action).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    action.accept(p);
+                propagateCompletion();
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ForEachMappingTask<K,V>
+        extends BulkTask<K,V,Void> {
+        final BiConsumer<? super K, ? super V> action;
+        ForEachMappingTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             BiConsumer<? super K,? super V> action) {
+            super(p, b, i, f, t);
+            this.action = action;
+        }
+        public final void compute() {
+            final BiConsumer<? super K, ? super V> action;
+            if ((action = this.action) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    new ForEachMappingTask<K,V>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         action).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    action.accept(p.key, p.val);
+                propagateCompletion();
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ForEachTransformedKeyTask<K,V,U>
+        extends BulkTask<K,V,Void> {
+        final Function<? super K, ? extends U> transformer;
+        final Consumer<? super U> action;
+        ForEachTransformedKeyTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             Function<? super K, ? extends U> transformer, Consumer<? super U> action) {
+            super(p, b, i, f, t);
+            this.transformer = transformer; this.action = action;
+        }
+        public final void compute() {
+            final Function<? super K, ? extends U> transformer;
+            final Consumer<? super U> action;
+            if ((transformer = this.transformer) != null &&
+                (action = this.action) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    new ForEachTransformedKeyTask<K,V,U>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         transformer, action).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    U u;
+                    if ((u = transformer.apply(p.key)) != null)
+                        action.accept(u);
+                }
+                propagateCompletion();
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ForEachTransformedValueTask<K,V,U>
+        extends BulkTask<K,V,Void> {
+        final Function<? super V, ? extends U> transformer;
+        final Consumer<? super U> action;
+        ForEachTransformedValueTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             Function<? super V, ? extends U> transformer, Consumer<? super U> action) {
+            super(p, b, i, f, t);
+            this.transformer = transformer; this.action = action;
+        }
+        public final void compute() {
+            final Function<? super V, ? extends U> transformer;
+            final Consumer<? super U> action;
+            if ((transformer = this.transformer) != null &&
+                (action = this.action) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    new ForEachTransformedValueTask<K,V,U>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         transformer, action).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    U u;
+                    if ((u = transformer.apply(p.val)) != null)
+                        action.accept(u);
+                }
+                propagateCompletion();
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ForEachTransformedEntryTask<K,V,U>
+        extends BulkTask<K,V,Void> {
+        final Function<Map.Entry<K,V>, ? extends U> transformer;
+        final Consumer<? super U> action;
+        ForEachTransformedEntryTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             Function<Map.Entry<K,V>, ? extends U> transformer, Consumer<? super U> action) {
+            super(p, b, i, f, t);
+            this.transformer = transformer; this.action = action;
+        }
+        public final void compute() {
+            final Function<Map.Entry<K,V>, ? extends U> transformer;
+            final Consumer<? super U> action;
+            if ((transformer = this.transformer) != null &&
+                (action = this.action) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    new ForEachTransformedEntryTask<K,V,U>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         transformer, action).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    U u;
+                    if ((u = transformer.apply(p)) != null)
+                        action.accept(u);
+                }
+                propagateCompletion();
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ForEachTransformedMappingTask<K,V,U>
+        extends BulkTask<K,V,Void> {
+        final BiFunction<? super K, ? super V, ? extends U> transformer;
+        final Consumer<? super U> action;
+        ForEachTransformedMappingTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             BiFunction<? super K, ? super V, ? extends U> transformer,
+             Consumer<? super U> action) {
+            super(p, b, i, f, t);
+            this.transformer = transformer; this.action = action;
+        }
+        public final void compute() {
+            final BiFunction<? super K, ? super V, ? extends U> transformer;
+            final Consumer<? super U> action;
+            if ((transformer = this.transformer) != null &&
+                (action = this.action) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    new ForEachTransformedMappingTask<K,V,U>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         transformer, action).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    U u;
+                    if ((u = transformer.apply(p.key, p.val)) != null)
+                        action.accept(u);
+                }
+                propagateCompletion();
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class SearchKeysTask<K,V,U>
+        extends BulkTask<K,V,U> {
+        final Function<? super K, ? extends U> searchFunction;
+        final AtomicReference<U> result;
+        SearchKeysTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             Function<? super K, ? extends U> searchFunction,
+             AtomicReference<U> result) {
+            super(p, b, i, f, t);
+            this.searchFunction = searchFunction; this.result = result;
+        }
+        public final U getRawResult() { return result.get(); }
+        public final void compute() {
+            final Function<? super K, ? extends U> searchFunction;
+            final AtomicReference<U> result;
+            if ((searchFunction = this.searchFunction) != null &&
+                (result = this.result) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    if (result.get() != null)
+                        return;
+                    addToPendingCount(1);
+                    new SearchKeysTask<K,V,U>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         searchFunction, result).fork();
+                }
+                while (result.get() == null) {
+                    U u;
+                    Node<K,V> p;
+                    if ((p = advance()) == null) {
+                        propagateCompletion();
+                        break;
+                    }
+                    if ((u = searchFunction.apply(p.key)) != null) {
+                        if (result.compareAndSet(null, u))
+                            quietlyCompleteRoot();
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class SearchValuesTask<K,V,U>
+        extends BulkTask<K,V,U> {
+        final Function<? super V, ? extends U> searchFunction;
+        final AtomicReference<U> result;
+        SearchValuesTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             Function<? super V, ? extends U> searchFunction,
+             AtomicReference<U> result) {
+            super(p, b, i, f, t);
+            this.searchFunction = searchFunction; this.result = result;
+        }
+        public final U getRawResult() { return result.get(); }
+        public final void compute() {
+            final Function<? super V, ? extends U> searchFunction;
+            final AtomicReference<U> result;
+            if ((searchFunction = this.searchFunction) != null &&
+                (result = this.result) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    if (result.get() != null)
+                        return;
+                    addToPendingCount(1);
+                    new SearchValuesTask<K,V,U>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         searchFunction, result).fork();
+                }
+                while (result.get() == null) {
+                    U u;
+                    Node<K,V> p;
+                    if ((p = advance()) == null) {
+                        propagateCompletion();
+                        break;
+                    }
+                    if ((u = searchFunction.apply(p.val)) != null) {
+                        if (result.compareAndSet(null, u))
+                            quietlyCompleteRoot();
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class SearchEntriesTask<K,V,U>
+        extends BulkTask<K,V,U> {
+        final Function<Entry<K,V>, ? extends U> searchFunction;
+        final AtomicReference<U> result;
+        SearchEntriesTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             Function<Entry<K,V>, ? extends U> searchFunction,
+             AtomicReference<U> result) {
+            super(p, b, i, f, t);
+            this.searchFunction = searchFunction; this.result = result;
+        }
+        public final U getRawResult() { return result.get(); }
+        public final void compute() {
+            final Function<Entry<K,V>, ? extends U> searchFunction;
+            final AtomicReference<U> result;
+            if ((searchFunction = this.searchFunction) != null &&
+                (result = this.result) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    if (result.get() != null)
+                        return;
+                    addToPendingCount(1);
+                    new SearchEntriesTask<K,V,U>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         searchFunction, result).fork();
+                }
+                while (result.get() == null) {
+                    U u;
+                    Node<K,V> p;
+                    if ((p = advance()) == null) {
+                        propagateCompletion();
+                        break;
+                    }
+                    if ((u = searchFunction.apply(p)) != null) {
+                        if (result.compareAndSet(null, u))
+                            quietlyCompleteRoot();
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class SearchMappingsTask<K,V,U>
+        extends BulkTask<K,V,U> {
+        final BiFunction<? super K, ? super V, ? extends U> searchFunction;
+        final AtomicReference<U> result;
+        SearchMappingsTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             BiFunction<? super K, ? super V, ? extends U> searchFunction,
+             AtomicReference<U> result) {
+            super(p, b, i, f, t);
+            this.searchFunction = searchFunction; this.result = result;
+        }
+        public final U getRawResult() { return result.get(); }
+        public final void compute() {
+            final BiFunction<? super K, ? super V, ? extends U> searchFunction;
+            final AtomicReference<U> result;
+            if ((searchFunction = this.searchFunction) != null &&
+                (result = this.result) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    if (result.get() != null)
+                        return;
+                    addToPendingCount(1);
+                    new SearchMappingsTask<K,V,U>
+                        (this, batch >>>= 1, baseLimit = h, f, tab,
+                         searchFunction, result).fork();
+                }
+                while (result.get() == null) {
+                    U u;
+                    Node<K,V> p;
+                    if ((p = advance()) == null) {
+                        propagateCompletion();
+                        break;
+                    }
+                    if ((u = searchFunction.apply(p.key, p.val)) != null) {
+                        if (result.compareAndSet(null, u))
+                            quietlyCompleteRoot();
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ReduceKeysTask<K,V>
+        extends BulkTask<K,V,K> {
+        final BiFunction<? super K, ? super K, ? extends K> reducer;
+        K result;
+        ReduceKeysTask<K,V> rights, nextRight;
+        ReduceKeysTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             ReduceKeysTask<K,V> nextRight,
+             BiFunction<? super K, ? super K, ? extends K> reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.reducer = reducer;
+        }
+        public final K getRawResult() { return result; }
+        public final void compute() {
+            final BiFunction<? super K, ? super K, ? extends K> reducer;
+            if ((reducer = this.reducer) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new ReduceKeysTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, reducer)).fork();
+                }
+                K r = null;
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    K u = p.key;
+                    r = (r == null) ? u : u == null ? r : reducer.apply(r, u);
+                }
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    ReduceKeysTask<K,V>
+                        t = (ReduceKeysTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        K tr, sr;
+                        if ((sr = s.result) != null)
+                            t.result = (((tr = t.result) == null) ? sr :
+                                        reducer.apply(tr, sr));
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ReduceValuesTask<K,V>
+        extends BulkTask<K,V,V> {
+        final BiFunction<? super V, ? super V, ? extends V> reducer;
+        V result;
+        ReduceValuesTask<K,V> rights, nextRight;
+        ReduceValuesTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             ReduceValuesTask<K,V> nextRight,
+             BiFunction<? super V, ? super V, ? extends V> reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.reducer = reducer;
+        }
+        public final V getRawResult() { return result; }
+        public final void compute() {
+            final BiFunction<? super V, ? super V, ? extends V> reducer;
+            if ((reducer = this.reducer) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new ReduceValuesTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, reducer)).fork();
+                }
+                V r = null;
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    V v = p.val;
+                    r = (r == null) ? v : reducer.apply(r, v);
+                }
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    ReduceValuesTask<K,V>
+                        t = (ReduceValuesTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        V tr, sr;
+                        if ((sr = s.result) != null)
+                            t.result = (((tr = t.result) == null) ? sr :
+                                        reducer.apply(tr, sr));
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class ReduceEntriesTask<K,V>
+        extends BulkTask<K,V,Map.Entry<K,V>> {
+        final BiFunction<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer;
+        Map.Entry<K,V> result;
+        ReduceEntriesTask<K,V> rights, nextRight;
+        ReduceEntriesTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             ReduceEntriesTask<K,V> nextRight,
+             BiFunction<Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.reducer = reducer;
+        }
+        public final Map.Entry<K,V> getRawResult() { return result; }
+        public final void compute() {
+            final BiFunction<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer;
+            if ((reducer = this.reducer) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new ReduceEntriesTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, reducer)).fork();
+                }
+                Map.Entry<K,V> r = null;
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = (r == null) ? p : reducer.apply(r, p);
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    ReduceEntriesTask<K,V>
+                        t = (ReduceEntriesTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        Map.Entry<K,V> tr, sr;
+                        if ((sr = s.result) != null)
+                            t.result = (((tr = t.result) == null) ? sr :
+                                        reducer.apply(tr, sr));
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceKeysTask<K,V,U>
+        extends BulkTask<K,V,U> {
+        final Function<? super K, ? extends U> transformer;
+        final BiFunction<? super U, ? super U, ? extends U> reducer;
+        U result;
+        MapReduceKeysTask<K,V,U> rights, nextRight;
+        MapReduceKeysTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceKeysTask<K,V,U> nextRight,
+             Function<? super K, ? extends U> transformer,
+             BiFunction<? super U, ? super U, ? extends U> reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.reducer = reducer;
+        }
+        public final U getRawResult() { return result; }
+        public final void compute() {
+            final Function<? super K, ? extends U> transformer;
+            final BiFunction<? super U, ? super U, ? extends U> reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceKeysTask<K,V,U>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, reducer)).fork();
+                }
+                U r = null;
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    U u;
+                    if ((u = transformer.apply(p.key)) != null)
+                        r = (r == null) ? u : reducer.apply(r, u);
+                }
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceKeysTask<K,V,U>
+                        t = (MapReduceKeysTask<K,V,U>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        U tr, sr;
+                        if ((sr = s.result) != null)
+                            t.result = (((tr = t.result) == null) ? sr :
+                                        reducer.apply(tr, sr));
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceValuesTask<K,V,U>
+        extends BulkTask<K,V,U> {
+        final Function<? super V, ? extends U> transformer;
+        final BiFunction<? super U, ? super U, ? extends U> reducer;
+        U result;
+        MapReduceValuesTask<K,V,U> rights, nextRight;
+        MapReduceValuesTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceValuesTask<K,V,U> nextRight,
+             Function<? super V, ? extends U> transformer,
+             BiFunction<? super U, ? super U, ? extends U> reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.reducer = reducer;
+        }
+        public final U getRawResult() { return result; }
+        public final void compute() {
+            final Function<? super V, ? extends U> transformer;
+            final BiFunction<? super U, ? super U, ? extends U> reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceValuesTask<K,V,U>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, reducer)).fork();
+                }
+                U r = null;
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    U u;
+                    if ((u = transformer.apply(p.val)) != null)
+                        r = (r == null) ? u : reducer.apply(r, u);
+                }
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceValuesTask<K,V,U>
+                        t = (MapReduceValuesTask<K,V,U>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        U tr, sr;
+                        if ((sr = s.result) != null)
+                            t.result = (((tr = t.result) == null) ? sr :
+                                        reducer.apply(tr, sr));
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceEntriesTask<K,V,U>
+        extends BulkTask<K,V,U> {
+        final Function<Map.Entry<K,V>, ? extends U> transformer;
+        final BiFunction<? super U, ? super U, ? extends U> reducer;
+        U result;
+        MapReduceEntriesTask<K,V,U> rights, nextRight;
+        MapReduceEntriesTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceEntriesTask<K,V,U> nextRight,
+             Function<Map.Entry<K,V>, ? extends U> transformer,
+             BiFunction<? super U, ? super U, ? extends U> reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.reducer = reducer;
+        }
+        public final U getRawResult() { return result; }
+        public final void compute() {
+            final Function<Map.Entry<K,V>, ? extends U> transformer;
+            final BiFunction<? super U, ? super U, ? extends U> reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceEntriesTask<K,V,U>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, reducer)).fork();
+                }
+                U r = null;
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    U u;
+                    if ((u = transformer.apply(p)) != null)
+                        r = (r == null) ? u : reducer.apply(r, u);
+                }
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceEntriesTask<K,V,U>
+                        t = (MapReduceEntriesTask<K,V,U>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        U tr, sr;
+                        if ((sr = s.result) != null)
+                            t.result = (((tr = t.result) == null) ? sr :
+                                        reducer.apply(tr, sr));
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceMappingsTask<K,V,U>
+        extends BulkTask<K,V,U> {
+        final BiFunction<? super K, ? super V, ? extends U> transformer;
+        final BiFunction<? super U, ? super U, ? extends U> reducer;
+        U result;
+        MapReduceMappingsTask<K,V,U> rights, nextRight;
+        MapReduceMappingsTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceMappingsTask<K,V,U> nextRight,
+             BiFunction<? super K, ? super V, ? extends U> transformer,
+             BiFunction<? super U, ? super U, ? extends U> reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.reducer = reducer;
+        }
+        public final U getRawResult() { return result; }
+        public final void compute() {
+            final BiFunction<? super K, ? super V, ? extends U> transformer;
+            final BiFunction<? super U, ? super U, ? extends U> reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceMappingsTask<K,V,U>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, reducer)).fork();
+                }
+                U r = null;
+                for (Node<K,V> p; (p = advance()) != null; ) {
+                    U u;
+                    if ((u = transformer.apply(p.key, p.val)) != null)
+                        r = (r == null) ? u : reducer.apply(r, u);
+                }
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceMappingsTask<K,V,U>
+                        t = (MapReduceMappingsTask<K,V,U>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        U tr, sr;
+                        if ((sr = s.result) != null)
+                            t.result = (((tr = t.result) == null) ? sr :
+                                        reducer.apply(tr, sr));
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceKeysToDoubleTask<K,V>
+        extends BulkTask<K,V,Double> {
+        final ToDoubleFunction<? super K> transformer;
+        final DoubleBinaryOperator reducer;
+        final double basis;
+        double result;
+        MapReduceKeysToDoubleTask<K,V> rights, nextRight;
+        MapReduceKeysToDoubleTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceKeysToDoubleTask<K,V> nextRight,
+             ToDoubleFunction<? super K> transformer,
+             double basis,
+             DoubleBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Double getRawResult() { return result; }
+        public final void compute() {
+            final ToDoubleFunction<? super K> transformer;
+            final DoubleBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                double r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceKeysToDoubleTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsDouble(r, transformer.applyAsDouble(p.key));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceKeysToDoubleTask<K,V>
+                        t = (MapReduceKeysToDoubleTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsDouble(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceValuesToDoubleTask<K,V>
+        extends BulkTask<K,V,Double> {
+        final ToDoubleFunction<? super V> transformer;
+        final DoubleBinaryOperator reducer;
+        final double basis;
+        double result;
+        MapReduceValuesToDoubleTask<K,V> rights, nextRight;
+        MapReduceValuesToDoubleTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceValuesToDoubleTask<K,V> nextRight,
+             ToDoubleFunction<? super V> transformer,
+             double basis,
+             DoubleBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Double getRawResult() { return result; }
+        public final void compute() {
+            final ToDoubleFunction<? super V> transformer;
+            final DoubleBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                double r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceValuesToDoubleTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsDouble(r, transformer.applyAsDouble(p.val));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceValuesToDoubleTask<K,V>
+                        t = (MapReduceValuesToDoubleTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsDouble(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceEntriesToDoubleTask<K,V>
+        extends BulkTask<K,V,Double> {
+        final ToDoubleFunction<Map.Entry<K,V>> transformer;
+        final DoubleBinaryOperator reducer;
+        final double basis;
+        double result;
+        MapReduceEntriesToDoubleTask<K,V> rights, nextRight;
+        MapReduceEntriesToDoubleTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceEntriesToDoubleTask<K,V> nextRight,
+             ToDoubleFunction<Map.Entry<K,V>> transformer,
+             double basis,
+             DoubleBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Double getRawResult() { return result; }
+        public final void compute() {
+            final ToDoubleFunction<Map.Entry<K,V>> transformer;
+            final DoubleBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                double r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceEntriesToDoubleTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsDouble(r, transformer.applyAsDouble(p));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceEntriesToDoubleTask<K,V>
+                        t = (MapReduceEntriesToDoubleTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsDouble(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceMappingsToDoubleTask<K,V>
+        extends BulkTask<K,V,Double> {
+        final ToDoubleBiFunction<? super K, ? super V> transformer;
+        final DoubleBinaryOperator reducer;
+        final double basis;
+        double result;
+        MapReduceMappingsToDoubleTask<K,V> rights, nextRight;
+        MapReduceMappingsToDoubleTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceMappingsToDoubleTask<K,V> nextRight,
+             ToDoubleBiFunction<? super K, ? super V> transformer,
+             double basis,
+             DoubleBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Double getRawResult() { return result; }
+        public final void compute() {
+            final ToDoubleBiFunction<? super K, ? super V> transformer;
+            final DoubleBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                double r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceMappingsToDoubleTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsDouble(r, transformer.applyAsDouble(p.key, p.val));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceMappingsToDoubleTask<K,V>
+                        t = (MapReduceMappingsToDoubleTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsDouble(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceKeysToLongTask<K,V>
+        extends BulkTask<K,V,Long> {
+        final ToLongFunction<? super K> transformer;
+        final LongBinaryOperator reducer;
+        final long basis;
+        long result;
+        MapReduceKeysToLongTask<K,V> rights, nextRight;
+        MapReduceKeysToLongTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceKeysToLongTask<K,V> nextRight,
+             ToLongFunction<? super K> transformer,
+             long basis,
+             LongBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Long getRawResult() { return result; }
+        public final void compute() {
+            final ToLongFunction<? super K> transformer;
+            final LongBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                long r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceKeysToLongTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsLong(r, transformer.applyAsLong(p.key));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceKeysToLongTask<K,V>
+                        t = (MapReduceKeysToLongTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsLong(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceValuesToLongTask<K,V>
+        extends BulkTask<K,V,Long> {
+        final ToLongFunction<? super V> transformer;
+        final LongBinaryOperator reducer;
+        final long basis;
+        long result;
+        MapReduceValuesToLongTask<K,V> rights, nextRight;
+        MapReduceValuesToLongTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceValuesToLongTask<K,V> nextRight,
+             ToLongFunction<? super V> transformer,
+             long basis,
+             LongBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Long getRawResult() { return result; }
+        public final void compute() {
+            final ToLongFunction<? super V> transformer;
+            final LongBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                long r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceValuesToLongTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsLong(r, transformer.applyAsLong(p.val));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceValuesToLongTask<K,V>
+                        t = (MapReduceValuesToLongTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsLong(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceEntriesToLongTask<K,V>
+        extends BulkTask<K,V,Long> {
+        final ToLongFunction<Map.Entry<K,V>> transformer;
+        final LongBinaryOperator reducer;
+        final long basis;
+        long result;
+        MapReduceEntriesToLongTask<K,V> rights, nextRight;
+        MapReduceEntriesToLongTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceEntriesToLongTask<K,V> nextRight,
+             ToLongFunction<Map.Entry<K,V>> transformer,
+             long basis,
+             LongBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Long getRawResult() { return result; }
+        public final void compute() {
+            final ToLongFunction<Map.Entry<K,V>> transformer;
+            final LongBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                long r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceEntriesToLongTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsLong(r, transformer.applyAsLong(p));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceEntriesToLongTask<K,V>
+                        t = (MapReduceEntriesToLongTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsLong(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceMappingsToLongTask<K,V>
+        extends BulkTask<K,V,Long> {
+        final ToLongBiFunction<? super K, ? super V> transformer;
+        final LongBinaryOperator reducer;
+        final long basis;
+        long result;
+        MapReduceMappingsToLongTask<K,V> rights, nextRight;
+        MapReduceMappingsToLongTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceMappingsToLongTask<K,V> nextRight,
+             ToLongBiFunction<? super K, ? super V> transformer,
+             long basis,
+             LongBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Long getRawResult() { return result; }
+        public final void compute() {
+            final ToLongBiFunction<? super K, ? super V> transformer;
+            final LongBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                long r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceMappingsToLongTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsLong(r, transformer.applyAsLong(p.key, p.val));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceMappingsToLongTask<K,V>
+                        t = (MapReduceMappingsToLongTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsLong(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceKeysToIntTask<K,V>
+        extends BulkTask<K,V,Integer> {
+        final ToIntFunction<? super K> transformer;
+        final IntBinaryOperator reducer;
+        final int basis;
+        int result;
+        MapReduceKeysToIntTask<K,V> rights, nextRight;
+        MapReduceKeysToIntTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceKeysToIntTask<K,V> nextRight,
+             ToIntFunction<? super K> transformer,
+             int basis,
+             IntBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Integer getRawResult() { return result; }
+        public final void compute() {
+            final ToIntFunction<? super K> transformer;
+            final IntBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                int r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceKeysToIntTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsInt(r, transformer.applyAsInt(p.key));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceKeysToIntTask<K,V>
+                        t = (MapReduceKeysToIntTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsInt(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceValuesToIntTask<K,V>
+        extends BulkTask<K,V,Integer> {
+        final ToIntFunction<? super V> transformer;
+        final IntBinaryOperator reducer;
+        final int basis;
+        int result;
+        MapReduceValuesToIntTask<K,V> rights, nextRight;
+        MapReduceValuesToIntTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceValuesToIntTask<K,V> nextRight,
+             ToIntFunction<? super V> transformer,
+             int basis,
+             IntBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Integer getRawResult() { return result; }
+        public final void compute() {
+            final ToIntFunction<? super V> transformer;
+            final IntBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                int r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceValuesToIntTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsInt(r, transformer.applyAsInt(p.val));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceValuesToIntTask<K,V>
+                        t = (MapReduceValuesToIntTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsInt(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceEntriesToIntTask<K,V>
+        extends BulkTask<K,V,Integer> {
+        final ToIntFunction<Map.Entry<K,V>> transformer;
+        final IntBinaryOperator reducer;
+        final int basis;
+        int result;
+        MapReduceEntriesToIntTask<K,V> rights, nextRight;
+        MapReduceEntriesToIntTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceEntriesToIntTask<K,V> nextRight,
+             ToIntFunction<Map.Entry<K,V>> transformer,
+             int basis,
+             IntBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Integer getRawResult() { return result; }
+        public final void compute() {
+            final ToIntFunction<Map.Entry<K,V>> transformer;
+            final IntBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                int r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceEntriesToIntTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsInt(r, transformer.applyAsInt(p));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceEntriesToIntTask<K,V>
+                        t = (MapReduceEntriesToIntTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsInt(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class MapReduceMappingsToIntTask<K,V>
+        extends BulkTask<K,V,Integer> {
+        final ToIntBiFunction<? super K, ? super V> transformer;
+        final IntBinaryOperator reducer;
+        final int basis;
+        int result;
+        MapReduceMappingsToIntTask<K,V> rights, nextRight;
+        MapReduceMappingsToIntTask
+            (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
+             MapReduceMappingsToIntTask<K,V> nextRight,
+             ToIntBiFunction<? super K, ? super V> transformer,
+             int basis,
+             IntBinaryOperator reducer) {
+            super(p, b, i, f, t); this.nextRight = nextRight;
+            this.transformer = transformer;
+            this.basis = basis; this.reducer = reducer;
+        }
+        public final Integer getRawResult() { return result; }
+        public final void compute() {
+            final ToIntBiFunction<? super K, ? super V> transformer;
+            final IntBinaryOperator reducer;
+            if ((transformer = this.transformer) != null &&
+                (reducer = this.reducer) != null) {
+                int r = this.basis;
+                for (int i = baseIndex, f, h; batch > 0 &&
+                         (h = ((f = baseLimit) + i) >>> 1) > i;) {
+                    addToPendingCount(1);
+                    (rights = new MapReduceMappingsToIntTask<K,V>
+                     (this, batch >>>= 1, baseLimit = h, f, tab,
+                      rights, transformer, r, reducer)).fork();
+                }
+                for (Node<K,V> p; (p = advance()) != null; )
+                    r = reducer.applyAsInt(r, transformer.applyAsInt(p.key, p.val));
+                result = r;
+                CountedCompleter<?> c;
+                for (c = firstComplete(); c != null; c = c.nextComplete()) {
+                    @SuppressWarnings("unchecked")
+                    MapReduceMappingsToIntTask<K,V>
+                        t = (MapReduceMappingsToIntTask<K,V>)c,
+                        s = t.rights;
+                    while (s != null) {
+                        t.result = reducer.applyAsInt(t.result, s.result);
+                        s = t.rights = s.nextRight;
+                    }
+                }
+            }
+        }
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
     private static final long SIZECTL;
     private static final long TRANSFERINDEX;
     private static final long BASECOUNT;
     private static final long CELLSBUSY;
     private static final long CELLVALUE;
-    private static final long ABASE;
+    private static final int ABASE;
     private static final int ASHIFT;
 
     static {
         try {
-            U = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = ConcurrentHashMap.class;
             SIZECTL = U.objectFieldOffset
-                (k.getDeclaredField("sizeCtl"));
+                (ConcurrentHashMap.class.getDeclaredField("sizeCtl"));
             TRANSFERINDEX = U.objectFieldOffset
-                (k.getDeclaredField("transferIndex"));
+                (ConcurrentHashMap.class.getDeclaredField("transferIndex"));
             BASECOUNT = U.objectFieldOffset
-                (k.getDeclaredField("baseCount"));
+                (ConcurrentHashMap.class.getDeclaredField("baseCount"));
             CELLSBUSY = U.objectFieldOffset
-                (k.getDeclaredField("cellsBusy"));
-            Class<?> ck = CounterCell.class;
+                (ConcurrentHashMap.class.getDeclaredField("cellsBusy"));
+
             CELLVALUE = U.objectFieldOffset
-                (ck.getDeclaredField("value"));
-            Class<?> ak = Node[].class;
-            ABASE = U.arrayBaseOffset(ak);
-            int scale = U.arrayIndexScale(ak);
+                (CounterCell.class.getDeclaredField("value"));
+
+            ABASE = U.arrayBaseOffset(Node[].class);
+            int scale = U.arrayIndexScale(Node[].class);
             if ((scale & (scale - 1)) != 0)
-                throw new Error("data type scale not a power of two");
+                throw new Error("array index scale not a power of two");
             ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
-        } catch (Exception e) {
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
 
@@ -3329,5 +6347,4 @@
         // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
         Class<?> ensureLoaded = LockSupport.class;
     }
-
 }
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java
index b38d6a5..7084d14 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java
@@ -7,12 +7,16 @@
 package java.util.concurrent;
 
 import java.util.AbstractCollection;
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Deque;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Queue;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -27,12 +31,8 @@
  * Like most other concurrent collection implementations, this class
  * does not permit the use of {@code null} elements.
  *
- * <p>Iterators are <i>weakly consistent</i>, returning elements
- * reflecting the state of the deque at some point at or since the
- * creation of the iterator.  They do <em>not</em> throw {@link
- * java.util.ConcurrentModificationException
- * ConcurrentModificationException}, and may proceed concurrently with
- * other operations.
+ * <p>Iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
  *
  * <p>Beware that, unlike in most collections, the {@code size} method
  * is <em>NOT</em> a constant-time operation. Because of the
@@ -59,7 +59,7 @@
  * @since 1.7
  * @author Doug Lea
  * @author Martin Buchholz
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this deque
  */
 public class ConcurrentLinkedDeque<E>
     extends AbstractCollection<E>
@@ -272,47 +272,45 @@
          * only be seen after publication via casNext or casPrev.
          */
         Node(E item) {
-            UNSAFE.putObject(this, itemOffset, item);
+            U.putObject(this, ITEM, item);
         }
 
         boolean casItem(E cmp, E val) {
-            return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
+            return U.compareAndSwapObject(this, ITEM, cmp, val);
         }
 
         void lazySetNext(Node<E> val) {
-            UNSAFE.putOrderedObject(this, nextOffset, val);
+            U.putOrderedObject(this, NEXT, val);
         }
 
         boolean casNext(Node<E> cmp, Node<E> val) {
-            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
+            return U.compareAndSwapObject(this, NEXT, cmp, val);
         }
 
         void lazySetPrev(Node<E> val) {
-            UNSAFE.putOrderedObject(this, prevOffset, val);
+            U.putOrderedObject(this, PREV, val);
         }
 
         boolean casPrev(Node<E> cmp, Node<E> val) {
-            return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
+            return U.compareAndSwapObject(this, PREV, cmp, val);
         }
 
         // Unsafe mechanics
 
-        private static final sun.misc.Unsafe UNSAFE;
-        private static final long prevOffset;
-        private static final long itemOffset;
-        private static final long nextOffset;
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final long PREV;
+        private static final long ITEM;
+        private static final long NEXT;
 
         static {
             try {
-                UNSAFE = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = Node.class;
-                prevOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("prev"));
-                itemOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("item"));
-                nextOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("next"));
-            } catch (Exception e) {
+                PREV = U.objectFieldOffset
+                    (Node.class.getDeclaredField("prev"));
+                ITEM = U.objectFieldOffset
+                    (Node.class.getDeclaredField("item"));
+                NEXT = U.objectFieldOffset
+                    (Node.class.getDeclaredField("next"));
+            } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
         }
@@ -322,8 +320,7 @@
      * Links e as first element.
      */
     private void linkFirst(E e) {
-        checkNotNull(e);
-        final Node<E> newNode = new Node<E>(e);
+        final Node<E> newNode = new Node<E>(Objects.requireNonNull(e));
 
         restartFromHead:
         for (;;)
@@ -355,8 +352,7 @@
      * Links e as last element.
      */
     private void linkLast(E e) {
-        checkNotNull(e);
-        final Node<E> newNode = new Node<E>(e);
+        final Node<E> newNode = new Node<E>(Objects.requireNonNull(e));
 
         restartFromTail:
         for (;;)
@@ -761,16 +757,6 @@
     // Minor convenience utilities
 
     /**
-     * Throws NullPointerException if argument is null.
-     *
-     * @param v the element
-     */
-    private static void checkNotNull(Object v) {
-        if (v == null)
-            throw new NullPointerException();
-    }
-
-    /**
      * Returns element unless it is null, in which case throws
      * NoSuchElementException.
      *
@@ -784,22 +770,6 @@
     }
 
     /**
-     * Creates an array list and fills it with elements of this list.
-     * Used by toArray.
-     *
-     * @return the array list
-     */
-    private ArrayList<E> toArrayList() {
-        ArrayList<E> list = new ArrayList<E>();
-        for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.item;
-            if (item != null)
-                list.add(item);
-        }
-        return list;
-    }
-
-    /**
      * Constructs an empty deque.
      */
     public ConcurrentLinkedDeque() {
@@ -819,8 +789,7 @@
         // Copy c into a private chain of Nodes
         Node<E> h = null, t = null;
         for (E e : c) {
-            checkNotNull(e);
-            Node<E> newNode = new Node<E>(e);
+            Node<E> newNode = new Node<E>(Objects.requireNonNull(e));
             if (h == null)
                 h = t = newNode;
             else {
@@ -995,23 +964,42 @@
     }
 
     public E poll()           { return pollFirst(); }
-    public E remove()         { return removeFirst(); }
     public E peek()           { return peekFirst(); }
-    public E element()        { return getFirst(); }
-    public void push(E e)     { addFirst(e); }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E remove()         { return removeFirst(); }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
     public E pop()            { return removeFirst(); }
 
     /**
-     * Removes the first element {@code e} such that
-     * {@code o.equals(e)}, if such an element exists in this deque.
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E element()        { return getFirst(); }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void push(E e)     { addFirst(e); }
+
+    /**
+     * 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 {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
+     * (or equivalently, if this deque changed as a result of the call).
      *
      * @param o element to be removed from this deque, if present
      * @return {@code true} if the deque contained the specified element
      * @throws NullPointerException if the specified element is null
      */
     public boolean removeFirstOccurrence(Object o) {
-        checkNotNull(o);
+        Objects.requireNonNull(o);
         for (Node<E> p = first(); p != null; p = succ(p)) {
             E item = p.item;
             if (item != null && o.equals(item) && p.casItem(item, null)) {
@@ -1023,16 +1011,19 @@
     }
 
     /**
-     * Removes the last element {@code e} such that
-     * {@code o.equals(e)}, if such an element exists in this deque.
+     * 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 {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
+     * (or equivalently, if this deque changed as a result of the call).
      *
      * @param o element to be removed from this deque, if present
      * @return {@code true} if the deque contained the specified element
      * @throws NullPointerException if the specified element is null
      */
     public boolean removeLastOccurrence(Object o) {
-        checkNotNull(o);
+        Objects.requireNonNull(o);
         for (Node<E> p = last(); p != null; p = pred(p)) {
             E item = p.item;
             if (item != null && o.equals(item) && p.casItem(item, null)) {
@@ -1044,18 +1035,20 @@
     }
 
     /**
-     * Returns {@code true} if this deque contains at least one
-     * element {@code e} such that {@code o.equals(e)}.
+     * Returns {@code true} if this deque contains the specified element.
+     * More formally, returns {@code true} if and only if this deque contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
      *
      * @param o element whose presence in this deque is to be tested
      * @return {@code true} if this deque contains the specified element
      */
     public boolean contains(Object o) {
-        if (o == null) return false;
-        for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.item;
-            if (item != null && o.equals(item))
-                return true;
+        if (o != null) {
+            for (Node<E> p = first(); p != null; p = succ(p)) {
+                E item = p.item;
+                if (item != null && o.equals(item))
+                    return true;
+            }
         }
         return false;
     }
@@ -1086,19 +1079,28 @@
      * @return the number of elements in this deque
      */
     public int size() {
-        int count = 0;
-        for (Node<E> p = first(); p != null; p = succ(p))
-            if (p.item != null)
-                // Collection.size() spec says to max out
-                if (++count == Integer.MAX_VALUE)
-                    break;
-        return count;
+        restartFromHead: for (;;) {
+            int count = 0;
+            for (Node<E> p = first(); p != null;) {
+                if (p.item != null)
+                    if (++count == Integer.MAX_VALUE)
+                        break;  // @see Collection.size()
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+            return count;
+        }
     }
 
     /**
-     * Removes the first element {@code e} such that
-     * {@code o.equals(e)}, if such an element exists in this deque.
+     * 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 {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
+     * (or equivalently, if this deque changed as a result of the call).
+     *
+     * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
      *
      * @param o element to be removed from this deque, if present
      * @return {@code true} if the deque contained the specified element
@@ -1128,8 +1130,7 @@
         // Copy c into a private chain of Nodes
         Node<E> beginningOfTheEnd = null, last = null;
         for (E e : c) {
-            checkNotNull(e);
-            Node<E> newNode = new Node<E>(e);
+            Node<E> newNode = new Node<E>(Objects.requireNonNull(e));
             if (beginningOfTheEnd == null)
                 beginningOfTheEnd = last = newNode;
             else {
@@ -1180,6 +1181,62 @@
             ;
     }
 
+    public String toString() {
+        String[] a = null;
+        restartFromHead: for (;;) {
+            int charLength = 0;
+            int size = 0;
+            for (Node<E> p = first(); p != null;) {
+                E item = p.item;
+                if (item != null) {
+                    if (a == null)
+                        a = new String[4];
+                    else if (size == a.length)
+                        a = Arrays.copyOf(a, 2 * size);
+                    String s = item.toString();
+                    a[size++] = s;
+                    charLength += s.length();
+                }
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+
+            if (size == 0)
+                return "[]";
+
+            return Helpers.toString(a, size, charLength);
+        }
+    }
+
+    private Object[] toArrayInternal(Object[] a) {
+        Object[] x = a;
+        restartFromHead: for (;;) {
+            int size = 0;
+            for (Node<E> p = first(); p != null;) {
+                E item = p.item;
+                if (item != null) {
+                    if (x == null)
+                        x = new Object[4];
+                    else if (size == x.length)
+                        x = Arrays.copyOf(x, 2 * (size + 4));
+                    x[size++] = item;
+                }
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+            if (x == null)
+                return new Object[0];
+            else if (a != null && size <= a.length) {
+                if (a != x)
+                    System.arraycopy(x, 0, a, 0, size);
+                if (size < a.length)
+                    a[size] = null;
+                return a;
+            }
+            return (size == x.length) ? x : Arrays.copyOf(x, size);
+        }
+    }
+
     /**
      * Returns an array containing all of the elements in this deque, in
      * proper sequence (from first to last element).
@@ -1194,7 +1251,7 @@
      * @return an array containing all of the elements in this deque
      */
     public Object[] toArray() {
-        return toArrayList().toArray();
+        return toArrayInternal(null);
     }
 
     /**
@@ -1220,7 +1277,7 @@
      * The following code can be used to dump the deque into a newly
      * allocated array of {@code String}:
      *
-     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -1234,20 +1291,18 @@
      *         this deque
      * @throws NullPointerException if the specified array is null
      */
+    @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
-        return toArrayList().toArray(a);
+        if (a == null) throw new NullPointerException();
+        return (T[]) toArrayInternal(a);
     }
 
     /**
      * Returns an iterator over the elements in this deque in proper sequence.
      * The elements will be returned in order from first (head) to last (tail).
      *
-     * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException}, and guarantees to traverse
-     * elements as they existed upon construction of the iterator, and
-     * may (but is not guaranteed to) reflect any modifications
-     * subsequent to construction.
+     * <p>The returned iterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return an iterator over the elements in this deque in proper sequence
      */
@@ -1260,12 +1315,8 @@
      * sequential order.  The elements will be returned in order from
      * last (tail) to first (head).
      *
-     * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException}, and guarantees to traverse
-     * elements as they existed upon construction of the iterator, and
-     * may (but is not guaranteed to) reflect any modifications
-     * subsequent to construction.
+     * <p>The returned iterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return an iterator over the elements in this deque in reverse order
      */
@@ -1310,7 +1361,7 @@
             Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
             for (;; p = nextNode(p)) {
                 if (p == null) {
-                    // p might be active end or TERMINATOR node; both are OK
+                    // might be at active end or TERMINATOR node; both are OK
                     nextNode = null;
                     nextItem = null;
                     break;
@@ -1356,9 +1407,121 @@
         Node<E> nextNode(Node<E> p) { return pred(p); }
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class CLDSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final ConcurrentLinkedDeque<E> queue;
+        Node<E> current;    // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        CLDSpliterator(ConcurrentLinkedDeque<E> queue) {
+            this.queue = queue;
+        }
+
+        public Spliterator<E> trySplit() {
+            Node<E> p;
+            final ConcurrentLinkedDeque<E> q = this.queue;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                if (p.item == null && p == (p = p.next))
+                    current = p = q.first();
+                if (p != null && p.next != null) {
+                    Object[] a = new Object[n];
+                    int i = 0;
+                    do {
+                        if ((a[i] = p.item) != null)
+                            ++i;
+                        if (p == (p = p.next))
+                            p = q.first();
+                    } while (p != null && i < n);
+                    if ((current = p) == null)
+                        exhausted = true;
+                    if (i > 0) {
+                        batch = i;
+                        return Spliterators.spliterator
+                            (a, 0, i, (Spliterator.ORDERED |
+                                       Spliterator.NONNULL |
+                                       Spliterator.CONCURRENT));
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            Node<E> p;
+            if (action == null) throw new NullPointerException();
+            final ConcurrentLinkedDeque<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                exhausted = true;
+                do {
+                    E e = p.item;
+                    if (p == (p = p.next))
+                        p = q.first();
+                    if (e != null)
+                        action.accept(e);
+                } while (p != null);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            Node<E> p;
+            if (action == null) throw new NullPointerException();
+            final ConcurrentLinkedDeque<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                E e;
+                do {
+                    e = p.item;
+                    if (p == (p = p.next))
+                        p = q.first();
+                } while (e == null && p != null);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept(e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public long estimateSize() { return Long.MAX_VALUE; }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
+    /**
+     * Returns a {@link Spliterator} over the elements in this deque.
+     *
+     * <p>The returned spliterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+     *
+     * @implNote
+     * The {@code Spliterator} implements {@code trySplit} to permit limited
+     * parallelism.
+     *
+     * @return a {@code Spliterator} over the elements in this deque
+     * @since 1.8
+     */
+    public Spliterator<E> spliterator() {
+        return new CLDSpliterator<E>(this);
+    }
+
     /**
      * Saves this deque to a stream (that is, serializes it).
      *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData All of the elements (each an {@code E}) in
      * the proper order, followed by a null
      */
@@ -1381,6 +1544,10 @@
 
     /**
      * Reconstitutes this deque from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
@@ -1388,8 +1555,7 @@
 
         // Read in elements until trailing null sentinel found
         Node<E> h = null, t = null;
-        Object item;
-        while ((item = s.readObject()) != null) {
+        for (Object item; (item = s.readObject()) != null; ) {
             @SuppressWarnings("unchecked")
             Node<E> newNode = new Node<E>((E) item);
             if (h == null)
@@ -1404,31 +1570,29 @@
     }
 
     private boolean casHead(Node<E> cmp, Node<E> val) {
-        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
+        return U.compareAndSwapObject(this, HEAD, cmp, val);
     }
 
     private boolean casTail(Node<E> cmp, Node<E> val) {
-        return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
+        return U.compareAndSwapObject(this, TAIL, cmp, val);
     }
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe UNSAFE;
-    private static final long headOffset;
-    private static final long tailOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long HEAD;
+    private static final long TAIL;
     static {
         PREV_TERMINATOR = new Node<Object>();
         PREV_TERMINATOR.next = PREV_TERMINATOR;
         NEXT_TERMINATOR = new Node<Object>();
         NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
         try {
-            UNSAFE = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = ConcurrentLinkedDeque.class;
-            headOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("head"));
-            tailOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("tail"));
-        } catch (Exception e) {
+            HEAD = U.objectFieldOffset
+                (ConcurrentLinkedDeque.class.getDeclaredField("head"));
+            TAIL = U.objectFieldOffset
+                (ConcurrentLinkedDeque.class.getDeclaredField("tail"));
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
     }
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
index 9010cbe..e96b1b8 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
@@ -7,11 +7,15 @@
 package java.util.concurrent;
 
 import java.util.AbstractQueue;
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Queue;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -68,7 +72,7 @@
  *
  * @since 1.5
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
         implements Queue<E>, java.io.Serializable {
@@ -148,45 +152,28 @@
     private static class Node<E> {
         volatile E item;
         volatile Node<E> next;
+    }
 
-        /**
-         * Constructs a new node.  Uses relaxed write because item can
-         * only be seen after publication via casNext.
-         */
-        Node(E item) {
-            UNSAFE.putObject(this, itemOffset, item);
-        }
+    /**
+     * Returns a new node holding item.  Uses relaxed write because item
+     * can only be seen after piggy-backing publication via casNext.
+     */
+    static <E> Node<E> newNode(E item) {
+        Node<E> node = new Node<E>();
+        U.putObject(node, ITEM, item);
+        return node;
+    }
 
-        boolean casItem(E cmp, E val) {
-            return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
-        }
+    static <E> boolean casItem(Node<E> node, E cmp, E val) {
+        return U.compareAndSwapObject(node, ITEM, cmp, val);
+    }
 
-        void lazySetNext(Node<E> val) {
-            UNSAFE.putOrderedObject(this, nextOffset, val);
-        }
+    static <E> void lazySetNext(Node<E> node, Node<E> val) {
+        U.putOrderedObject(node, NEXT, val);
+    }
 
-        boolean casNext(Node<E> cmp, Node<E> val) {
-            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
-        }
-
-        // Unsafe mechanics
-
-        private static final sun.misc.Unsafe UNSAFE;
-        private static final long itemOffset;
-        private static final long nextOffset;
-
-        static {
-            try {
-                UNSAFE = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = Node.class;
-                itemOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("item"));
-                nextOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("next"));
-            } catch (Exception e) {
-                throw new Error(e);
-            }
-        }
+    static <E> boolean casNext(Node<E> node, Node<E> cmp, Node<E> val) {
+        return U.compareAndSwapObject(node, NEXT, cmp, val);
     }
 
     /**
@@ -201,7 +188,7 @@
      * - it is permitted for tail to lag behind head, that is, for tail
      *   to not be reachable from head!
      */
-    private transient volatile Node<E> head;
+    transient volatile Node<E> head;
 
     /**
      * A node from which the last node on list (that is, the unique
@@ -221,7 +208,7 @@
      * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
      */
     public ConcurrentLinkedQueue() {
-        head = tail = new Node<E>(null);
+        head = tail = newNode(null);
     }
 
     /**
@@ -236,17 +223,16 @@
     public ConcurrentLinkedQueue(Collection<? extends E> c) {
         Node<E> h = null, t = null;
         for (E e : c) {
-            checkNotNull(e);
-            Node<E> newNode = new Node<E>(e);
+            Node<E> newNode = newNode(Objects.requireNonNull(e));
             if (h == null)
                 h = t = newNode;
             else {
-                t.lazySetNext(newNode);
+                lazySetNext(t, newNode);
                 t = newNode;
             }
         }
         if (h == null)
-            h = t = new Node<E>(null);
+            h = t = newNode(null);
         head = h;
         tail = t;
     }
@@ -270,8 +256,9 @@
      * as sentinel for succ(), below.
      */
     final void updateHead(Node<E> h, Node<E> p) {
+        // assert h != null && p != null && (h == p || h.item == null);
         if (h != p && casHead(h, p))
-            h.lazySetNext(h);
+            lazySetNext(h, h);
     }
 
     /**
@@ -292,14 +279,13 @@
      * @throws NullPointerException if the specified element is null
      */
     public boolean offer(E e) {
-        checkNotNull(e);
-        final Node<E> newNode = new Node<E>(e);
+        final Node<E> newNode = newNode(Objects.requireNonNull(e));
 
         for (Node<E> t = tail, p = t;;) {
             Node<E> q = p.next;
             if (q == null) {
                 // p is last node
-                if (p.casNext(null, newNode)) {
+                if (casNext(p, null, newNode)) {
                     // Successful CAS is the linearization point
                     // for e to become an element of this queue,
                     // and for newNode to become "live".
@@ -327,7 +313,7 @@
             for (Node<E> h = head, p = h, q;;) {
                 E item = p.item;
 
-                if (item != null && p.casItem(item, null)) {
+                if (item != null && casItem(p, item, null)) {
                     // Successful CAS is the linearization point
                     // for item to be removed from this queue.
                     if (p != h) // hop two nodes at a time
@@ -414,13 +400,17 @@
      * @return the number of elements in this queue
      */
     public int size() {
-        int count = 0;
-        for (Node<E> p = first(); p != null; p = succ(p))
-            if (p.item != null)
-                // Collection.size() spec says to max out
-                if (++count == Integer.MAX_VALUE)
-                    break;
-        return count;
+        restartFromHead: for (;;) {
+            int count = 0;
+            for (Node<E> p = first(); p != null;) {
+                if (p.item != null)
+                    if (++count == Integer.MAX_VALUE)
+                        break;  // @see Collection.size()
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+            return count;
+        }
     }
 
     /**
@@ -432,11 +422,12 @@
      * @return {@code true} if this queue contains the specified element
      */
     public boolean contains(Object o) {
-        if (o == null) return false;
-        for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.item;
-            if (item != null && o.equals(item))
-                return true;
+        if (o != null) {
+            for (Node<E> p = first(); p != null; p = succ(p)) {
+                E item = p.item;
+                if (item != null && o.equals(item))
+                    return true;
+            }
         }
         return false;
     }
@@ -453,19 +444,25 @@
      * @return {@code true} if this queue changed as a result of the call
      */
     public boolean remove(Object o) {
-        if (o == null) return false;
-        Node<E> pred = null;
-        for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.item;
-            if (item != null &&
-                o.equals(item) &&
-                p.casItem(item, null)) {
-                Node<E> next = succ(p);
-                if (pred != null && next != null)
-                    pred.casNext(p, next);
-                return true;
+        if (o != null) {
+            Node<E> next, pred = null;
+            for (Node<E> p = first(); p != null; pred = p, p = next) {
+                boolean removed = false;
+                E item = p.item;
+                if (item != null) {
+                    if (!o.equals(item)) {
+                        next = succ(p);
+                        continue;
+                    }
+                    removed = casItem(p, item, null);
+                }
+
+                next = succ(p);
+                if (pred != null && next != null) // unlink
+                    casNext(pred, p, next);
+                if (removed)
+                    return true;
             }
-            pred = p;
         }
         return false;
     }
@@ -490,12 +487,11 @@
         // Copy c into a private chain of Nodes
         Node<E> beginningOfTheEnd = null, last = null;
         for (E e : c) {
-            checkNotNull(e);
-            Node<E> newNode = new Node<E>(e);
+            Node<E> newNode = newNode(Objects.requireNonNull(e));
             if (beginningOfTheEnd == null)
                 beginningOfTheEnd = last = newNode;
             else {
-                last.lazySetNext(newNode);
+                lazySetNext(last, newNode);
                 last = newNode;
             }
         }
@@ -507,7 +503,7 @@
             Node<E> q = p.next;
             if (q == null) {
                 // p is last node
-                if (p.casNext(null, beginningOfTheEnd)) {
+                if (casNext(p, null, beginningOfTheEnd)) {
                     // Successful CAS is the linearization point
                     // for all elements to be added to this queue.
                     if (!casTail(t, last)) {
@@ -533,6 +529,62 @@
         }
     }
 
+    public String toString() {
+        String[] a = null;
+        restartFromHead: for (;;) {
+            int charLength = 0;
+            int size = 0;
+            for (Node<E> p = first(); p != null;) {
+                E item = p.item;
+                if (item != null) {
+                    if (a == null)
+                        a = new String[4];
+                    else if (size == a.length)
+                        a = Arrays.copyOf(a, 2 * size);
+                    String s = item.toString();
+                    a[size++] = s;
+                    charLength += s.length();
+                }
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+
+            if (size == 0)
+                return "[]";
+
+            return Helpers.toString(a, size, charLength);
+        }
+    }
+
+    private Object[] toArrayInternal(Object[] a) {
+        Object[] x = a;
+        restartFromHead: for (;;) {
+            int size = 0;
+            for (Node<E> p = first(); p != null;) {
+                E item = p.item;
+                if (item != null) {
+                    if (x == null)
+                        x = new Object[4];
+                    else if (size == x.length)
+                        x = Arrays.copyOf(x, 2 * (size + 4));
+                    x[size++] = item;
+                }
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+            if (x == null)
+                return new Object[0];
+            else if (a != null && size <= a.length) {
+                if (a != x)
+                    System.arraycopy(x, 0, a, 0, size);
+                if (size < a.length)
+                    a[size] = null;
+                return a;
+            }
+            return (size == x.length) ? x : Arrays.copyOf(x, size);
+        }
+    }
+
     /**
      * Returns an array containing all of the elements in this queue, in
      * proper sequence.
@@ -547,14 +599,7 @@
      * @return an array containing all of the elements in this queue
      */
     public Object[] toArray() {
-        // Use ArrayList to deal with resizing.
-        ArrayList<E> al = new ArrayList<E>();
-        for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.item;
-            if (item != null)
-                al.add(item);
-        }
-        return al.toArray();
+        return toArrayInternal(null);
     }
 
     /**
@@ -578,7 +623,7 @@
      * The following code can be used to dump the queue into a newly
      * allocated array of {@code String}:
      *
-     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -594,40 +639,16 @@
      */
     @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
-        // try to use sent-in array
-        int k = 0;
-        Node<E> p;
-        for (p = first(); p != null && k < a.length; p = succ(p)) {
-            E item = p.item;
-            if (item != null)
-                a[k++] = (T)item;
-        }
-        if (p == null) {
-            if (k < a.length)
-                a[k] = null;
-            return a;
-        }
-
-        // If won't fit, use ArrayList version
-        ArrayList<E> al = new ArrayList<E>();
-        for (Node<E> q = first(); q != null; q = succ(q)) {
-            E item = q.item;
-            if (item != null)
-                al.add(item);
-        }
-        return al.toArray(a);
+        if (a == null) throw new NullPointerException();
+        return (T[]) toArrayInternal(a);
     }
 
     /**
      * Returns an iterator over the elements in this queue in proper sequence.
      * The elements will be returned in order from first (head) to last (tail).
      *
-     * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException}, and guarantees to traverse
-     * elements as they existed upon construction of the iterator, and
-     * may (but is not guaranteed to) reflect any modifications
-     * subsequent to construction.
+     * <p>The returned iterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return an iterator over the elements in this queue in proper sequence
      */
@@ -655,54 +676,47 @@
         private Node<E> lastRet;
 
         Itr() {
-            advance();
-        }
-
-        /**
-         * Moves to next valid node and returns item to return for
-         * next(), or null if no such.
-         */
-        private E advance() {
-            lastRet = nextNode;
-            E x = nextItem;
-
-            Node<E> pred, p;
-            if (nextNode == null) {
-                p = first();
-                pred = null;
-            } else {
-                pred = nextNode;
-                p = succ(nextNode);
-            }
-
-            for (;;) {
-                if (p == null) {
-                    nextNode = null;
-                    nextItem = null;
-                    return x;
+            restartFromHead: for (;;) {
+                Node<E> h, p, q;
+                for (p = h = head;; p = q) {
+                    E item;
+                    if ((item = p.item) != null) {
+                        nextNode = p;
+                        nextItem = item;
+                        break;
+                    }
+                    else if ((q = p.next) == null)
+                        break;
+                    else if (p == q)
+                        continue restartFromHead;
                 }
-                E item = p.item;
-                if (item != null) {
-                    nextNode = p;
-                    nextItem = item;
-                    return x;
-                } else {
-                    // skip over nulls
-                    Node<E> next = succ(p);
-                    if (pred != null && next != null)
-                        pred.casNext(p, next);
-                    p = next;
-                }
+                updateHead(h, p);
+                return;
             }
         }
 
         public boolean hasNext() {
-            return nextNode != null;
+            return nextItem != null;
         }
 
         public E next() {
-            if (nextNode == null) throw new NoSuchElementException();
-            return advance();
+            final Node<E> pred = nextNode;
+            if (pred == null) throw new NoSuchElementException();
+            // assert nextItem != null;
+            lastRet = pred;
+            E item = null;
+
+            for (Node<E> p = succ(pred), q;; p = q) {
+                if (p == null || (item = p.item) != null) {
+                    nextNode = p;
+                    E x = nextItem;
+                    nextItem = item;
+                    return x;
+                }
+                // unlink deleted nodes
+                if ((q = succ(p)) != null)
+                    casNext(pred, p, q);
+            }
         }
 
         public void remove() {
@@ -717,6 +731,8 @@
     /**
      * Saves this queue to a stream (that is, serializes it).
      *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData All of the elements (each an {@code E}) in
      * the proper order, followed by a null
      */
@@ -739,6 +755,10 @@
 
     /**
      * Reconstitutes this queue from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
@@ -746,55 +766,156 @@
 
         // Read in elements until trailing null sentinel found
         Node<E> h = null, t = null;
-        Object item;
-        while ((item = s.readObject()) != null) {
+        for (Object item; (item = s.readObject()) != null; ) {
             @SuppressWarnings("unchecked")
-            Node<E> newNode = new Node<E>((E) item);
+            Node<E> newNode = newNode((E) item);
             if (h == null)
                 h = t = newNode;
             else {
-                t.lazySetNext(newNode);
+                lazySetNext(t, newNode);
                 t = newNode;
             }
         }
         if (h == null)
-            h = t = new Node<E>(null);
+            h = t = newNode(null);
         head = h;
         tail = t;
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class CLQSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final ConcurrentLinkedQueue<E> queue;
+        Node<E> current;    // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        CLQSpliterator(ConcurrentLinkedQueue<E> queue) {
+            this.queue = queue;
+        }
+
+        public Spliterator<E> trySplit() {
+            Node<E> p;
+            final ConcurrentLinkedQueue<E> q = this.queue;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null) &&
+                p.next != null) {
+                Object[] a = new Object[n];
+                int i = 0;
+                do {
+                    if ((a[i] = p.item) != null)
+                        ++i;
+                    if (p == (p = p.next))
+                        p = q.first();
+                } while (p != null && i < n);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (i > 0) {
+                    batch = i;
+                    return Spliterators.spliterator
+                        (a, 0, i, (Spliterator.ORDERED |
+                                   Spliterator.NONNULL |
+                                   Spliterator.CONCURRENT));
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            Node<E> p;
+            if (action == null) throw new NullPointerException();
+            final ConcurrentLinkedQueue<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                exhausted = true;
+                do {
+                    E e = p.item;
+                    if (p == (p = p.next))
+                        p = q.first();
+                    if (e != null)
+                        action.accept(e);
+                } while (p != null);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            Node<E> p;
+            if (action == null) throw new NullPointerException();
+            final ConcurrentLinkedQueue<E> q = this.queue;
+            if (!exhausted &&
+                ((p = current) != null || (p = q.first()) != null)) {
+                E e;
+                do {
+                    e = p.item;
+                    if (p == (p = p.next))
+                        p = q.first();
+                } while (e == null && p != null);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept(e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public long estimateSize() { return Long.MAX_VALUE; }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
     /**
-     * Throws NullPointerException if argument is null.
+     * Returns a {@link Spliterator} over the elements in this queue.
      *
-     * @param v the element
+     * <p>The returned spliterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+     *
+     * @implNote
+     * The {@code Spliterator} implements {@code trySplit} to permit limited
+     * parallelism.
+     *
+     * @return a {@code Spliterator} over the elements in this queue
+     * @since 1.8
      */
-    private static void checkNotNull(Object v) {
-        if (v == null)
-            throw new NullPointerException();
+    @Override
+    public Spliterator<E> spliterator() {
+        return new CLQSpliterator<E>(this);
     }
 
     private boolean casTail(Node<E> cmp, Node<E> val) {
-        return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
+        return U.compareAndSwapObject(this, TAIL, cmp, val);
     }
 
     private boolean casHead(Node<E> cmp, Node<E> val) {
-        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
+        return U.compareAndSwapObject(this, HEAD, cmp, val);
     }
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe UNSAFE;
-    private static final long headOffset;
-    private static final long tailOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long HEAD;
+    private static final long TAIL;
+    private static final long ITEM;
+    private static final long NEXT;
     static {
         try {
-            UNSAFE = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = ConcurrentLinkedQueue.class;
-            headOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("head"));
-            tailOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("tail"));
-        } catch (Exception e) {
+            HEAD = U.objectFieldOffset
+                (ConcurrentLinkedQueue.class.getDeclaredField("head"));
+            TAIL = U.objectFieldOffset
+                (ConcurrentLinkedQueue.class.getDeclaredField("tail"));
+            ITEM = U.objectFieldOffset
+                (Node.class.getDeclaredField("item"));
+            NEXT = U.objectFieldOffset
+                (Node.class.getDeclaredField("next"));
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
     }
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentMap.java
index 1391f04..ae4d221 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentMap.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentMap.java
@@ -7,14 +7,27 @@
 package java.util.concurrent;
 
 import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
 
 // BEGIN android-note
 // removed link to collections framework docs
+// fixed framework docs link to "Collection#optional"
 // END android-note
 
 /**
- * A {@link java.util.Map} providing additional atomic
- * {@code putIfAbsent}, {@code remove}, and {@code replace} methods.
+ * A {@link java.util.Map} providing thread safety and atomicity
+ * guarantees.
+ *
+ * <p>To maintain the specified guarantees, default implementations of
+ * methods including {@link #putIfAbsent} inherited from {@link Map}
+ * must be overridden by implementations of this interface. Similarly,
+ * implementations of the collections returned by methods {@link
+ * #keySet}, {@link #values}, and {@link #entrySet} must override
+ * methods such as {@code removeIf} when necessary to
+ * preserve atomicity guarantees.
  *
  * <p>Memory consistency effects: As with other concurrent
  * collections, actions in a thread prior to placing an object into a
@@ -29,11 +42,65 @@
  * @param <V> the type of mapped values
  */
 public interface ConcurrentMap<K,V> extends Map<K,V> {
+
+    /**
+     * {@inheritDoc}
+     *
+     * @implNote This implementation assumes that the ConcurrentMap cannot
+     * contain null values and {@code get()} returning null unambiguously means
+     * the key is absent. Implementations which support null values
+     * <strong>must</strong> override this default implementation.
+     *
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    default V getOrDefault(Object key, V defaultValue) {
+        V v;
+        return ((v = get(key)) != null) ? v : defaultValue;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @implSpec The default implementation is equivalent to, for this
+     * {@code map}:
+     * <pre> {@code
+     * for (Map.Entry<K,V> entry : map.entrySet()) {
+     *   action.accept(entry.getKey(), entry.getValue());
+     * }}</pre>
+     *
+     * @implNote The default implementation assumes that
+     * {@code IllegalStateException} thrown by {@code getKey()} or
+     * {@code getValue()} indicates that the entry has been removed and cannot
+     * be processed. Operation continues for subsequent entries.
+     *
+     * @throws NullPointerException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    default void forEach(BiConsumer<? super K, ? super V> action) {
+        Objects.requireNonNull(action);
+        for (Map.Entry<K,V> entry : entrySet()) {
+            K k;
+            V v;
+            try {
+                k = entry.getKey();
+                v = entry.getValue();
+            } catch (IllegalStateException ise) {
+                // this usually means the entry is no longer in the map.
+                continue;
+            }
+            action.accept(k, v);
+        }
+    }
+
     /**
      * If the specified key is not already associated
-     * with a value, associate it with the given value.
-     * This is equivalent to
-     *  <pre> {@code
+     * with a value, associates it with the given value.
+     * This is equivalent to, for this {@code map}:
+     * <pre> {@code
      * if (!map.containsKey(key))
      *   return map.put(key, value);
      * else
@@ -41,6 +108,9 @@
      *
      * except that the action is performed atomically.
      *
+     * @implNote This implementation intentionally re-abstracts the
+     * inappropriate default provided in {@code Map}.
+     *
      * @param key key with which the specified value is to be associated
      * @param value value to be associated with the specified key
      * @return the previous value associated with the specified key, or
@@ -61,16 +131,21 @@
 
     /**
      * Removes the entry for a key only if currently mapped to a given value.
-     * This is equivalent to
-     *  <pre> {@code
-     * if (map.containsKey(key) && map.get(key).equals(value)) {
+     * This is equivalent to, for this {@code map}:
+     * <pre> {@code
+     * if (map.containsKey(key)
+     *     && Objects.equals(map.get(key), value)) {
      *   map.remove(key);
      *   return true;
-     * } else
-     *   return false;}</pre>
+     * } else {
+     *   return false;
+     * }}</pre>
      *
      * except that the action is performed atomically.
      *
+     * @implNote This implementation intentionally re-abstracts the
+     * inappropriate default provided in {@code Map}.
+     *
      * @param key key with which the specified value is associated
      * @param value value expected to be associated with the specified key
      * @return {@code true} if the value was removed
@@ -78,25 +153,30 @@
      *         is not supported by this map
      * @throws ClassCastException if the key or value is of an inappropriate
      *         type for this map
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified key or value is null,
      *         and this map does not permit null keys or values
-     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      */
     boolean remove(Object key, Object value);
 
     /**
      * Replaces the entry for a key only if currently mapped to a given value.
-     * This is equivalent to
-     *  <pre> {@code
-     * if (map.containsKey(key) && map.get(key).equals(oldValue)) {
+     * This is equivalent to, for this {@code map}:
+     * <pre> {@code
+     * if (map.containsKey(key)
+     *     && Objects.equals(map.get(key), oldValue)) {
      *   map.put(key, newValue);
      *   return true;
-     * } else
-     *   return false;}</pre>
+     * } else {
+     *   return false;
+     * }}</pre>
      *
      * except that the action is performed atomically.
      *
+     * @implNote This implementation intentionally re-abstracts the
+     * inappropriate default provided in {@code Map}.
+     *
      * @param key key with which the specified value is associated
      * @param oldValue value expected to be associated with the specified key
      * @param newValue value to be associated with the specified key
@@ -114,15 +194,18 @@
 
     /**
      * Replaces the entry for a key only if currently mapped to some value.
-     * This is equivalent to
-     *  <pre> {@code
-     * if (map.containsKey(key)) {
+     * This is equivalent to, for this {@code map}:
+     * <pre> {@code
+     * if (map.containsKey(key))
      *   return map.put(key, value);
-     * } else
+     * else
      *   return null;}</pre>
      *
      * except that the action is performed atomically.
      *
+     * @implNote This implementation intentionally re-abstracts the
+     * inappropriate default provided in {@code Map}.
+     *
      * @param key key with which the specified value is associated
      * @param value value to be associated with the specified key
      * @return the previous value associated with the specified key, or
@@ -140,4 +223,251 @@
      *         or value prevents it from being stored in this map
      */
     V replace(K key, V value);
+
+    /**
+     * {@inheritDoc}
+     *
+     * @implSpec
+     * <p>The default implementation is equivalent to, for this {@code map}:
+     * <pre> {@code
+     * for (Map.Entry<K,V> entry : map.entrySet()) {
+     *   K k;
+     *   V v;
+     *   do {
+     *     k = entry.getKey();
+     *     v = entry.getValue();
+     *   } while (!map.replace(k, v, function.apply(k, v)));
+     * }}</pre>
+     *
+     * The default implementation may retry these steps when multiple
+     * threads attempt updates including potentially calling the function
+     * repeatedly for a given key.
+     *
+     * <p>This implementation assumes that the ConcurrentMap cannot contain null
+     * values and {@code get()} returning null unambiguously means the key is
+     * absent. Implementations which support null values <strong>must</strong>
+     * override this default implementation.
+     *
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @throws ClassCastException {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
+        Objects.requireNonNull(function);
+        forEach((k,v) -> {
+            while (!replace(k, v, function.apply(k, v))) {
+                // v changed or k is gone
+                if ( (v = get(k)) == null) {
+                    // k is no longer in the map.
+                    break;
+                }
+            }
+        });
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @implSpec
+     * The default implementation is equivalent to the following steps for this
+     * {@code map}:
+     *
+     * <pre> {@code
+     * V oldValue, newValue;
+     * return ((oldValue = map.get(key)) == null
+     *         && (newValue = mappingFunction.apply(key)) != null
+     *         && (oldValue = map.putIfAbsent(key, newValue)) == null)
+     *   ? newValue
+     *   : oldValue;}</pre>
+     *
+     * <p>This implementation assumes that the ConcurrentMap cannot contain null
+     * values and {@code get()} returning null unambiguously means the key is
+     * absent. Implementations which support null values <strong>must</strong>
+     * override this default implementation.
+     *
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    default V computeIfAbsent(K key,
+            Function<? super K, ? extends V> mappingFunction) {
+        Objects.requireNonNull(mappingFunction);
+        V oldValue, newValue;
+        return ((oldValue = get(key)) == null
+                && (newValue = mappingFunction.apply(key)) != null
+                && (oldValue = putIfAbsent(key, newValue)) == null)
+            ? newValue
+            : oldValue;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @implSpec
+     * The default implementation is equivalent to performing the following
+     * steps for this {@code map}:
+     *
+     * <pre> {@code
+     * for (V oldValue; (oldValue = map.get(key)) != null; ) {
+     *   V newValue = remappingFunction.apply(key, oldValue);
+     *   if ((newValue == null)
+     *       ? map.remove(key, oldValue)
+     *       : map.replace(key, oldValue, newValue))
+     *     return newValue;
+     * }
+     * return null;}</pre>
+     * When multiple threads attempt updates, map operations and the
+     * remapping function may be called multiple times.
+     *
+     * <p>This implementation assumes that the ConcurrentMap cannot contain null
+     * values and {@code get()} returning null unambiguously means the key is
+     * absent. Implementations which support null values <strong>must</strong>
+     * override this default implementation.
+     *
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    default V computeIfPresent(K key,
+            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        Objects.requireNonNull(remappingFunction);
+        for (V oldValue; (oldValue = get(key)) != null; ) {
+            V newValue = remappingFunction.apply(key, oldValue);
+            if ((newValue == null)
+                ? remove(key, oldValue)
+                : replace(key, oldValue, newValue))
+                return newValue;
+        }
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @implSpec
+     * The default implementation is equivalent to performing the following
+     * steps for this {@code map}:
+     *
+     * <pre> {@code
+     * for (;;) {
+     *   V oldValue = map.get(key);
+     *   V newValue = remappingFunction.apply(key, oldValue);
+     *   if (newValue != null) {
+     *     if ((oldValue != null)
+     *       ? map.replace(key, oldValue, newValue)
+     *       : map.putIfAbsent(key, newValue) == null)
+     *       return newValue;
+     *   } else if (oldValue == null || map.remove(key, oldValue)) {
+     *     return null;
+     *   }
+     * }}</pre>
+     * When multiple threads attempt updates, map operations and the
+     * remapping function may be called multiple times.
+     *
+     * <p>This implementation assumes that the ConcurrentMap cannot contain null
+     * values and {@code get()} returning null unambiguously means the key is
+     * absent. Implementations which support null values <strong>must</strong>
+     * override this default implementation.
+     *
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    default V compute(K key,
+                      BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        retry: for (;;) {
+            V oldValue = get(key);
+            // if putIfAbsent fails, opportunistically use its return value
+            haveOldValue: for (;;) {
+                V newValue = remappingFunction.apply(key, oldValue);
+                if (newValue != null) {
+                    if (oldValue != null) {
+                        if (replace(key, oldValue, newValue))
+                            return newValue;
+                    }
+                    else if ((oldValue = putIfAbsent(key, newValue)) == null)
+                        return newValue;
+                    else continue haveOldValue;
+                } else if (oldValue == null || remove(key, oldValue)) {
+                    return null;
+                }
+                continue retry;
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @implSpec
+     * The default implementation is equivalent to performing the following
+     * steps for this {@code map}:
+     *
+     * <pre> {@code
+     * for (;;) {
+     *   V oldValue = map.get(key);
+     *   if (oldValue != null) {
+     *     V newValue = remappingFunction.apply(oldValue, value);
+     *     if (newValue != null) {
+     *       if (map.replace(key, oldValue, newValue))
+     *         return newValue;
+     *     } else if (map.remove(key, oldValue)) {
+     *       return null;
+     *     }
+     *   } else if (map.putIfAbsent(key, value) == null) {
+     *     return value;
+     *   }
+     * }}</pre>
+     * When multiple threads attempt updates, map operations and the
+     * remapping function may be called multiple times.
+     *
+     * <p>This implementation assumes that the ConcurrentMap cannot contain null
+     * values and {@code get()} returning null unambiguously means the key is
+     * absent. Implementations which support null values <strong>must</strong>
+     * override this default implementation.
+     *
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     * @since 1.8
+     */
+    @Override
+    default V merge(K key, V value,
+            BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+        Objects.requireNonNull(remappingFunction);
+        Objects.requireNonNull(value);
+        retry: for (;;) {
+            V oldValue = get(key);
+            // if putIfAbsent fails, opportunistically use its return value
+            haveOldValue: for (;;) {
+                if (oldValue != null) {
+                    V newValue = remappingFunction.apply(oldValue, value);
+                    if (newValue != null) {
+                        if (replace(key, oldValue, newValue))
+                            return newValue;
+                    } else if (remove(key, oldValue)) {
+                        return null;
+                    }
+                    continue retry;
+                } else {
+                    if ((oldValue = putIfAbsent(key, value)) == null)
+                        return value;
+                    continue haveOldValue;
+                }
+            }
+        }
+    }
 }
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java
index 17890ff..0d795b4 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java
@@ -6,7 +6,8 @@
 
 package java.util.concurrent;
 
-import java.util.*;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -73,7 +74,7 @@
      * reflected in the descending map, and vice-versa.
      *
      * <p>The returned map has an ordering equivalent to
-     * {@link Collections#reverseOrder(Comparator) Collections.reverseOrder}{@code (comparator())}.
+     * {@link java.util.Collections#reverseOrder(Comparator) Collections.reverseOrder}{@code (comparator())}.
      * The expression {@code m.descendingMap().descendingMap()} returns a
      * view of {@code m} essentially equivalent to {@code m}.
      *
@@ -92,15 +93,12 @@
      * operations.  It does not support the {@code add} or {@code addAll}
      * operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's iterators and spliterators are
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return a navigable set view of the keys in this map
      */
-    public NavigableSet<K> navigableKeySet();
+    NavigableSet<K> navigableKeySet();
 
     /**
      * Returns a {@link NavigableSet} view of the keys contained in this map.
@@ -113,11 +111,8 @@
      * operations.  It does not support the {@code add} or {@code addAll}
      * operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's iterators and spliterators are
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * <p>This method is equivalent to method {@code navigableKeySet}.
      *
@@ -136,13 +131,10 @@
      * operations.  It does not support the {@code add} or {@code addAll}
      * operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's iterators and spliterators are
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return a reverse order navigable set view of the keys in this map
      */
-    public NavigableSet<K> descendingKeySet();
+    NavigableSet<K> descendingKeySet();
 }
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java
index 0e8b64a..359d4f1 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java
@@ -6,7 +6,28 @@
 
 package java.util.concurrent;
 
-import java.util.*;
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -24,12 +45,13 @@
  * {@code containsKey}, {@code get}, {@code put} and
  * {@code remove} operations and their variants.  Insertion, removal,
  * update, and access operations safely execute concurrently by
- * multiple threads.  Iterators are <i>weakly consistent</i>, returning
- * elements reflecting the state of the map at some point at or since
- * the creation of the iterator.  They do <em>not</em> throw {@link
- * ConcurrentModificationException}, and may proceed concurrently with
- * other operations. Ascending key ordered views and their iterators
- * are faster than descending ones.
+ * multiple threads.
+ *
+ * <p>Iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>Ascending key ordered views and their iterators are faster than
+ * descending ones.
  *
  * <p>All {@code Map.Entry} pairs returned by methods in this class
  * and its views represent snapshots of mappings at the time they were
@@ -61,11 +83,8 @@
  * @param <V> the type of mapped values
  * @since 1.6
  */
-@SuppressWarnings("unchecked")
 public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
-    implements ConcurrentNavigableMap<K,V>,
-               Cloneable,
-               java.io.Serializable {
+    implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable {
     /*
      * This class implements a tree-like two-dimensionally linked skip
      * list in which the index levels are represented in separate
@@ -229,7 +248,7 @@
      *
      * Indexing uses skip list parameters that maintain good search
      * performance while using sparser-than-usual indices: The
-     * hardwired parameters k=1, p=0.5 (see method randomLevel) mean
+     * hardwired parameters k=1, p=0.5 (see method doPut) mean
      * that about one-quarter of the nodes have indices. Of those that
      * do, half have one level, a quarter have two, and so on (see
      * Pugh's Skip List Cookbook, sec 3.4).  The expected total space
@@ -267,6 +286,20 @@
      * there is a fair amount of near-duplication of code to handle
      * variants.
      *
+     * To produce random values without interference across threads,
+     * we use within-JDK thread local random support (via the
+     * "secondary seed", to avoid interference with user-level
+     * ThreadLocalRandom.)
+     *
+     * A previous version of this class wrapped non-comparable keys
+     * with their comparators to emulate Comparables when using
+     * comparators vs Comparables.  However, JVMs now appear to better
+     * handle infusing comparator-vs-comparable choice into search
+     * loops. Static method cpr(comparator, x, y) is used for all
+     * comparisons, which works well as long as the comparator
+     * argument is set up outside of loops (thus sometimes passed as
+     * an argument to internal methods) to avoid field re-reads.
+     *
      * For explanation of algorithms sharing at least a couple of
      * features with this one, see Mikhail Fomitchev's thesis
      * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis
@@ -294,18 +327,10 @@
 
     private static final long serialVersionUID = -8627078645895051609L;
 
-//  BEGIN android-removed
-//  /**
-//   * Generates the initial random seed for the cheaper per-instance
-//   * random number generators used in randomLevel.
-//   */
-//  private static final Random seedGenerator = new Random();
-//  END android-removed
-
     /**
-     * Special value used to identify base-level header
+     * Special value used to identify base-level header.
      */
-    private static final Object BASE_HEADER = new Object();
+    static final Object BASE_HEADER = new Object();
 
     /**
      * The topmost head index of the skiplist.
@@ -313,24 +338,19 @@
     private transient volatile HeadIndex<K,V> head;
 
     /**
-     * The comparator used to maintain order in this map, or null
-     * if using natural ordering.
+     * The comparator used to maintain order in this map, or null if
+     * using natural ordering.  (Non-private to simplify access in
+     * nested classes.)
      * @serial
      */
-    private final Comparator<? super K> comparator;
-
-    /**
-     * Seed for simple random number generator.  Not volatile since it
-     * doesn't matter too much if different threads don't see updates.
-     */
-    private transient int randomSeed;
+    final Comparator<? super K> comparator;
 
     /** Lazily initialized key set */
-    private transient KeySet<K> keySet;
+    private transient KeySet<K,V> keySet;
     /** Lazily initialized entry set */
     private transient EntrySet<K,V> entrySet;
     /** Lazily initialized values collection */
-    private transient Values<V> values;
+    private transient Values<K,V> values;
     /** Lazily initialized descending key set */
     private transient ConcurrentNavigableMap<K,V> descendingMap;
 
@@ -339,27 +359,20 @@
      * clear, readObject. and ConcurrentSkipListSet.clone.
      * (Note that comparator must be separately initialized.)
      */
-    final void initialize() {
+    private void initialize() {
         keySet = null;
         entrySet = null;
         values = null;
         descendingMap = null;
-        // BEGIN android-changed
-        //
-        // Most processes are forked from the zygote, so they'll end up
-        // with the same random seed unless we take additional post fork
-        // measures.
-        randomSeed = Math.randomIntInternal() | 0x0100; // ensure nonzero
-        // END android-changed
         head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null),
                                   null, null, 1);
     }
 
     /**
-     * compareAndSet head node
+     * compareAndSet head node.
      */
     private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) {
-        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
+        return U.compareAndSwapObject(this, HEAD, cmp, val);
     }
 
     /* ---------------- Nodes -------------- */
@@ -399,17 +412,17 @@
         }
 
         /**
-         * compareAndSet value field
+         * compareAndSet value field.
          */
         boolean casValue(Object cmp, Object val) {
-            return UNSAFE.compareAndSwapObject(this, valueOffset, cmp, val);
+            return U.compareAndSwapObject(this, VALUE, cmp, val);
         }
 
         /**
-         * compareAndSet next field
+         * compareAndSet next field.
          */
         boolean casNext(Node<K,V> cmp, Node<K,V> val) {
-            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
+            return U.compareAndSwapObject(this, NEXT, cmp, val);
         }
 
         /**
@@ -457,7 +470,7 @@
              */
             if (f == next && this == b.next) {
                 if (f == null || f.value != f) // not already marked
-                    appendMarker(f);
+                    casNext(f, new Node<K,V>(f));
                 else
                     b.casNext(this, f.next);
             }
@@ -473,7 +486,8 @@
             Object v = value;
             if (v == this || v == BASE_HEADER)
                 return null;
-            return (V)v;
+            @SuppressWarnings("unchecked") V vv = (V)v;
+            return vv;
         }
 
         /**
@@ -482,27 +496,26 @@
          * @return new entry or null
          */
         AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() {
-            V v = getValidValue();
-            if (v == null)
+            Object v = value;
+            if (v == null || v == this || v == BASE_HEADER)
                 return null;
-            return new AbstractMap.SimpleImmutableEntry<K,V>(key, v);
+            @SuppressWarnings("unchecked") V vv = (V)v;
+            return new AbstractMap.SimpleImmutableEntry<K,V>(key, vv);
         }
 
-        // UNSAFE mechanics
+        // Unsafe mechanics
 
-        private static final sun.misc.Unsafe UNSAFE;
-        private static final long valueOffset;
-        private static final long nextOffset;
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final long VALUE;
+        private static final long NEXT;
 
         static {
             try {
-                UNSAFE = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = Node.class;
-                valueOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("value"));
-                nextOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("next"));
-            } catch (Exception e) {
+                VALUE = U.objectFieldOffset
+                    (Node.class.getDeclaredField("value"));
+                NEXT = U.objectFieldOffset
+                    (Node.class.getDeclaredField("next"));
+            } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
         }
@@ -532,10 +545,10 @@
         }
 
         /**
-         * compareAndSet right field
+         * compareAndSet right field.
          */
         final boolean casRight(Index<K,V> cmp, Index<K,V> val) {
-            return UNSAFE.compareAndSwapObject(this, rightOffset, cmp, val);
+            return U.compareAndSwapObject(this, RIGHT, cmp, val);
         }
 
         /**
@@ -568,19 +581,17 @@
          * @return true if successful
          */
         final boolean unlink(Index<K,V> succ) {
-            return !indexesDeletedNode() && casRight(succ, succ.right);
+            return node.value != null && casRight(succ, succ.right);
         }
 
         // Unsafe mechanics
-        private static final sun.misc.Unsafe UNSAFE;
-        private static final long rightOffset;
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final long RIGHT;
         static {
             try {
-                UNSAFE = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = Index.class;
-                rightOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("right"));
-            } catch (Exception e) {
+                RIGHT = U.objectFieldOffset
+                    (Index.class.getDeclaredField("right"));
+            } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
         }
@@ -602,80 +613,12 @@
     /* ---------------- Comparison utilities -------------- */
 
     /**
-     * Represents a key with a comparator as a Comparable.
-     *
-     * Because most sorted collections seem to use natural ordering on
-     * Comparables (Strings, Integers, etc), most internal methods are
-     * geared to use them. This is generally faster than checking
-     * per-comparison whether to use comparator or comparable because
-     * it doesn't require a (Comparable) cast for each comparison.
-     * (Optimizers can only sometimes remove such redundant checks
-     * themselves.) When Comparators are used,
-     * ComparableUsingComparators are created so that they act in the
-     * same way as natural orderings. This penalizes use of
-     * Comparators vs Comparables, which seems like the right
-     * tradeoff.
+     * Compares using comparator or natural ordering if null.
+     * Called only by methods that have performed required type checks.
      */
-    static final class ComparableUsingComparator<K> implements Comparable<K> {
-        final K actualKey;
-        final Comparator<? super K> cmp;
-        ComparableUsingComparator(K key, Comparator<? super K> cmp) {
-            this.actualKey = key;
-            this.cmp = cmp;
-        }
-        public int compareTo(K k2) {
-            return cmp.compare(actualKey, k2);
-        }
-    }
-
-    /**
-     * If using comparator, return a ComparableUsingComparator, else
-     * cast key as Comparable, which may cause ClassCastException,
-     * which is propagated back to caller.
-     */
-    private Comparable<? super K> comparable(Object key)
-            throws ClassCastException {
-        if (key == null)
-            throw new NullPointerException();
-        if (comparator != null)
-            return new ComparableUsingComparator<K>((K)key, comparator);
-        else
-            return (Comparable<? super K>)key;
-    }
-
-    /**
-     * Compares using comparator or natural ordering. Used when the
-     * ComparableUsingComparator approach doesn't apply.
-     */
-    int compare(K k1, K k2) throws ClassCastException {
-        Comparator<? super K> cmp = comparator;
-        if (cmp != null)
-            return cmp.compare(k1, k2);
-        else
-            return ((Comparable<? super K>)k1).compareTo(k2);
-    }
-
-    /**
-     * Returns true if given key greater than or equal to least and
-     * strictly less than fence, bypassing either test if least or
-     * fence are null. Needed mainly in submap operations.
-     */
-    boolean inHalfOpenRange(K key, K least, K fence) {
-        if (key == null)
-            throw new NullPointerException();
-        return ((least == null || compare(key, least) >= 0) &&
-                (fence == null || compare(key, fence) <  0));
-    }
-
-    /**
-     * Returns true if given key greater than or equal to least and less
-     * or equal to fence. Needed mainly in submap operations.
-     */
-    boolean inOpenRange(K key, K least, K fence) {
-        if (key == null)
-            throw new NullPointerException();
-        return ((least == null || compare(key, least) >= 0) &&
-                (fence == null || compare(key, fence) <= 0));
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    static final int cpr(Comparator c, Object x, Object y) {
+        return (c != null) ? c.compare(x, y) : ((Comparable)x).compareTo(y);
     }
 
     /* ---------------- Traversal -------------- */
@@ -688,13 +631,11 @@
      * @param key the key
      * @return a predecessor of key
      */
-    private Node<K,V> findPredecessor(Comparable<? super K> key) {
+    private Node<K,V> findPredecessor(Object key, Comparator<? super K> cmp) {
         if (key == null)
             throw new NullPointerException(); // don't postpone errors
         for (;;) {
-            Index<K,V> q = head;
-            Index<K,V> r = q.right;
-            for (;;) {
+            for (Index<K,V> q = head, r = q.right, d;;) {
                 if (r != null) {
                     Node<K,V> n = r.node;
                     K k = n.key;
@@ -704,18 +645,16 @@
                         r = q.right;         // reread r
                         continue;
                     }
-                    if (key.compareTo(k) > 0) {
+                    if (cpr(cmp, key, k) > 0) {
                         q = r;
                         r = r.right;
                         continue;
                     }
                 }
-                Index<K,V> d = q.down;
-                if (d != null) {
-                    q = d;
-                    r = d.right;
-                } else
+                if ((d = q.down) == null)
                     return q.node;
+                q = d;
+                r = d.right;
             }
         }
     }
@@ -756,62 +695,79 @@
      *
      * The traversal loops in doPut, doRemove, and findNear all
      * include the same three kinds of checks. And specialized
-     * versions appear in findFirst, and findLast and their
-     * variants. They can't easily share code because each uses the
-     * reads of fields held in locals occurring in the orders they
-     * were performed.
+     * versions appear in findFirst, and findLast and their variants.
+     * They can't easily share code because each uses the reads of
+     * fields held in locals occurring in the orders they were
+     * performed.
      *
      * @param key the key
      * @return node holding key, or null if no such
      */
-    private Node<K,V> findNode(Comparable<? super K> key) {
-        for (;;) {
-            Node<K,V> b = findPredecessor(key);
-            Node<K,V> n = b.next;
-            for (;;) {
+    private Node<K,V> findNode(Object key) {
+        if (key == null)
+            throw new NullPointerException(); // don't postpone errors
+        Comparator<? super K> cmp = comparator;
+        outer: for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
+                Object v; int c;
                 if (n == null)
-                    return null;
+                    break outer;
                 Node<K,V> f = n.next;
                 if (n != b.next)                // inconsistent read
                     break;
-                Object v = n.value;
-                if (v == null) {                // n is deleted
+                if ((v = n.value) == null) {    // n is deleted
                     n.helpDelete(b, f);
                     break;
                 }
-                if (v == n || b.value == null)  // b is deleted
+                if (b.value == null || v == n)  // b is deleted
                     break;
-                int c = key.compareTo(n.key);
-                if (c == 0)
+                if ((c = cpr(cmp, key, n.key)) == 0)
                     return n;
                 if (c < 0)
-                    return null;
+                    break outer;
                 b = n;
                 n = f;
             }
         }
+        return null;
     }
 
     /**
-     * Gets value for key using findNode.
-     * @param okey the key
+     * Gets value for key. Almost the same as findNode, but returns
+     * the found value (to avoid retries during re-reads)
+     *
+     * @param key the key
      * @return the value, or null if absent
      */
-    private V doGet(Object okey) {
-        Comparable<? super K> key = comparable(okey);
-        /*
-         * Loop needed here and elsewhere in case value field goes
-         * null just as it is about to be returned, in which case we
-         * lost a race with a deletion, so must retry.
-         */
-        for (;;) {
-            Node<K,V> n = findNode(key);
-            if (n == null)
-                return null;
-            Object v = n.value;
-            if (v != null)
-                return (V)v;
+    private V doGet(Object key) {
+        if (key == null)
+            throw new NullPointerException();
+        Comparator<? super K> cmp = comparator;
+        outer: for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
+                Object v; int c;
+                if (n == null)
+                    break outer;
+                Node<K,V> f = n.next;
+                if (n != b.next)                // inconsistent read
+                    break;
+                if ((v = n.value) == null) {    // n is deleted
+                    n.helpDelete(b, f);
+                    break;
+                }
+                if (b.value == null || v == n)  // b is deleted
+                    break;
+                if ((c = cpr(cmp, key, n.key)) == 0) {
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    return vv;
+                }
+                if (c < 0)
+                    break outer;
+                b = n;
+                n = f;
+            }
         }
+        return null;
     }
 
     /* ---------------- Insertion -------------- */
@@ -819,187 +775,126 @@
     /**
      * Main insertion method.  Adds element if not present, or
      * replaces value if present and onlyIfAbsent is false.
-     * @param kkey the key
+     * @param key the key
      * @param value the value that must be associated with key
      * @param onlyIfAbsent if should not insert if already present
      * @return the old value, or null if newly inserted
      */
-    private V doPut(K kkey, V value, boolean onlyIfAbsent) {
-        Comparable<? super K> key = comparable(kkey);
-        for (;;) {
-            Node<K,V> b = findPredecessor(key);
-            Node<K,V> n = b.next;
-            for (;;) {
+    private V doPut(K key, V value, boolean onlyIfAbsent) {
+        Node<K,V> z;             // added node
+        if (key == null)
+            throw new NullPointerException();
+        Comparator<? super K> cmp = comparator;
+        outer: for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
                 if (n != null) {
+                    Object v; int c;
                     Node<K,V> f = n.next;
                     if (n != b.next)               // inconsistent read
                         break;
-                    Object v = n.value;
-                    if (v == null) {               // n is deleted
+                    if ((v = n.value) == null) {   // n is deleted
                         n.helpDelete(b, f);
                         break;
                     }
-                    if (v == n || b.value == null) // b is deleted
+                    if (b.value == null || v == n) // b is deleted
                         break;
-                    int c = key.compareTo(n.key);
-                    if (c > 0) {
+                    if ((c = cpr(cmp, key, n.key)) > 0) {
                         b = n;
                         n = f;
                         continue;
                     }
                     if (c == 0) {
-                        if (onlyIfAbsent || n.casValue(v, value))
-                            return (V)v;
-                        else
-                            break; // restart if lost race to replace value
+                        if (onlyIfAbsent || n.casValue(v, value)) {
+                            @SuppressWarnings("unchecked") V vv = (V)v;
+                            return vv;
+                        }
+                        break; // restart if lost race to replace value
                     }
                     // else c < 0; fall through
                 }
 
-                Node<K,V> z = new Node<K,V>(kkey, value, n);
+                z = new Node<K,V>(key, value, n);
                 if (!b.casNext(n, z))
                     break;         // restart if lost race to append to b
-                int level = randomLevel();
-                if (level > 0)
-                    insertIndex(z, level);
-                return null;
+                break outer;
             }
         }
-    }
 
-    /**
-     * Returns a random level for inserting a new node.
-     * Hardwired to k=1, p=0.5, max 31 (see above and
-     * Pugh's "Skip List Cookbook", sec 3.4).
-     *
-     * This uses the simplest of the generators described in George
-     * Marsaglia's "Xorshift RNGs" paper.  This is not a high-quality
-     * generator but is acceptable here.
-     */
-    private int randomLevel() {
-        int x = randomSeed;
-        x ^= x << 13;
-        x ^= x >>> 17;
-        randomSeed = x ^= x << 5;
-        if ((x & 0x80000001) != 0) // test highest and lowest bits
-            return 0;
-        int level = 1;
-        while (((x >>>= 1) & 1) != 0) ++level;
-        return level;
-    }
-
-    /**
-     * Creates and adds index nodes for the given node.
-     * @param z the node
-     * @param level the level of the index
-     */
-    private void insertIndex(Node<K,V> z, int level) {
-        HeadIndex<K,V> h = head;
-        int max = h.level;
-
-        if (level <= max) {
+        int rnd = ThreadLocalRandom.nextSecondarySeed();
+        if ((rnd & 0x80000001) == 0) { // test highest and lowest bits
+            int level = 1, max;
+            while (((rnd >>>= 1) & 1) != 0)
+                ++level;
             Index<K,V> idx = null;
-            for (int i = 1; i <= level; ++i)
-                idx = new Index<K,V>(z, idx, null);
-            addIndex(idx, h, level);
-
-        } else { // Add a new level
-            /*
-             * To reduce interference by other threads checking for
-             * empty levels in tryReduceLevel, new levels are added
-             * with initialized right pointers. Which in turn requires
-             * keeping levels in an array to access them while
-             * creating new head index nodes from the opposite
-             * direction.
-             */
-            level = max + 1;
-            Index<K,V>[] idxs = (Index<K,V>[])new Index<?,?>[level+1];
-            Index<K,V> idx = null;
-            for (int i = 1; i <= level; ++i)
-                idxs[i] = idx = new Index<K,V>(z, idx, null);
-
-            HeadIndex<K,V> oldh;
-            int k;
-            for (;;) {
-                oldh = head;
-                int oldLevel = oldh.level;
-                if (level <= oldLevel) { // lost race to add level
-                    k = level;
-                    break;
-                }
-                HeadIndex<K,V> newh = oldh;
-                Node<K,V> oldbase = oldh.node;
-                for (int j = oldLevel+1; j <= level; ++j)
-                    newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
-                if (casHead(oldh, newh)) {
-                    k = oldLevel;
-                    break;
+            HeadIndex<K,V> h = head;
+            if (level <= (max = h.level)) {
+                for (int i = 1; i <= level; ++i)
+                    idx = new Index<K,V>(z, idx, null);
+            }
+            else { // try to grow by one level
+                level = max + 1; // hold in array and later pick the one to use
+                @SuppressWarnings("unchecked")Index<K,V>[] idxs =
+                    (Index<K,V>[])new Index<?,?>[level+1];
+                for (int i = 1; i <= level; ++i)
+                    idxs[i] = idx = new Index<K,V>(z, idx, null);
+                for (;;) {
+                    h = head;
+                    int oldLevel = h.level;
+                    if (level <= oldLevel) // lost race to add level
+                        break;
+                    HeadIndex<K,V> newh = h;
+                    Node<K,V> oldbase = h.node;
+                    for (int j = oldLevel+1; j <= level; ++j)
+                        newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
+                    if (casHead(h, newh)) {
+                        h = newh;
+                        idx = idxs[level = oldLevel];
+                        break;
+                    }
                 }
             }
-            addIndex(idxs[k], oldh, k);
-        }
-    }
-
-    /**
-     * Adds given index nodes from given level down to 1.
-     * @param idx the topmost index node being inserted
-     * @param h the value of head to use to insert. This must be
-     * snapshotted by callers to provide correct insertion level.
-     * @param indexLevel the level of the index
-     */
-    private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) {
-        // Track next level to insert in case of retries
-        int insertionLevel = indexLevel;
-        Comparable<? super K> key = comparable(idx.node.key);
-        if (key == null) throw new NullPointerException();
-
-        // Similar to findPredecessor, but adding index nodes along
-        // path to key.
-        for (;;) {
-            int j = h.level;
-            Index<K,V> q = h;
-            Index<K,V> r = q.right;
-            Index<K,V> t = idx;
-            for (;;) {
-                if (r != null) {
-                    Node<K,V> n = r.node;
-                    // compare before deletion check avoids needing recheck
-                    int c = key.compareTo(n.key);
-                    if (n.value == null) {
-                        if (!q.unlink(r))
-                            break;
-                        r = q.right;
-                        continue;
+            // find insertion points and splice in
+            splice: for (int insertionLevel = level;;) {
+                int j = h.level;
+                for (Index<K,V> q = h, r = q.right, t = idx;;) {
+                    if (q == null || t == null)
+                        break splice;
+                    if (r != null) {
+                        Node<K,V> n = r.node;
+                        // compare before deletion check avoids needing recheck
+                        int c = cpr(cmp, key, n.key);
+                        if (n.value == null) {
+                            if (!q.unlink(r))
+                                break;
+                            r = q.right;
+                            continue;
+                        }
+                        if (c > 0) {
+                            q = r;
+                            r = r.right;
+                            continue;
+                        }
                     }
-                    if (c > 0) {
-                        q = r;
-                        r = r.right;
-                        continue;
-                    }
-                }
 
-                if (j == insertionLevel) {
-                    // Don't insert index if node already deleted
-                    if (t.indexesDeletedNode()) {
-                        findNode(key); // cleans up
-                        return;
-                    }
-                    if (!q.link(r, t))
-                        break; // restart
-                    if (--insertionLevel == 0) {
-                        // need final deletion check before return
-                        if (t.indexesDeletedNode())
+                    if (j == insertionLevel) {
+                        if (!q.link(r, t))
+                            break; // restart
+                        if (t.node.value == null) {
                             findNode(key);
-                        return;
+                            break splice;
+                        }
+                        if (--insertionLevel == 0)
+                            break splice;
                     }
-                }
 
-                if (--j >= insertionLevel && j < indexLevel)
-                    t = t.down;
-                q = q.down;
-                r = q.right;
+                    if (--j >= insertionLevel && j < level)
+                        t = t.down;
+                    q = q.down;
+                    r = q.right;
+                }
             }
         }
+        return null;
     }
 
     /* ---------------- Deletion -------------- */
@@ -1018,51 +913,52 @@
      * search for it, and we'd like to ensure lack of garbage
      * retention, so must call to be sure.
      *
-     * @param okey the key
+     * @param key the key
      * @param value if non-null, the value that must be
      * associated with key
      * @return the node, or null if not found
      */
-    final V doRemove(Object okey, Object value) {
-        Comparable<? super K> key = comparable(okey);
-        for (;;) {
-            Node<K,V> b = findPredecessor(key);
-            Node<K,V> n = b.next;
-            for (;;) {
+    final V doRemove(Object key, Object value) {
+        if (key == null)
+            throw new NullPointerException();
+        Comparator<? super K> cmp = comparator;
+        outer: for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
+                Object v; int c;
                 if (n == null)
-                    return null;
+                    break outer;
                 Node<K,V> f = n.next;
                 if (n != b.next)                    // inconsistent read
                     break;
-                Object v = n.value;
-                if (v == null) {                    // n is deleted
+                if ((v = n.value) == null) {        // n is deleted
                     n.helpDelete(b, f);
                     break;
                 }
-                if (v == n || b.value == null)      // b is deleted
+                if (b.value == null || v == n)      // b is deleted
                     break;
-                int c = key.compareTo(n.key);
-                if (c < 0)
-                    return null;
+                if ((c = cpr(cmp, key, n.key)) < 0)
+                    break outer;
                 if (c > 0) {
                     b = n;
                     n = f;
                     continue;
                 }
                 if (value != null && !value.equals(v))
-                    return null;
+                    break outer;
                 if (!n.casValue(v, null))
                     break;
                 if (!n.appendMarker(f) || !b.casNext(n, f))
-                    findNode(key);                  // Retry via findNode
+                    findNode(key);                  // retry via findNode
                 else {
-                    findPredecessor(key);           // Clean index
+                    findPredecessor(key, cmp);      // clean index
                     if (head.right == null)
                         tryReduceLevel();
                 }
-                return (V)v;
+                @SuppressWarnings("unchecked") V vv = (V)v;
+                return vv;
             }
         }
+        return null;
     }
 
     /**
@@ -1106,11 +1002,9 @@
      * Specialized variant of findNode to get first valid node.
      * @return first node or null if empty
      */
-    Node<K,V> findFirst() {
-        for (;;) {
-            Node<K,V> b = head.node;
-            Node<K,V> n = b.next;
-            if (n == null)
+    final Node<K,V> findFirst() {
+        for (Node<K,V> b, n;;) {
+            if ((n = (b = head.node).next) == null)
                 return null;
             if (n.value != null)
                 return n;
@@ -1122,11 +1016,9 @@
      * Removes first entry; returns its snapshot.
      * @return null if empty, else snapshot of first entry
      */
-    Map.Entry<K,V> doRemoveFirstEntry() {
-        for (;;) {
-            Node<K,V> b = head.node;
-            Node<K,V> n = b.next;
-            if (n == null)
+    private Map.Entry<K,V> doRemoveFirstEntry() {
+        for (Node<K,V> b, n;;) {
+            if ((n = (b = head.node).next) == null)
                 return null;
             Node<K,V> f = n.next;
             if (n != b.next)
@@ -1141,7 +1033,8 @@
             if (!n.appendMarker(f) || !b.casNext(n, f))
                 findFirst(); // retry
             clearIndexToFirst();
-            return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v);
+            @SuppressWarnings("unchecked") V vv = (V)v;
+            return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, vv);
         }
     }
 
@@ -1150,8 +1043,7 @@
      */
     private void clearIndexToFirst() {
         for (;;) {
-            Index<K,V> q = head;
-            for (;;) {
+            for (Index<K,V> q = head;;) {
                 Index<K,V> r = q.right;
                 if (r != null && r.indexesDeletedNode() && !q.unlink(r))
                     break;
@@ -1164,6 +1056,52 @@
         }
     }
 
+    /**
+     * Removes last entry; returns its snapshot.
+     * Specialized variant of doRemove.
+     * @return null if empty, else snapshot of last entry
+     */
+    private Map.Entry<K,V> doRemoveLastEntry() {
+        for (;;) {
+            Node<K,V> b = findPredecessorOfLast();
+            Node<K,V> n = b.next;
+            if (n == null) {
+                if (b.isBaseHeader())               // empty
+                    return null;
+                else
+                    continue; // all b's successors are deleted; retry
+            }
+            for (;;) {
+                Node<K,V> f = n.next;
+                if (n != b.next)                    // inconsistent read
+                    break;
+                Object v = n.value;
+                if (v == null) {                    // n is deleted
+                    n.helpDelete(b, f);
+                    break;
+                }
+                if (b.value == null || v == n)      // b is deleted
+                    break;
+                if (f != null) {
+                    b = n;
+                    n = f;
+                    continue;
+                }
+                if (!n.casValue(v, null))
+                    break;
+                K key = n.key;
+                if (!n.appendMarker(f) || !b.casNext(n, f))
+                    findNode(key);                  // retry via findNode
+                else {                              // clean index
+                    findPredecessor(key, comparator);
+                    if (head.right == null)
+                        tryReduceLevel();
+                }
+                @SuppressWarnings("unchecked") V vv = (V)v;
+                return new AbstractMap.SimpleImmutableEntry<K,V>(key, vv);
+            }
+        }
+    }
 
     /* ---------------- Finding and removing last element -------------- */
 
@@ -1171,7 +1109,7 @@
      * Specialized version of find to get last valid node.
      * @return last node or null if empty
      */
-    Node<K,V> findLast() {
+    final Node<K,V> findLast() {
         /*
          * findPredecessor can't be used to traverse index level
          * because this doesn't use comparisons.  So traversals of
@@ -1190,9 +1128,7 @@
             } else if ((d = q.down) != null) {
                 q = d;
             } else {
-                Node<K,V> b = q.node;
-                Node<K,V> n = b.next;
-                for (;;) {
+                for (Node<K,V> b = q.node, n = b.next;;) {
                     if (n == null)
                         return b.isBaseHeader() ? null : b;
                     Node<K,V> f = n.next;            // inconsistent read
@@ -1203,7 +1139,7 @@
                         n.helpDelete(b, f);
                         break;
                     }
-                    if (v == n || b.value == null)   // b is deleted
+                    if (b.value == null || v == n)      // b is deleted
                         break;
                     b = n;
                     n = f;
@@ -1222,8 +1158,7 @@
      */
     private Node<K,V> findPredecessorOfLast() {
         for (;;) {
-            Index<K,V> q = head;
-            for (;;) {
+            for (Index<K,V> q = head;;) {
                 Index<K,V> d, r;
                 if ((r = q.right) != null) {
                     if (r.indexesDeletedNode()) {
@@ -1244,53 +1179,6 @@
         }
     }
 
-    /**
-     * Removes last entry; returns its snapshot.
-     * Specialized variant of doRemove.
-     * @return null if empty, else snapshot of last entry
-     */
-    Map.Entry<K,V> doRemoveLastEntry() {
-        for (;;) {
-            Node<K,V> b = findPredecessorOfLast();
-            Node<K,V> n = b.next;
-            if (n == null) {
-                if (b.isBaseHeader())               // empty
-                    return null;
-                else
-                    continue; // all b's successors are deleted; retry
-            }
-            for (;;) {
-                Node<K,V> f = n.next;
-                if (n != b.next)                    // inconsistent read
-                    break;
-                Object v = n.value;
-                if (v == null) {                    // n is deleted
-                    n.helpDelete(b, f);
-                    break;
-                }
-                if (v == n || b.value == null)      // b is deleted
-                    break;
-                if (f != null) {
-                    b = n;
-                    n = f;
-                    continue;
-                }
-                if (!n.casValue(v, null))
-                    break;
-                K key = n.key;
-                Comparable<? super K> ck = comparable(key);
-                if (!n.appendMarker(f) || !b.casNext(n, f))
-                    findNode(ck);                  // Retry via findNode
-                else {
-                    findPredecessor(ck);           // Clean index
-                    if (head.right == null)
-                        tryReduceLevel();
-                }
-                return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v);
-            }
-        }
-    }
-
     /* ---------------- Relational operations -------------- */
 
     // Control values OR'ed as arguments to findNear
@@ -1301,29 +1189,28 @@
 
     /**
      * Utility for ceiling, floor, lower, higher methods.
-     * @param kkey the key
+     * @param key the key
      * @param rel the relation -- OR'ed combination of EQ, LT, GT
      * @return nearest node fitting relation, or null if no such
      */
-    Node<K,V> findNear(K kkey, int rel) {
-        Comparable<? super K> key = comparable(kkey);
+    final Node<K,V> findNear(K key, int rel, Comparator<? super K> cmp) {
+        if (key == null)
+            throw new NullPointerException();
         for (;;) {
-            Node<K,V> b = findPredecessor(key);
-            Node<K,V> n = b.next;
-            for (;;) {
+            for (Node<K,V> b = findPredecessor(key, cmp), n = b.next;;) {
+                Object v;
                 if (n == null)
                     return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b;
                 Node<K,V> f = n.next;
                 if (n != b.next)                  // inconsistent read
                     break;
-                Object v = n.value;
-                if (v == null) {                  // n is deleted
+                if ((v = n.value) == null) {      // n is deleted
                     n.helpDelete(b, f);
                     break;
                 }
-                if (v == n || b.value == null)    // b is deleted
+                if (b.value == null || v == n)      // b is deleted
                     break;
-                int c = key.compareTo(n.key);
+                int c = cpr(cmp, key, n.key);
                 if ((c == 0 && (rel & EQ) != 0) ||
                     (c <  0 && (rel & LT) == 0))
                     return n;
@@ -1341,9 +1228,10 @@
      * @param rel the relation -- OR'ed combination of EQ, LT, GT
      * @return Entry fitting relation, or null if no such
      */
-    AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) {
+    final AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) {
+        Comparator<? super K> cmp = comparator;
         for (;;) {
-            Node<K,V> n = findNear(key, rel);
+            Node<K,V> n = findNear(key, rel, cmp);
             if (n == null)
                 return null;
             AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
@@ -1352,7 +1240,6 @@
         }
     }
 
-
     /* ---------------- Constructors -------------- */
 
     /**
@@ -1442,7 +1329,7 @@
 
         // Track the current rightmost node at each level. Uses an
         // ArrayList to avoid committing to initial or maximum level.
-        ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
+        ArrayList<Index<K,V>> preds = new ArrayList<>();
 
         // initialize
         for (int i = 0; i <= h.level; ++i)
@@ -1457,8 +1344,14 @@
             map.entrySet().iterator();
         while (it.hasNext()) {
             Map.Entry<? extends K, ? extends V> e = it.next();
-            int j = randomLevel();
-            if (j > h.level) j = h.level + 1;
+            int rnd = ThreadLocalRandom.current().nextInt();
+            int j = 0;
+            if ((rnd & 0x80000001) == 0) {
+                do {
+                    ++j;
+                } while (((rnd >>>= 1) & 1) != 0);
+                if (j > h.level) j = h.level + 1;
+            }
             K k = e.getKey();
             V v = e.getValue();
             if (k == null || v == null)
@@ -1489,6 +1382,8 @@
     /**
      * Saves this map to a stream (that is, serializes it).
      *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData The key (Object) and value (Object) for each
      * key-value mapping represented by the map, followed by
      * {@code null}. The key-value mappings are emitted in key-order
@@ -1513,7 +1408,12 @@
 
     /**
      * Reconstitutes this map from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
+    @SuppressWarnings("unchecked")
     private void readObject(final java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
         // Read in the Comparator and any hidden stuff
@@ -1526,12 +1426,12 @@
          * distinct because readObject calls can't be nicely adapted
          * as the kind of iterator needed by buildFromSorted. (They
          * can be, but doing so requires type cheats and/or creation
-         * of adaptor classes.) It is simpler to just adapt the code.
+         * of adapter classes.) It is simpler to just adapt the code.
          */
 
         HeadIndex<K,V> h = head;
         Node<K,V> basepred = h.node;
-        ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
+        ArrayList<Index<K,V>> preds = new ArrayList<>();
         for (int i = 0; i <= h.level; ++i)
             preds.add(null);
         Index<K,V> q = h;
@@ -1549,8 +1449,14 @@
                 throw new NullPointerException();
             K key = (K) k;
             V val = (V) v;
-            int j = randomLevel();
-            if (j > h.level) j = h.level + 1;
+            int rnd = ThreadLocalRandom.current().nextInt();
+            int j = 0;
+            if ((rnd & 0x80000001) == 0) {
+                do {
+                    ++j;
+                } while (((rnd >>>= 1) & 1) != 0);
+                if (j > h.level) j = h.level + 1;
+            }
             Node<K,V> z = new Node<K,V>(key, val, null);
             basepred.next = z;
             basepred = z;
@@ -1607,6 +1513,22 @@
     }
 
     /**
+     * Returns the value to which the specified key is mapped,
+     * or the given defaultValue if this map contains no mapping for the key.
+     *
+     * @param key the key
+     * @param defaultValue the value to return if this map contains
+     * no mapping for the given key
+     * @return the mapping for the key, if present; else the defaultValue
+     * @throws NullPointerException if the specified key is null
+     * @since 1.8
+     */
+    public V getOrDefault(Object key, V defaultValue) {
+        V v;
+        return (v = doGet(key)) == null ? defaultValue : v;
+    }
+
+    /**
      * Associates the specified value with the specified key in this map.
      * If the map previously contained a mapping for the key, the old
      * value is replaced.
@@ -1702,6 +1624,140 @@
         initialize();
     }
 
+    /**
+     * If the specified key is not already associated with a value,
+     * attempts to compute its value using the given mapping function
+     * and enters it into this map unless {@code null}.  The function
+     * is <em>NOT</em> guaranteed to be applied once atomically only
+     * if the value is not present.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param mappingFunction the function to compute a value
+     * @return the current (existing or computed) value associated with
+     *         the specified key, or null if the computed value is null
+     * @throws NullPointerException if the specified key is null
+     *         or the mappingFunction is null
+     * @since 1.8
+     */
+    public V computeIfAbsent(K key,
+                             Function<? super K, ? extends V> mappingFunction) {
+        if (key == null || mappingFunction == null)
+            throw new NullPointerException();
+        V v, p, r;
+        if ((v = doGet(key)) == null &&
+            (r = mappingFunction.apply(key)) != null)
+            v = (p = doPut(key, r, true)) == null ? r : p;
+        return v;
+    }
+
+    /**
+     * If the value for the specified key is present, attempts to
+     * compute a new mapping given the key and its current mapped
+     * value. The function is <em>NOT</em> guaranteed to be applied
+     * once atomically.
+     *
+     * @param key key with which a value may be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key is null
+     *         or the remappingFunction is null
+     * @since 1.8
+     */
+    public V computeIfPresent(K key,
+                              BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        Node<K,V> n; Object v;
+        while ((n = findNode(key)) != null) {
+            if ((v = n.value) != null) {
+                @SuppressWarnings("unchecked") V vv = (V) v;
+                V r = remappingFunction.apply(key, vv);
+                if (r != null) {
+                    if (n.casValue(vv, r))
+                        return r;
+                }
+                else if (doRemove(key, vv) != null)
+                    break;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Attempts to compute a mapping for the specified key and its
+     * current mapped value (or {@code null} if there is no current
+     * mapping). The function is <em>NOT</em> guaranteed to be applied
+     * once atomically.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param remappingFunction the function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key is null
+     *         or the remappingFunction is null
+     * @since 1.8
+     */
+    public V compute(K key,
+                     BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        if (key == null || remappingFunction == null)
+            throw new NullPointerException();
+        for (;;) {
+            Node<K,V> n; Object v; V r;
+            if ((n = findNode(key)) == null) {
+                if ((r = remappingFunction.apply(key, null)) == null)
+                    break;
+                if (doPut(key, r, true) == null)
+                    return r;
+            }
+            else if ((v = n.value) != null) {
+                @SuppressWarnings("unchecked") V vv = (V) v;
+                if ((r = remappingFunction.apply(key, vv)) != null) {
+                    if (n.casValue(vv, r))
+                        return r;
+                }
+                else if (doRemove(key, vv) != null)
+                    break;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * If the specified key is not already associated with a value,
+     * associates it with the given value.  Otherwise, replaces the
+     * value with the results of the given remapping function, or
+     * removes if {@code null}. The function is <em>NOT</em>
+     * guaranteed to be applied once atomically.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param value the value to use if absent
+     * @param remappingFunction the function to recompute a value if present
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key or value is null
+     *         or the remappingFunction is null
+     * @since 1.8
+     */
+    public V merge(K key, V value,
+                   BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+        if (key == null || value == null || remappingFunction == null)
+            throw new NullPointerException();
+        for (;;) {
+            Node<K,V> n; Object v; V r;
+            if ((n = findNode(key)) == null) {
+                if (doPut(key, value, true) == null)
+                    return value;
+            }
+            else if ((v = n.value) != null) {
+                @SuppressWarnings("unchecked") V vv = (V) v;
+                if ((r = remappingFunction.apply(vv, value)) != null) {
+                    if (n.casValue(vv, r))
+                        return r;
+                }
+                else if (doRemove(key, vv) != null)
+                    return null;
+            }
+        }
+    }
+
     /* ---------------- View methods -------------- */
 
     /*
@@ -1715,8 +1771,18 @@
 
     /**
      * Returns a {@link NavigableSet} view of the keys contained in this map.
-     * The set's iterator returns the keys in ascending order.
-     * The set is backed by the map, so changes to the map are
+     *
+     * <p>The set's iterator returns the keys in ascending order.
+     * The set's spliterator additionally reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and
+     * {@link Spliterator#ORDERED}, with an encounter order that is ascending
+     * key order.  The spliterator's comparator (see
+     * {@link java.util.Spliterator#getComparator()}) is {@code null} if
+     * the map's comparator (see {@link #comparator()}) is {@code null}.
+     * Otherwise, the spliterator's comparator is the same as or imposes the
+     * same total ordering as the map's comparator.
+     *
+     * <p>The set is backed by the map, so changes to the map are
      * reflected in the set, and vice-versa.  The set supports element
      * removal, which removes the corresponding mapping from the map,
      * via the {@code Iterator.remove}, {@code Set.remove},
@@ -1724,31 +1790,32 @@
      * operations.  It does not support the {@code add} or {@code addAll}
      * operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's iterators and spliterators are
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * <p>This method is equivalent to method {@code navigableKeySet}.
      *
      * @return a navigable set view of the keys in this map
      */
     public NavigableSet<K> keySet() {
-        KeySet<K> ks = keySet;
-        return (ks != null) ? ks : (keySet = new KeySet<K>(this));
+        KeySet<K,V> ks = keySet;
+        return (ks != null) ? ks : (keySet = new KeySet<>(this));
     }
 
     public NavigableSet<K> navigableKeySet() {
-        KeySet<K> ks = keySet;
-        return (ks != null) ? ks : (keySet = new KeySet<K>(this));
+        KeySet<K,V> ks = keySet;
+        return (ks != null) ? ks : (keySet = new KeySet<>(this));
     }
 
     /**
      * Returns a {@link Collection} view of the values contained in this map.
-     * The collection's iterator returns the values in ascending order
-     * of the corresponding keys.
-     * The collection is backed by the map, so changes to the map are
+     * <p>The collection's iterator returns the values in ascending order
+     * of the corresponding keys. The collections's spliterator additionally
+     * reports {@link Spliterator#CONCURRENT}, {@link Spliterator#NONNULL} and
+     * {@link Spliterator#ORDERED}, with an encounter order that is ascending
+     * order of the corresponding keys.
+     *
+     * <p>The collection is backed by the map, so changes to the map are
      * reflected in the collection, and vice-versa.  The collection
      * supports element removal, which removes the corresponding
      * mapping from the map, via the {@code Iterator.remove},
@@ -1756,21 +1823,24 @@
      * {@code retainAll} and {@code clear} operations.  It does not
      * support the {@code add} or {@code addAll} operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's iterators and spliterators are
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      */
     public Collection<V> values() {
-        Values<V> vs = values;
-        return (vs != null) ? vs : (values = new Values<V>(this));
+        Values<K,V> vs = values;
+        return (vs != null) ? vs : (values = new Values<>(this));
     }
 
     /**
      * Returns a {@link Set} view of the mappings contained in this map.
-     * The set's iterator returns the entries in ascending key order.
-     * The set is backed by the map, so changes to the map are
+     *
+     * <p>The set's iterator returns the entries in ascending key order.  The
+     * set's spliterator additionally reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and
+     * {@link Spliterator#ORDERED}, with an encounter order that is ascending
+     * key order.
+     *
+     * <p>The set is backed by the map, so changes to the map are
      * reflected in the set, and vice-versa.  The set supports element
      * removal, which removes the corresponding mapping from the map,
      * via the {@code Iterator.remove}, {@code Set.remove},
@@ -1778,15 +1848,12 @@
      * operations.  It does not support the {@code add} or
      * {@code addAll} operations.
      *
-     * <p>The view's {@code iterator} is a "weakly consistent" iterator
-     * that will never throw {@link ConcurrentModificationException},
-     * and guarantees to traverse elements as they existed upon
-     * construction of the iterator, and may (but is not guaranteed to)
-     * reflect any modifications subsequent to construction.
+     * <p>The view's iterators and spliterators are
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
-     * <p>The {@code Map.Entry} elements returned by
-     * {@code iterator.next()} do <em>not</em> support the
-     * {@code setValue} operation.
+     * <p>The {@code Map.Entry} elements traversed by the {@code iterator}
+     * or {@code spliterator} do <em>not</em> support the {@code setValue}
+     * operation.
      *
      * @return a set view of the mappings contained in this map,
      *         sorted in ascending key order
@@ -1871,9 +1938,7 @@
     public boolean remove(Object key, Object value) {
         if (key == null)
             throw new NullPointerException();
-        if (value == null)
-            return false;
-        return doRemove(key, value) != null;
+        return value != null && doRemove(key, value) != null;
     }
 
     /**
@@ -1884,15 +1949,13 @@
      * @throws NullPointerException if any of the arguments are null
      */
     public boolean replace(K key, V oldValue, V newValue) {
-        if (oldValue == null || newValue == null)
+        if (key == null || oldValue == null || newValue == null)
             throw new NullPointerException();
-        Comparable<? super K> k = comparable(key);
         for (;;) {
-            Node<K,V> n = findNode(k);
-            if (n == null)
+            Node<K,V> n; Object v;
+            if ((n = findNode(key)) == null)
                 return false;
-            Object v = n.value;
-            if (v != null) {
+            if ((v = n.value) != null) {
                 if (!oldValue.equals(v))
                     return false;
                 if (n.casValue(v, newValue))
@@ -1911,16 +1974,16 @@
      * @throws NullPointerException if the specified key or value is null
      */
     public V replace(K key, V value) {
-        if (value == null)
+        if (key == null || value == null)
             throw new NullPointerException();
-        Comparable<? super K> k = comparable(key);
         for (;;) {
-            Node<K,V> n = findNode(k);
-            if (n == null)
+            Node<K,V> n; Object v;
+            if ((n = findNode(key)) == null)
                 return null;
-            Object v = n.value;
-            if (v != null && n.casValue(v, value))
-                return (V)v;
+            if ((v = n.value) != null && n.casValue(v, value)) {
+                @SuppressWarnings("unchecked") V vv = (V)v;
+                return vv;
+            }
         }
     }
 
@@ -2038,7 +2101,7 @@
      * @throws NullPointerException if the specified key is null
      */
     public K lowerKey(K key) {
-        Node<K,V> n = findNear(key, LT);
+        Node<K,V> n = findNear(key, LT, comparator);
         return (n == null) ? null : n.key;
     }
 
@@ -2062,7 +2125,7 @@
      * @throws NullPointerException if the specified key is null
      */
     public K floorKey(K key) {
-        Node<K,V> n = findNear(key, LT|EQ);
+        Node<K,V> n = findNear(key, LT|EQ, comparator);
         return (n == null) ? null : n.key;
     }
 
@@ -2084,7 +2147,7 @@
      * @throws NullPointerException if the specified key is null
      */
     public K ceilingKey(K key) {
-        Node<K,V> n = findNear(key, GT|EQ);
+        Node<K,V> n = findNear(key, GT|EQ, comparator);
         return (n == null) ? null : n.key;
     }
 
@@ -2108,7 +2171,7 @@
      * @throws NullPointerException if the specified key is null
      */
     public K higherKey(K key) {
-        Node<K,V> n = findNear(key, GT);
+        Node<K,V> n = findNear(key, GT, comparator);
         return (n == null) ? null : n.key;
     }
 
@@ -2182,13 +2245,11 @@
 
         /** Initializes ascending iterator for entire range. */
         Iter() {
-            for (;;) {
-                next = findFirst();
-                if (next == null)
-                    break;
+            while ((next = findFirst()) != null) {
                 Object x = next.value;
                 if (x != null && x != next) {
-                    nextValue = (V) x;
+                    @SuppressWarnings("unchecked") V vv = (V)x;
+                    nextValue = vv;
                     break;
                 }
             }
@@ -2203,13 +2264,11 @@
             if (next == null)
                 throw new NoSuchElementException();
             lastReturned = next;
-            for (;;) {
-                next = next.next;
-                if (next == null)
-                    break;
+            while ((next = next.next) != null) {
                 Object x = next.value;
                 if (x != null && x != next) {
-                    nextValue = (V) x;
+                    @SuppressWarnings("unchecked") V vv = (V)x;
+                    nextValue = vv;
                     break;
                 }
             }
@@ -2252,20 +2311,6 @@
         }
     }
 
-    // Factory methods for iterators needed by ConcurrentSkipListSet etc
-
-    Iterator<K> keyIterator() {
-        return new KeyIterator();
-    }
-
-    Iterator<V> valueIterator() {
-        return new ValueIterator();
-    }
-
-    Iterator<Map.Entry<K,V>> entryIterator() {
-        return new EntryIterator();
-    }
-
     /* ---------------- View Classes -------------- */
 
     /*
@@ -2282,35 +2327,34 @@
         return list;
     }
 
-    static final class KeySet<E>
-            extends AbstractSet<E> implements NavigableSet<E> {
-        private final ConcurrentNavigableMap<E,?> m;
-        KeySet(ConcurrentNavigableMap<E,?> map) { m = map; }
+    static final class KeySet<K,V>
+            extends AbstractSet<K> implements NavigableSet<K> {
+        final ConcurrentNavigableMap<K,V> m;
+        KeySet(ConcurrentNavigableMap<K,V> map) { m = map; }
         public int size() { return m.size(); }
         public boolean isEmpty() { return m.isEmpty(); }
         public boolean contains(Object o) { return m.containsKey(o); }
         public boolean remove(Object o) { return m.remove(o) != null; }
         public void clear() { m.clear(); }
-        public E lower(E e) { return m.lowerKey(e); }
-        public E floor(E e) { return m.floorKey(e); }
-        public E ceiling(E e) { return m.ceilingKey(e); }
-        public E higher(E e) { return m.higherKey(e); }
-        public Comparator<? super E> comparator() { return m.comparator(); }
-        public E first() { return m.firstKey(); }
-        public E last() { return m.lastKey(); }
-        public E pollFirst() {
-            Map.Entry<E,?> e = m.pollFirstEntry();
+        public K lower(K e) { return m.lowerKey(e); }
+        public K floor(K e) { return m.floorKey(e); }
+        public K ceiling(K e) { return m.ceilingKey(e); }
+        public K higher(K e) { return m.higherKey(e); }
+        public Comparator<? super K> comparator() { return m.comparator(); }
+        public K first() { return m.firstKey(); }
+        public K last() { return m.lastKey(); }
+        public K pollFirst() {
+            Map.Entry<K,V> e = m.pollFirstEntry();
             return (e == null) ? null : e.getKey();
         }
-        public E pollLast() {
-            Map.Entry<E,?> e = m.pollLastEntry();
+        public K pollLast() {
+            Map.Entry<K,V> e = m.pollLastEntry();
             return (e == null) ? null : e.getKey();
         }
-        public Iterator<E> iterator() {
-            if (m instanceof ConcurrentSkipListMap)
-                return ((ConcurrentSkipListMap<E,Object>)m).keyIterator();
-            else
-                return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator();
+        public Iterator<K> iterator() {
+            return (m instanceof ConcurrentSkipListMap)
+                ? ((ConcurrentSkipListMap<K,V>)m).new KeyIterator()
+                : ((SubMap<K,V>)m).new SubMapKeyIterator();
         }
         public boolean equals(Object o) {
             if (o == this)
@@ -2328,81 +2372,99 @@
         }
         public Object[] toArray()     { return toList(this).toArray();  }
         public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
-        public Iterator<E> descendingIterator() {
+        public Iterator<K> descendingIterator() {
             return descendingSet().iterator();
         }
-        public NavigableSet<E> subSet(E fromElement,
+        public NavigableSet<K> subSet(K fromElement,
                                       boolean fromInclusive,
-                                      E toElement,
+                                      K toElement,
                                       boolean toInclusive) {
-            return new KeySet<E>(m.subMap(fromElement, fromInclusive,
-                                          toElement,   toInclusive));
+            return new KeySet<>(m.subMap(fromElement, fromInclusive,
+                                         toElement,   toInclusive));
         }
-        public NavigableSet<E> headSet(E toElement, boolean inclusive) {
-            return new KeySet<E>(m.headMap(toElement, inclusive));
+        public NavigableSet<K> headSet(K toElement, boolean inclusive) {
+            return new KeySet<>(m.headMap(toElement, inclusive));
         }
-        public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
-            return new KeySet<E>(m.tailMap(fromElement, inclusive));
+        public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
+            return new KeySet<>(m.tailMap(fromElement, inclusive));
         }
-        public NavigableSet<E> subSet(E fromElement, E toElement) {
+        public NavigableSet<K> subSet(K fromElement, K toElement) {
             return subSet(fromElement, true, toElement, false);
         }
-        public NavigableSet<E> headSet(E toElement) {
+        public NavigableSet<K> headSet(K toElement) {
             return headSet(toElement, false);
         }
-        public NavigableSet<E> tailSet(E fromElement) {
+        public NavigableSet<K> tailSet(K fromElement) {
             return tailSet(fromElement, true);
         }
-        public NavigableSet<E> descendingSet() {
-            return new KeySet<E>(m.descendingMap());
+        public NavigableSet<K> descendingSet() {
+            return new KeySet<>(m.descendingMap());
+        }
+
+        public Spliterator<K> spliterator() {
+            return (m instanceof ConcurrentSkipListMap)
+                ? ((ConcurrentSkipListMap<K,V>)m).keySpliterator()
+                : ((SubMap<K,V>)m).new SubMapKeyIterator();
         }
     }
 
-    static final class Values<E> extends AbstractCollection<E> {
-        private final ConcurrentNavigableMap<?,E> m;
-        Values(ConcurrentNavigableMap<?,E> map) {
+    static final class Values<K,V> extends AbstractCollection<V> {
+        final ConcurrentNavigableMap<K,V> m;
+        Values(ConcurrentNavigableMap<K,V> map) {
             m = map;
         }
-        public Iterator<E> iterator() {
-            if (m instanceof ConcurrentSkipListMap)
-                return ((ConcurrentSkipListMap<?,E>)m).valueIterator();
-            else
-                return ((SubMap<?,E>)m).valueIterator();
+        public Iterator<V> iterator() {
+            return (m instanceof ConcurrentSkipListMap)
+                ? ((ConcurrentSkipListMap<K,V>)m).new ValueIterator()
+                : ((SubMap<K,V>)m).new SubMapValueIterator();
         }
-        public boolean isEmpty() {
-            return m.isEmpty();
-        }
-        public int size() {
-            return m.size();
-        }
-        public boolean contains(Object o) {
-            return m.containsValue(o);
-        }
-        public void clear() {
-            m.clear();
-        }
+        public int size() { return m.size(); }
+        public boolean isEmpty() { return m.isEmpty(); }
+        public boolean contains(Object o) { return m.containsValue(o); }
+        public void clear() { m.clear(); }
         public Object[] toArray()     { return toList(this).toArray();  }
         public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
-    }
 
-    static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> {
-        private final ConcurrentNavigableMap<K1, V1> m;
-        EntrySet(ConcurrentNavigableMap<K1, V1> map) {
-            m = map;
+        public Spliterator<V> spliterator() {
+            return (m instanceof ConcurrentSkipListMap)
+                ? ((ConcurrentSkipListMap<K,V>)m).valueSpliterator()
+                : ((SubMap<K,V>)m).new SubMapValueIterator();
         }
 
-        public Iterator<Map.Entry<K1,V1>> iterator() {
+        public boolean removeIf(Predicate<? super V> filter) {
+            if (filter == null) throw new NullPointerException();
             if (m instanceof ConcurrentSkipListMap)
-                return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator();
-            else
-                return ((SubMap<K1,V1>)m).entryIterator();
+                return ((ConcurrentSkipListMap<K,V>)m).removeValueIf(filter);
+            // else use iterator
+            Iterator<Map.Entry<K,V>> it =
+                ((SubMap<K,V>)m).new SubMapEntryIterator();
+            boolean removed = false;
+            while (it.hasNext()) {
+                Map.Entry<K,V> e = it.next();
+                V v = e.getValue();
+                if (filter.test(v) && m.remove(e.getKey(), v))
+                    removed = true;
+            }
+            return removed;
+        }
+    }
+
+    static final class EntrySet<K,V> extends AbstractSet<Map.Entry<K,V>> {
+        final ConcurrentNavigableMap<K,V> m;
+        EntrySet(ConcurrentNavigableMap<K,V> map) {
+            m = map;
+        }
+        public Iterator<Map.Entry<K,V>> iterator() {
+            return (m instanceof ConcurrentSkipListMap)
+                ? ((ConcurrentSkipListMap<K,V>)m).new EntryIterator()
+                : ((SubMap<K,V>)m).new SubMapEntryIterator();
         }
 
         public boolean contains(Object o) {
             if (!(o instanceof Map.Entry))
                 return false;
             Map.Entry<?,?> e = (Map.Entry<?,?>)o;
-            V1 v = m.get(e.getKey());
+            V v = m.get(e.getKey());
             return v != null && v.equals(e.getValue());
         }
         public boolean remove(Object o) {
@@ -2437,27 +2499,47 @@
         }
         public Object[] toArray()     { return toList(this).toArray();  }
         public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
+
+        public Spliterator<Map.Entry<K,V>> spliterator() {
+            return (m instanceof ConcurrentSkipListMap)
+                ? ((ConcurrentSkipListMap<K,V>)m).entrySpliterator()
+                : ((SubMap<K,V>)m).new SubMapEntryIterator();
+        }
+        public boolean removeIf(Predicate<? super Entry<K,V>> filter) {
+            if (filter == null) throw new NullPointerException();
+            if (m instanceof ConcurrentSkipListMap)
+                return ((ConcurrentSkipListMap<K,V>)m).removeEntryIf(filter);
+            // else use iterator
+            Iterator<Map.Entry<K,V>> it =
+                ((SubMap<K,V>)m).new SubMapEntryIterator();
+            boolean removed = false;
+            while (it.hasNext()) {
+                Map.Entry<K,V> e = it.next();
+                if (filter.test(e) && m.remove(e.getKey(), e.getValue()))
+                    removed = true;
+            }
+            return removed;
+        }
     }
 
     /**
      * Submaps returned by {@link ConcurrentSkipListMap} submap operations
-     * represent a subrange of mappings of their underlying
-     * maps. Instances of this class support all methods of their
-     * underlying maps, differing in that mappings outside their range are
-     * ignored, and attempts to add mappings outside their ranges result
-     * in {@link IllegalArgumentException}.  Instances of this class are
-     * constructed only using the {@code subMap}, {@code headMap}, and
-     * {@code tailMap} methods of their underlying maps.
+     * represent a subrange of mappings of their underlying maps.
+     * Instances of this class support all methods of their underlying
+     * maps, differing in that mappings outside their range are ignored,
+     * and attempts to add mappings outside their ranges result in {@link
+     * IllegalArgumentException}.  Instances of this class are constructed
+     * only using the {@code subMap}, {@code headMap}, and {@code tailMap}
+     * methods of their underlying maps.
      *
      * @serial include
      */
     static final class SubMap<K,V> extends AbstractMap<K,V>
-        implements ConcurrentNavigableMap<K,V>, Cloneable,
-                   java.io.Serializable {
+        implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable {
         private static final long serialVersionUID = -7647078645895051609L;
 
         /** Underlying map */
-        private final ConcurrentSkipListMap<K,V> m;
+        final ConcurrentSkipListMap<K,V> m;
         /** lower bound key, or null if from start */
         private final K lo;
         /** upper bound key, or null if to end */
@@ -2467,10 +2549,10 @@
         /** inclusion flag for hi */
         private final boolean hiInclusive;
         /** direction */
-        private final boolean isDescending;
+        final boolean isDescending;
 
         // Lazily initialized view holders
-        private transient KeySet<K> keySetView;
+        private transient KeySet<K,V> keySetView;
         private transient Set<Map.Entry<K,V>> entrySetView;
         private transient Collection<V> valuesView;
 
@@ -2481,8 +2563,9 @@
                K fromKey, boolean fromInclusive,
                K toKey, boolean toInclusive,
                boolean isDescending) {
+            Comparator<? super K> cmp = map.comparator;
             if (fromKey != null && toKey != null &&
-                map.compare(fromKey, toKey) > 0)
+                cpr(cmp, fromKey, toKey) > 0)
                 throw new IllegalArgumentException("inconsistent range");
             this.m = map;
             this.lo = fromKey;
@@ -2494,39 +2577,34 @@
 
         /* ----------------  Utilities -------------- */
 
-        private boolean tooLow(K key) {
-            if (lo != null) {
-                int c = m.compare(key, lo);
-                if (c < 0 || (c == 0 && !loInclusive))
-                    return true;
-            }
-            return false;
+        boolean tooLow(Object key, Comparator<? super K> cmp) {
+            int c;
+            return (lo != null && ((c = cpr(cmp, key, lo)) < 0 ||
+                                   (c == 0 && !loInclusive)));
         }
 
-        private boolean tooHigh(K key) {
-            if (hi != null) {
-                int c = m.compare(key, hi);
-                if (c > 0 || (c == 0 && !hiInclusive))
-                    return true;
-            }
-            return false;
+        boolean tooHigh(Object key, Comparator<? super K> cmp) {
+            int c;
+            return (hi != null && ((c = cpr(cmp, key, hi)) > 0 ||
+                                   (c == 0 && !hiInclusive)));
         }
 
-        private boolean inBounds(K key) {
-            return !tooLow(key) && !tooHigh(key);
+        boolean inBounds(Object key, Comparator<? super K> cmp) {
+            return !tooLow(key, cmp) && !tooHigh(key, cmp);
         }
 
-        private void checkKeyBounds(K key) throws IllegalArgumentException {
+        void checkKeyBounds(K key, Comparator<? super K> cmp) {
             if (key == null)
                 throw new NullPointerException();
-            if (!inBounds(key))
+            if (!inBounds(key, cmp))
                 throw new IllegalArgumentException("key out of range");
         }
 
         /**
          * Returns true if node key is less than upper bound of range.
          */
-        private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) {
+        boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n,
+                            Comparator<? super K> cmp) {
             if (n == null)
                 return false;
             if (hi == null)
@@ -2534,7 +2612,7 @@
             K k = n.key;
             if (k == null) // pass by markers and headers
                 return true;
-            int c = m.compare(k, hi);
+            int c = cpr(cmp, k, hi);
             if (c > 0 || (c == 0 && !hiInclusive))
                 return false;
             return true;
@@ -2544,34 +2622,35 @@
          * Returns lowest node. This node might not be in range, so
          * most usages need to check bounds.
          */
-        private ConcurrentSkipListMap.Node<K,V> loNode() {
+        ConcurrentSkipListMap.Node<K,V> loNode(Comparator<? super K> cmp) {
             if (lo == null)
                 return m.findFirst();
             else if (loInclusive)
-                return m.findNear(lo, GT|EQ);
+                return m.findNear(lo, GT|EQ, cmp);
             else
-                return m.findNear(lo, GT);
+                return m.findNear(lo, GT, cmp);
         }
 
         /**
          * Returns highest node. This node might not be in range, so
          * most usages need to check bounds.
          */
-        private ConcurrentSkipListMap.Node<K,V> hiNode() {
+        ConcurrentSkipListMap.Node<K,V> hiNode(Comparator<? super K> cmp) {
             if (hi == null)
                 return m.findLast();
             else if (hiInclusive)
-                return m.findNear(hi, LT|EQ);
+                return m.findNear(hi, LT|EQ, cmp);
             else
-                return m.findNear(hi, LT);
+                return m.findNear(hi, LT, cmp);
         }
 
         /**
          * Returns lowest absolute key (ignoring directionality).
          */
-        private K lowestKey() {
-            ConcurrentSkipListMap.Node<K,V> n = loNode();
-            if (isBeforeEnd(n))
+        K lowestKey() {
+            Comparator<? super K> cmp = m.comparator;
+            ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+            if (isBeforeEnd(n, cmp))
                 return n.key;
             else
                 throw new NoSuchElementException();
@@ -2580,20 +2659,22 @@
         /**
          * Returns highest absolute key (ignoring directionality).
          */
-        private K highestKey() {
-            ConcurrentSkipListMap.Node<K,V> n = hiNode();
+        K highestKey() {
+            Comparator<? super K> cmp = m.comparator;
+            ConcurrentSkipListMap.Node<K,V> n = hiNode(cmp);
             if (n != null) {
                 K last = n.key;
-                if (inBounds(last))
+                if (inBounds(last, cmp))
                     return last;
             }
             throw new NoSuchElementException();
         }
 
-        private Map.Entry<K,V> lowestEntry() {
+        Map.Entry<K,V> lowestEntry() {
+            Comparator<? super K> cmp = m.comparator;
             for (;;) {
-                ConcurrentSkipListMap.Node<K,V> n = loNode();
-                if (!isBeforeEnd(n))
+                ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                if (!isBeforeEnd(n, cmp))
                     return null;
                 Map.Entry<K,V> e = n.createSnapshot();
                 if (e != null)
@@ -2601,10 +2682,11 @@
             }
         }
 
-        private Map.Entry<K,V> highestEntry() {
+        Map.Entry<K,V> highestEntry() {
+            Comparator<? super K> cmp = m.comparator;
             for (;;) {
-                ConcurrentSkipListMap.Node<K,V> n = hiNode();
-                if (n == null || !inBounds(n.key))
+                ConcurrentSkipListMap.Node<K,V> n = hiNode(cmp);
+                if (n == null || !inBounds(n.key, cmp))
                     return null;
                 Map.Entry<K,V> e = n.createSnapshot();
                 if (e != null)
@@ -2612,13 +2694,14 @@
             }
         }
 
-        private Map.Entry<K,V> removeLowest() {
+        Map.Entry<K,V> removeLowest() {
+            Comparator<? super K> cmp = m.comparator;
             for (;;) {
-                Node<K,V> n = loNode();
+                Node<K,V> n = loNode(cmp);
                 if (n == null)
                     return null;
                 K k = n.key;
-                if (!inBounds(k))
+                if (!inBounds(k, cmp))
                     return null;
                 V v = m.doRemove(k, null);
                 if (v != null)
@@ -2626,13 +2709,14 @@
             }
         }
 
-        private Map.Entry<K,V> removeHighest() {
+        Map.Entry<K,V> removeHighest() {
+            Comparator<? super K> cmp = m.comparator;
             for (;;) {
-                Node<K,V> n = hiNode();
+                Node<K,V> n = hiNode(cmp);
                 if (n == null)
                     return null;
                 K k = n.key;
-                if (!inBounds(k))
+                if (!inBounds(k, cmp))
                     return null;
                 V v = m.doRemove(k, null);
                 if (v != null)
@@ -2641,22 +2725,23 @@
         }
 
         /**
-         * Submap version of ConcurrentSkipListMap.getNearEntry
+         * Submap version of ConcurrentSkipListMap.getNearEntry.
          */
-        private Map.Entry<K,V> getNearEntry(K key, int rel) {
+        Map.Entry<K,V> getNearEntry(K key, int rel) {
+            Comparator<? super K> cmp = m.comparator;
             if (isDescending) { // adjust relation for direction
                 if ((rel & LT) == 0)
                     rel |= LT;
                 else
                     rel &= ~LT;
             }
-            if (tooLow(key))
+            if (tooLow(key, cmp))
                 return ((rel & LT) != 0) ? null : lowestEntry();
-            if (tooHigh(key))
+            if (tooHigh(key, cmp))
                 return ((rel & LT) != 0) ? highestEntry() : null;
             for (;;) {
-                Node<K,V> n = m.findNear(key, rel);
-                if (n == null || !inBounds(n.key))
+                Node<K,V> n = m.findNear(key, rel, cmp);
+                if (n == null || !inBounds(n.key, cmp))
                     return null;
                 K k = n.key;
                 V v = n.getValidValue();
@@ -2666,35 +2751,36 @@
         }
 
         // Almost the same as getNearEntry, except for keys
-        private K getNearKey(K key, int rel) {
+        K getNearKey(K key, int rel) {
+            Comparator<? super K> cmp = m.comparator;
             if (isDescending) { // adjust relation for direction
                 if ((rel & LT) == 0)
                     rel |= LT;
                 else
                     rel &= ~LT;
             }
-            if (tooLow(key)) {
+            if (tooLow(key, cmp)) {
                 if ((rel & LT) == 0) {
-                    ConcurrentSkipListMap.Node<K,V> n = loNode();
-                    if (isBeforeEnd(n))
+                    ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                    if (isBeforeEnd(n, cmp))
                         return n.key;
                 }
                 return null;
             }
-            if (tooHigh(key)) {
+            if (tooHigh(key, cmp)) {
                 if ((rel & LT) != 0) {
-                    ConcurrentSkipListMap.Node<K,V> n = hiNode();
+                    ConcurrentSkipListMap.Node<K,V> n = hiNode(cmp);
                     if (n != null) {
                         K last = n.key;
-                        if (inBounds(last))
+                        if (inBounds(last, cmp))
                             return last;
                     }
                 }
                 return null;
             }
             for (;;) {
-                Node<K,V> n = m.findNear(key, rel);
-                if (n == null || !inBounds(n.key))
+                Node<K,V> n = m.findNear(key, rel, cmp);
+                if (n == null || !inBounds(n.key, cmp))
                     return null;
                 K k = n.key;
                 V v = n.getValidValue();
@@ -2707,30 +2793,28 @@
 
         public boolean containsKey(Object key) {
             if (key == null) throw new NullPointerException();
-            K k = (K)key;
-            return inBounds(k) && m.containsKey(k);
+            return inBounds(key, m.comparator) && m.containsKey(key);
         }
 
         public V get(Object key) {
             if (key == null) throw new NullPointerException();
-            K k = (K)key;
-            return (!inBounds(k)) ? null : m.get(k);
+            return (!inBounds(key, m.comparator)) ? null : m.get(key);
         }
 
         public V put(K key, V value) {
-            checkKeyBounds(key);
+            checkKeyBounds(key, m.comparator);
             return m.put(key, value);
         }
 
         public V remove(Object key) {
-            K k = (K)key;
-            return (!inBounds(k)) ? null : m.remove(k);
+            return (!inBounds(key, m.comparator)) ? null : m.remove(key);
         }
 
         public int size() {
+            Comparator<? super K> cmp = m.comparator;
             long count = 0;
-            for (ConcurrentSkipListMap.Node<K,V> n = loNode();
-                 isBeforeEnd(n);
+            for (ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                 isBeforeEnd(n, cmp);
                  n = n.next) {
                 if (n.getValidValue() != null)
                     ++count;
@@ -2739,14 +2823,16 @@
         }
 
         public boolean isEmpty() {
-            return !isBeforeEnd(loNode());
+            Comparator<? super K> cmp = m.comparator;
+            return !isBeforeEnd(loNode(cmp), cmp);
         }
 
         public boolean containsValue(Object value) {
             if (value == null)
                 throw new NullPointerException();
-            for (ConcurrentSkipListMap.Node<K,V> n = loNode();
-                 isBeforeEnd(n);
+            Comparator<? super K> cmp = m.comparator;
+            for (ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                 isBeforeEnd(n, cmp);
                  n = n.next) {
                 V v = n.getValidValue();
                 if (v != null && value.equals(v))
@@ -2756,8 +2842,9 @@
         }
 
         public void clear() {
-            for (ConcurrentSkipListMap.Node<K,V> n = loNode();
-                 isBeforeEnd(n);
+            Comparator<? super K> cmp = m.comparator;
+            for (ConcurrentSkipListMap.Node<K,V> n = loNode(cmp);
+                 isBeforeEnd(n, cmp);
                  n = n.next) {
                 if (n.getValidValue() != null)
                     m.remove(n.key);
@@ -2767,22 +2854,21 @@
         /* ----------------  ConcurrentMap API methods -------------- */
 
         public V putIfAbsent(K key, V value) {
-            checkKeyBounds(key);
+            checkKeyBounds(key, m.comparator);
             return m.putIfAbsent(key, value);
         }
 
         public boolean remove(Object key, Object value) {
-            K k = (K)key;
-            return inBounds(k) && m.remove(k, value);
+            return inBounds(key, m.comparator) && m.remove(key, value);
         }
 
         public boolean replace(K key, V oldValue, V newValue) {
-            checkKeyBounds(key);
+            checkKeyBounds(key, m.comparator);
             return m.replace(key, oldValue, newValue);
         }
 
         public V replace(K key, V value) {
-            checkKeyBounds(key);
+            checkKeyBounds(key, m.comparator);
             return m.replace(key, value);
         }
 
@@ -2800,10 +2886,9 @@
          * Utility to create submaps, where given bounds override
          * unbounded(null) ones and/or are checked against bounded ones.
          */
-        private SubMap<K,V> newSubMap(K fromKey,
-                                      boolean fromInclusive,
-                                      K toKey,
-                                      boolean toInclusive) {
+        SubMap<K,V> newSubMap(K fromKey, boolean fromInclusive,
+                              K toKey, boolean toInclusive) {
+            Comparator<? super K> cmp = m.comparator;
             if (isDescending) { // flip senses
                 K tk = fromKey;
                 fromKey = toKey;
@@ -2818,7 +2903,7 @@
                     fromInclusive = loInclusive;
                 }
                 else {
-                    int c = m.compare(fromKey, lo);
+                    int c = cpr(cmp, fromKey, lo);
                     if (c < 0 || (c == 0 && !loInclusive && fromInclusive))
                         throw new IllegalArgumentException("key out of range");
                 }
@@ -2829,7 +2914,7 @@
                     toInclusive = hiInclusive;
                 }
                 else {
-                    int c = m.compare(toKey, hi);
+                    int c = cpr(cmp, toKey, hi);
                     if (c > 0 || (c == 0 && !hiInclusive && toInclusive))
                         throw new IllegalArgumentException("key out of range");
                 }
@@ -2838,24 +2923,20 @@
                                    toKey, toInclusive, isDescending);
         }
 
-        public SubMap<K,V> subMap(K fromKey,
-                                  boolean fromInclusive,
-                                  K toKey,
-                                  boolean toInclusive) {
+        public SubMap<K,V> subMap(K fromKey, boolean fromInclusive,
+                                  K toKey, boolean toInclusive) {
             if (fromKey == null || toKey == null)
                 throw new NullPointerException();
             return newSubMap(fromKey, fromInclusive, toKey, toInclusive);
         }
 
-        public SubMap<K,V> headMap(K toKey,
-                                   boolean inclusive) {
+        public SubMap<K,V> headMap(K toKey, boolean inclusive) {
             if (toKey == null)
                 throw new NullPointerException();
             return newSubMap(null, false, toKey, inclusive);
         }
 
-        public SubMap<K,V> tailMap(K fromKey,
-                                   boolean inclusive) {
+        public SubMap<K,V> tailMap(K fromKey, boolean inclusive) {
             if (fromKey == null)
                 throw new NullPointerException();
             return newSubMap(fromKey, inclusive, null, false);
@@ -2939,18 +3020,18 @@
         /* ---------------- Submap Views -------------- */
 
         public NavigableSet<K> keySet() {
-            KeySet<K> ks = keySetView;
-            return (ks != null) ? ks : (keySetView = new KeySet<K>(this));
+            KeySet<K,V> ks = keySetView;
+            return (ks != null) ? ks : (keySetView = new KeySet<>(this));
         }
 
         public NavigableSet<K> navigableKeySet() {
-            KeySet<K> ks = keySetView;
-            return (ks != null) ? ks : (keySetView = new KeySet<K>(this));
+            KeySet<K,V> ks = keySetView;
+            return (ks != null) ? ks : (keySetView = new KeySet<>(this));
         }
 
         public Collection<V> values() {
             Collection<V> vs = valuesView;
-            return (vs != null) ? vs : (valuesView = new Values<V>(this));
+            return (vs != null) ? vs : (valuesView = new Values<>(this));
         }
 
         public Set<Map.Entry<K,V>> entrySet() {
@@ -2962,22 +3043,11 @@
             return descendingMap().navigableKeySet();
         }
 
-        Iterator<K> keyIterator() {
-            return new SubMapKeyIterator();
-        }
-
-        Iterator<V> valueIterator() {
-            return new SubMapValueIterator();
-        }
-
-        Iterator<Map.Entry<K,V>> entryIterator() {
-            return new SubMapEntryIterator();
-        }
-
         /**
          * Variant of main Iter class to traverse through submaps.
+         * Also serves as back-up Spliterator for views.
          */
-        abstract class SubMapIter<T> implements Iterator<T> {
+        abstract class SubMapIter<T> implements Iterator<T>, Spliterator<T> {
             /** the last node returned by next() */
             Node<K,V> lastReturned;
             /** the next node to return from next(); */
@@ -2986,16 +3056,19 @@
             V nextValue;
 
             SubMapIter() {
+                Comparator<? super K> cmp = m.comparator;
                 for (;;) {
-                    next = isDescending ? hiNode() : loNode();
+                    next = isDescending ? hiNode(cmp) : loNode(cmp);
                     if (next == null)
                         break;
                     Object x = next.value;
                     if (x != null && x != next) {
-                        if (! inBounds(next.key))
+                        if (! inBounds(next.key, cmp))
                             next = null;
-                        else
-                            nextValue = (V) x;
+                        else {
+                            @SuppressWarnings("unchecked") V vv = (V)x;
+                            nextValue = vv;
+                        }
                         break;
                     }
                 }
@@ -3016,32 +3089,38 @@
             }
 
             private void ascend() {
+                Comparator<? super K> cmp = m.comparator;
                 for (;;) {
                     next = next.next;
                     if (next == null)
                         break;
                     Object x = next.value;
                     if (x != null && x != next) {
-                        if (tooHigh(next.key))
+                        if (tooHigh(next.key, cmp))
                             next = null;
-                        else
-                            nextValue = (V) x;
+                        else {
+                            @SuppressWarnings("unchecked") V vv = (V)x;
+                            nextValue = vv;
+                        }
                         break;
                     }
                 }
             }
 
             private void descend() {
+                Comparator<? super K> cmp = m.comparator;
                 for (;;) {
-                    next = m.findNear(lastReturned.key, LT);
+                    next = m.findNear(lastReturned.key, LT, cmp);
                     if (next == null)
                         break;
                     Object x = next.value;
                     if (x != null && x != next) {
-                        if (tooLow(next.key))
+                        if (tooLow(next.key, cmp))
                             next = null;
-                        else
-                            nextValue = (V) x;
+                        else {
+                            @SuppressWarnings("unchecked") V vv = (V)x;
+                            nextValue = vv;
+                        }
                         break;
                     }
                 }
@@ -3055,6 +3134,27 @@
                 lastReturned = null;
             }
 
+            public Spliterator<T> trySplit() {
+                return null;
+            }
+
+            public boolean tryAdvance(Consumer<? super T> action) {
+                if (hasNext()) {
+                    action.accept(next());
+                    return true;
+                }
+                return false;
+            }
+
+            public void forEachRemaining(Consumer<? super T> action) {
+                while (hasNext())
+                    action.accept(next());
+            }
+
+            public long estimateSize() {
+                return Long.MAX_VALUE;
+            }
+
         }
 
         final class SubMapValueIterator extends SubMapIter<V> {
@@ -3063,6 +3163,9 @@
                 advance();
                 return v;
             }
+            public int characteristics() {
+                return 0;
+            }
         }
 
         final class SubMapKeyIterator extends SubMapIter<K> {
@@ -3071,6 +3174,13 @@
                 advance();
                 return n.key;
             }
+            public int characteristics() {
+                return Spliterator.DISTINCT | Spliterator.ORDERED |
+                    Spliterator.SORTED;
+            }
+            public final Comparator<? super K> getComparator() {
+                return SubMap.this.comparator();
+            }
         }
 
         final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> {
@@ -3080,19 +3190,390 @@
                 advance();
                 return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
             }
+            public int characteristics() {
+                return Spliterator.DISTINCT;
+            }
+        }
+    }
+
+    // default Map method overrides
+
+    public void forEach(BiConsumer<? super K, ? super V> action) {
+        if (action == null) throw new NullPointerException();
+        V v;
+        for (Node<K,V> n = findFirst(); n != null; n = n.next) {
+            if ((v = n.getValidValue()) != null)
+                action.accept(n.key, v);
+        }
+    }
+
+    public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
+        if (function == null) throw new NullPointerException();
+        V v;
+        for (Node<K,V> n = findFirst(); n != null; n = n.next) {
+            while ((v = n.getValidValue()) != null) {
+                V r = function.apply(n.key, v);
+                if (r == null) throw new NullPointerException();
+                if (n.casValue(v, r))
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Helper method for EntrySet.removeIf.
+     */
+    boolean removeEntryIf(Predicate<? super Entry<K,V>> function) {
+        if (function == null) throw new NullPointerException();
+        boolean removed = false;
+        for (Node<K,V> n = findFirst(); n != null; n = n.next) {
+            V v;
+            if ((v = n.getValidValue()) != null) {
+                K k = n.key;
+                Map.Entry<K,V> e = new AbstractMap.SimpleImmutableEntry<>(k, v);
+                if (function.test(e) && remove(k, v))
+                    removed = true;
+            }
+        }
+        return removed;
+    }
+
+    /**
+     * Helper method for Values.removeIf.
+     */
+    boolean removeValueIf(Predicate<? super V> function) {
+        if (function == null) throw new NullPointerException();
+        boolean removed = false;
+        for (Node<K,V> n = findFirst(); n != null; n = n.next) {
+            V v;
+            if ((v = n.getValidValue()) != null) {
+                K k = n.key;
+                if (function.test(v) && remove(k, v))
+                    removed = true;
+            }
+        }
+        return removed;
+    }
+
+    /**
+     * Base class providing common structure for Spliterators.
+     * (Although not all that much common functionality; as usual for
+     * view classes, details annoyingly vary in key, value, and entry
+     * subclasses in ways that are not worth abstracting out for
+     * internal classes.)
+     *
+     * The basic split strategy is to recursively descend from top
+     * level, row by row, descending to next row when either split
+     * off, or the end of row is encountered. Control of the number of
+     * splits relies on some statistical estimation: The expected
+     * remaining number of elements of a skip list when advancing
+     * either across or down decreases by about 25%. To make this
+     * observation useful, we need to know initial size, which we
+     * don't. But we can just use Integer.MAX_VALUE so that we
+     * don't prematurely zero out while splitting.
+     */
+    abstract static class CSLMSpliterator<K,V> {
+        final Comparator<? super K> comparator;
+        final K fence;     // exclusive upper bound for keys, or null if to end
+        Index<K,V> row;    // the level to split out
+        Node<K,V> current; // current traversal node; initialize at origin
+        int est;           // pseudo-size estimate
+        CSLMSpliterator(Comparator<? super K> comparator, Index<K,V> row,
+                        Node<K,V> origin, K fence, int est) {
+            this.comparator = comparator; this.row = row;
+            this.current = origin; this.fence = fence; this.est = est;
+        }
+
+        public final long estimateSize() { return (long)est; }
+    }
+
+    static final class KeySpliterator<K,V> extends CSLMSpliterator<K,V>
+        implements Spliterator<K> {
+        KeySpliterator(Comparator<? super K> comparator, Index<K,V> row,
+                       Node<K,V> origin, K fence, int est) {
+            super(comparator, row, origin, fence, est);
+        }
+
+        public KeySpliterator<K,V> trySplit() {
+            Node<K,V> e; K ek;
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            if ((e = current) != null && (ek = e.key) != null) {
+                for (Index<K,V> q = row; q != null; q = row = q.down) {
+                    Index<K,V> s; Node<K,V> b, n; K sk;
+                    if ((s = q.right) != null && (b = s.node) != null &&
+                        (n = b.next) != null && n.value != null &&
+                        (sk = n.key) != null && cpr(cmp, sk, ek) > 0 &&
+                        (f == null || cpr(cmp, sk, f) < 0)) {
+                        current = n;
+                        Index<K,V> r = q.down;
+                        row = (s.right != null) ? s : s.down;
+                        est -= est >>> 2;
+                        return new KeySpliterator<K,V>(cmp, r, e, sk, est);
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super K> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            current = null;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0)
+                    break;
+                if ((v = e.value) != null && v != e)
+                    action.accept(k);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super K> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) {
+                    e = null;
+                    break;
+                }
+                if ((v = e.value) != null && v != e) {
+                    current = e.next;
+                    action.accept(k);
+                    return true;
+                }
+            }
+            current = e;
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.DISTINCT | Spliterator.SORTED |
+                Spliterator.ORDERED | Spliterator.CONCURRENT |
+                Spliterator.NONNULL;
+        }
+
+        public final Comparator<? super K> getComparator() {
+            return comparator;
+        }
+    }
+    // factory method for KeySpliterator
+    final KeySpliterator<K,V> keySpliterator() {
+        Comparator<? super K> cmp = comparator;
+        for (;;) { // ensure h corresponds to origin p
+            HeadIndex<K,V> h; Node<K,V> p;
+            Node<K,V> b = (h = head).node;
+            if ((p = b.next) == null || p.value != null)
+                return new KeySpliterator<K,V>(cmp, h, p, null, (p == null) ?
+                                               0 : Integer.MAX_VALUE);
+            p.helpDelete(b, p.next);
+        }
+    }
+
+    static final class ValueSpliterator<K,V> extends CSLMSpliterator<K,V>
+        implements Spliterator<V> {
+        ValueSpliterator(Comparator<? super K> comparator, Index<K,V> row,
+                       Node<K,V> origin, K fence, int est) {
+            super(comparator, row, origin, fence, est);
+        }
+
+        public ValueSpliterator<K,V> trySplit() {
+            Node<K,V> e; K ek;
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            if ((e = current) != null && (ek = e.key) != null) {
+                for (Index<K,V> q = row; q != null; q = row = q.down) {
+                    Index<K,V> s; Node<K,V> b, n; K sk;
+                    if ((s = q.right) != null && (b = s.node) != null &&
+                        (n = b.next) != null && n.value != null &&
+                        (sk = n.key) != null && cpr(cmp, sk, ek) > 0 &&
+                        (f == null || cpr(cmp, sk, f) < 0)) {
+                        current = n;
+                        Index<K,V> r = q.down;
+                        row = (s.right != null) ? s : s.down;
+                        est -= est >>> 2;
+                        return new ValueSpliterator<K,V>(cmp, r, e, sk, est);
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super V> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            current = null;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0)
+                    break;
+                if ((v = e.value) != null && v != e) {
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    action.accept(vv);
+                }
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super V> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) {
+                    e = null;
+                    break;
+                }
+                if ((v = e.value) != null && v != e) {
+                    current = e.next;
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    action.accept(vv);
+                    return true;
+                }
+            }
+            current = e;
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.CONCURRENT | Spliterator.ORDERED |
+                Spliterator.NONNULL;
+        }
+    }
+
+    // Almost the same as keySpliterator()
+    final ValueSpliterator<K,V> valueSpliterator() {
+        Comparator<? super K> cmp = comparator;
+        for (;;) {
+            HeadIndex<K,V> h; Node<K,V> p;
+            Node<K,V> b = (h = head).node;
+            if ((p = b.next) == null || p.value != null)
+                return new ValueSpliterator<K,V>(cmp, h, p, null, (p == null) ?
+                                                 0 : Integer.MAX_VALUE);
+            p.helpDelete(b, p.next);
+        }
+    }
+
+    static final class EntrySpliterator<K,V> extends CSLMSpliterator<K,V>
+        implements Spliterator<Map.Entry<K,V>> {
+        EntrySpliterator(Comparator<? super K> comparator, Index<K,V> row,
+                         Node<K,V> origin, K fence, int est) {
+            super(comparator, row, origin, fence, est);
+        }
+
+        public EntrySpliterator<K,V> trySplit() {
+            Node<K,V> e; K ek;
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            if ((e = current) != null && (ek = e.key) != null) {
+                for (Index<K,V> q = row; q != null; q = row = q.down) {
+                    Index<K,V> s; Node<K,V> b, n; K sk;
+                    if ((s = q.right) != null && (b = s.node) != null &&
+                        (n = b.next) != null && n.value != null &&
+                        (sk = n.key) != null && cpr(cmp, sk, ek) > 0 &&
+                        (f == null || cpr(cmp, sk, f) < 0)) {
+                        current = n;
+                        Index<K,V> r = q.down;
+                        row = (s.right != null) ? s : s.down;
+                        est -= est >>> 2;
+                        return new EntrySpliterator<K,V>(cmp, r, e, sk, est);
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super Map.Entry<K,V>> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            current = null;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0)
+                    break;
+                if ((v = e.value) != null && v != e) {
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    action.accept
+                        (new AbstractMap.SimpleImmutableEntry<K,V>(k, vv));
+                }
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
+            if (action == null) throw new NullPointerException();
+            Comparator<? super K> cmp = comparator;
+            K f = fence;
+            Node<K,V> e = current;
+            for (; e != null; e = e.next) {
+                K k; Object v;
+                if ((k = e.key) != null && f != null && cpr(cmp, f, k) <= 0) {
+                    e = null;
+                    break;
+                }
+                if ((v = e.value) != null && v != e) {
+                    current = e.next;
+                    @SuppressWarnings("unchecked") V vv = (V)v;
+                    action.accept
+                        (new AbstractMap.SimpleImmutableEntry<K,V>(k, vv));
+                    return true;
+                }
+            }
+            current = e;
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.DISTINCT | Spliterator.SORTED |
+                Spliterator.ORDERED | Spliterator.CONCURRENT |
+                Spliterator.NONNULL;
+        }
+
+        public final Comparator<Map.Entry<K,V>> getComparator() {
+            // Adapt or create a key-based comparator
+            if (comparator != null) {
+                return Map.Entry.comparingByKey(comparator);
+            }
+            else {
+                return (Comparator<Map.Entry<K,V>> & Serializable) (e1, e2) -> {
+                    @SuppressWarnings("unchecked")
+                    Comparable<? super K> k1 = (Comparable<? super K>) e1.getKey();
+                    return k1.compareTo(e2.getKey());
+                };
+            }
+        }
+    }
+
+    // Almost the same as keySpliterator()
+    final EntrySpliterator<K,V> entrySpliterator() {
+        Comparator<? super K> cmp = comparator;
+        for (;;) { // almost same as key version
+            HeadIndex<K,V> h; Node<K,V> p;
+            Node<K,V> b = (h = head).node;
+            if ((p = b.next) == null || p.value != null)
+                return new EntrySpliterator<K,V>(cmp, h, p, null, (p == null) ?
+                                                 0 : Integer.MAX_VALUE);
+            p.helpDelete(b, p.next);
         }
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe UNSAFE;
-    private static final long headOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long HEAD;
     static {
         try {
-            UNSAFE = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = ConcurrentSkipListMap.class;
-            headOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("head"));
-        } catch (Exception e) {
+            HEAD = U.objectFieldOffset
+                (ConcurrentSkipListMap.class.getDeclaredField("head"));
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
     }
diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java
index 13f1a43..1719822 100644
--- a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java
+++ b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java
@@ -6,10 +6,21 @@
 
 package java.util.concurrent;
 
-import java.util.*;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.Spliterator;
 
 // BEGIN android-note
 // removed link to collections framework docs
+// fixed framework docs link to "Collection#optional"
 // END android-note
 
 /**
@@ -23,12 +34,12 @@
  * cost for the {@code contains}, {@code add}, and {@code remove}
  * operations and their variants.  Insertion, removal, and access
  * operations safely execute concurrently by multiple threads.
- * Iterators are <i>weakly consistent</i>, returning elements
- * reflecting the state of the set at some point at or since the
- * creation of the iterator.  They do <em>not</em> throw {@link
- * ConcurrentModificationException}, and may proceed concurrently with
- * other operations.  Ascending ordered views and their iterators are
- * faster than descending ones.
+ *
+ * <p>Iterators and spliterators are
+ * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+ *
+ * <p>Ascending ordered views and their iterators are faster than
+ * descending ones.
  *
  * <p>Beware that, unlike in most collections, the {@code size}
  * method is <em>not</em> a constant-time operation. Because of the
@@ -285,8 +296,9 @@
      *
      * @param  c collection containing elements to be removed from this set
      * @return {@code true} if this set changed as a result of the call
-     * @throws ClassCastException if the types of one or more elements in this
-     *         set are incompatible with the specified collection
+     * @throws ClassCastException if the class of an element of this set
+     *         is incompatible with the specified collection
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified collection or any
      *         of its elements are null
      */
@@ -346,20 +358,19 @@
 
     /* ---------------- SortedSet operations -------------- */
 
-
     public Comparator<? super E> comparator() {
         return m.comparator();
     }
 
     /**
-     * @throws NoSuchElementException {@inheritDoc}
+     * @throws java.util.NoSuchElementException {@inheritDoc}
      */
     public E first() {
         return m.firstKey();
     }
 
     /**
-     * @throws NoSuchElementException {@inheritDoc}
+     * @throws java.util.NoSuchElementException {@inheritDoc}
      */
     public E last() {
         return m.lastKey();
@@ -442,20 +453,42 @@
         return new ConcurrentSkipListSet<E>(m.descendingMap());
     }
 
-    // Support for resetting map in clone
-    private void setMap(ConcurrentNavigableMap<E,Object> map) {
-        UNSAFE.putObjectVolatile(this, mapOffset, map);
+    /**
+     * Returns a {@link Spliterator} over the elements in this set.
+     *
+     * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#NONNULL}, {@link Spliterator#DISTINCT},
+     * {@link Spliterator#SORTED} and {@link Spliterator#ORDERED}, with an
+     * encounter order that is ascending order.  Overriding implementations
+     * should document the reporting of additional characteristic values.
+     *
+     * <p>The spliterator's comparator (see
+     * {@link java.util.Spliterator#getComparator()}) is {@code null} if
+     * the set's comparator (see {@link #comparator()}) is {@code null}.
+     * Otherwise, the spliterator's comparator is the same as or imposes the
+     * same total ordering as the set's comparator.
+     *
+     * @return a {@code Spliterator} over the elements in this set
+     * @since 1.8
+     */
+    public Spliterator<E> spliterator() {
+        return (m instanceof ConcurrentSkipListMap)
+            ? ((ConcurrentSkipListMap<E,?>)m).keySpliterator()
+            : ((ConcurrentSkipListMap.SubMap<E,?>)m).new SubMapKeyIterator();
     }
 
-    private static final sun.misc.Unsafe UNSAFE;
-    private static final long mapOffset;
+    // Support for resetting map in clone
+    private void setMap(ConcurrentNavigableMap<E,Object> map) {
+        U.putObjectVolatile(this, MAP, map);
+    }
+
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long MAP;
     static {
         try {
-            UNSAFE = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = ConcurrentSkipListSet.class;
-            mapOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("m"));
-        } catch (Exception e) {
+            MAP = U.objectFieldOffset
+                (ConcurrentSkipListSet.class.getDeclaredField("m"));
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
     }
diff --git a/luni/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java b/luni/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
index 798eaaf..c8e342e 100644
--- a/luni/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
+++ b/luni/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
@@ -1,783 +1,1542 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group.  Adapted and released, under explicit permission,
+ * from JDK ArrayList.java which carries the following copyright:
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Copyright 1997 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
  */
 
 package java.util.concurrent;
 
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
+
 import java.util.AbstractList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.ConcurrentModificationException;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.RandomAccess;
+import java.util.Spliterator;
+import java.util.Spliterators;
 import java.util.function.Consumer;
-
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
 import libcore.util.EmptyArray;
-import libcore.util.Objects;
+
+// BEGIN android-note
+// removed link to collections framework docs from header
+// END android-note
 
 /**
- * A thread-safe random-access list.
+ * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
+ * operations ({@code add}, {@code set}, and so on) are implemented by
+ * making a fresh copy of the underlying array.
  *
- * <p>Read operations (including {@link #get}) do not block and may overlap with
- * update operations. Reads reflect the results of the most recently completed
- * operations. Aggregate operations like {@link #addAll} and {@link #clear} are
- * atomic; they never expose an intermediate state.
+ * <p>This is ordinarily too costly, but may be <em>more</em> efficient
+ * than alternatives when traversal operations vastly outnumber
+ * mutations, and is useful when you cannot or don't want to
+ * synchronize traversals, yet need to preclude interference among
+ * concurrent threads.  The "snapshot" style iterator method uses a
+ * reference to the state of the array at the point that the iterator
+ * was created. This array never changes during the lifetime of the
+ * iterator, so interference is impossible and the iterator is
+ * guaranteed not to throw {@code ConcurrentModificationException}.
+ * The iterator will not reflect additions, removals, or changes to
+ * the list since the iterator was created.  Element-changing
+ * operations on iterators themselves ({@code remove}, {@code set}, and
+ * {@code add}) are not supported. These methods throw
+ * {@code UnsupportedOperationException}.
  *
- * <p>Iterators of this list never throw {@link
- * ConcurrentModificationException}. When an iterator is created, it keeps a
- * copy of the list's contents. It is always safe to iterate this list, but
- * iterations may not reflect the latest state of the list.
+ * <p>All elements are permitted, including {@code null}.
  *
- * <p>Iterators returned by this list and its sub lists cannot modify the
- * underlying list. In particular, {@link Iterator#remove}, {@link
- * ListIterator#add} and {@link ListIterator#set} all throw {@link
- * UnsupportedOperationException}.
+ * <p>Memory consistency effects: As with other concurrent
+ * collections, actions in a thread prior to placing an object into a
+ * {@code CopyOnWriteArrayList}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions subsequent to the access or removal of that element from
+ * the {@code CopyOnWriteArrayList} in another thread.
  *
- * <p>This class offers extended API beyond the {@link List} interface. It
- * includes additional overloads for indexed search ({@link #indexOf} and {@link
- * #lastIndexOf}) and methods for conditional adds ({@link #addIfAbsent} and
- * {@link #addAllAbsent}).
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this list
  */
-public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
-
+public class CopyOnWriteArrayList<E>
+    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
     private static final long serialVersionUID = 8673264195747942595L;
 
     /**
-     * Holds the latest snapshot of the list's data. This field is volatile so
-     * that data can be read without synchronization. As a consequence, all
-     * writes to this field must be atomic; it is an error to modify the
-     * contents of an array after it has been assigned to this field.
-     *
-     * Synchronization is required by all update operations. This defends
-     * against one update clobbering the result of another operation. For
-     * example, 100 threads simultaneously calling add() will grow the list's
-     * size by 100 when they have completed. No update operations are lost!
-     *
-     * Maintainers should be careful to read this field only once in
-     * non-blocking read methods. Write methods must be synchronized to avoid
-     * clobbering concurrent writes.
+     * The lock protecting all mutators.  (We have a mild preference
+     * for builtin monitors over ReentrantLock when either will do.)
      */
-    private transient volatile Object[] elements;
+    final transient Object lock = new Object();
+
+    /** The array, accessed only via getArray/setArray. */
+    private transient volatile Object[] array;
 
     /**
-     * Creates a new empty instance.
+     * Gets the array.  Non-private so as to also be accessible
+     * from CopyOnWriteArraySet class.
+     */
+    final Object[] getArray() {
+        return array;
+    }
+
+    /**
+     * Sets the array.
+     */
+    final void setArray(Object[] a) {
+        array = a;
+    }
+
+    /**
+     * Creates an empty list.
      */
     public CopyOnWriteArrayList() {
-        elements = EmptyArray.OBJECT;
+        setArray(new Object[0]);
     }
 
     /**
-     * Creates a new instance containing the elements of {@code collection}.
+     * Creates a list containing the elements of the specified
+     * collection, in the order they are returned by the collection's
+     * iterator.
+     *
+     * @param c the collection of initially held elements
+     * @throws NullPointerException if the specified collection is null
      */
-    @SuppressWarnings("unchecked")
-    public CopyOnWriteArrayList(Collection<? extends E> collection) {
-        this((E[]) collection.toArray());
+    public CopyOnWriteArrayList(Collection<? extends E> c) {
+        Object[] elements;
+        if (c.getClass() == CopyOnWriteArrayList.class)
+            elements = ((CopyOnWriteArrayList<?>)c).getArray();
+        else {
+            elements = c.toArray();
+            // defend against c.toArray (incorrectly) not returning Object[]
+            // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
+            if (elements.getClass() != Object[].class)
+                elements = Arrays.copyOf(elements, elements.length, Object[].class);
+        }
+        setArray(elements);
     }
 
     /**
-     * Creates a new instance containing the elements of {@code array}.
+     * Creates a list holding a copy of the given array.
+     *
+     * @param toCopyIn the array (a copy of this array is used as the
+     *        internal array)
+     * @throws NullPointerException if the specified array is null
      */
-    public CopyOnWriteArrayList(E[] array) {
-        this.elements = Arrays.copyOf(array, array.length, Object[].class);
+    public CopyOnWriteArrayList(E[] toCopyIn) {
+        setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
     }
 
-    @Override public Object clone() {
+    /**
+     * Returns the number of elements in this list.
+     *
+     * @return the number of elements in this list
+     */
+    public int size() {
+        return getArray().length;
+    }
+
+    /**
+     * Returns {@code true} if this list contains no elements.
+     *
+     * @return {@code true} if this list contains no elements
+     */
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    /**
+     * static version of indexOf, to allow repeated calls without
+     * needing to re-acquire array each time.
+     * @param o element to search for
+     * @param elements the array
+     * @param index first index to search
+     * @param fence one past last index to search
+     * @return index of element, or -1 if absent
+     */
+    private static int indexOf(Object o, Object[] elements,
+                               int index, int fence) {
+        if (o == null) {
+            for (int i = index; i < fence; i++)
+                if (elements[i] == null)
+                    return i;
+        } else {
+            for (int i = index; i < fence; i++)
+                if (o.equals(elements[i]))
+                    return i;
+        }
+        return -1;
+    }
+
+    /**
+     * static version of lastIndexOf.
+     * @param o element to search for
+     * @param elements the array
+     * @param index first index to search
+     * @return index of element, or -1 if absent
+     */
+    private static int lastIndexOf(Object o, Object[] elements, int index) {
+        if (o == null) {
+            for (int i = index; i >= 0; i--)
+                if (elements[i] == null)
+                    return i;
+        } else {
+            for (int i = index; i >= 0; i--)
+                if (o.equals(elements[i]))
+                    return i;
+        }
+        return -1;
+    }
+
+    /**
+     * Returns {@code true} if this list contains the specified element.
+     * More formally, returns {@code true} if and only if this list contains
+     * at least one element {@code e} such that {@code Objects.equals(o, e)}.
+     *
+     * @param o element whose presence in this list is to be tested
+     * @return {@code true} if this list contains the specified element
+     */
+    public boolean contains(Object o) {
+        Object[] elements = getArray();
+        return indexOf(o, elements, 0, elements.length) >= 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int indexOf(Object o) {
+        Object[] elements = getArray();
+        return indexOf(o, elements, 0, elements.length);
+    }
+
+    /**
+     * Returns the index of the first occurrence of the specified element in
+     * this list, searching forwards from {@code index}, or returns -1 if
+     * the element is not found.
+     * More formally, returns the lowest index {@code i} such that
+     * {@code i >= index && Objects.equals(get(i), e)},
+     * or -1 if there is no such index.
+     *
+     * @param e element to search for
+     * @param index index to start searching from
+     * @return the index of the first occurrence of the element in
+     *         this list at position {@code index} or later in the list;
+     *         {@code -1} if the element is not found.
+     * @throws IndexOutOfBoundsException if the specified index is negative
+     */
+    public int indexOf(E e, int index) {
+        Object[] elements = getArray();
+        return indexOf(e, elements, index, elements.length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int lastIndexOf(Object o) {
+        Object[] elements = getArray();
+        return lastIndexOf(o, elements, elements.length - 1);
+    }
+
+    /**
+     * Returns the index of the last occurrence of the specified element in
+     * this list, searching backwards from {@code index}, or returns -1 if
+     * the element is not found.
+     * More formally, returns the highest index {@code i} such that
+     * {@code i <= index && Objects.equals(get(i), e)},
+     * or -1 if there is no such index.
+     *
+     * @param e element to search for
+     * @param index index to start searching backwards from
+     * @return the index of the last occurrence of the element at position
+     *         less than or equal to {@code index} in this list;
+     *         -1 if the element is not found.
+     * @throws IndexOutOfBoundsException if the specified index is greater
+     *         than or equal to the current size of this list
+     */
+    public int lastIndexOf(E e, int index) {
+        Object[] elements = getArray();
+        return lastIndexOf(e, elements, index);
+    }
+
+    /**
+     * Returns a shallow copy of this list.  (The elements themselves
+     * are not copied.)
+     *
+     * @return a clone of this list
+     */
+    public Object clone() {
         try {
-            CopyOnWriteArrayList result = (CopyOnWriteArrayList) super.clone();
-            result.elements = result.elements.clone();
-            return result;
+            @SuppressWarnings("unchecked")
+            CopyOnWriteArrayList<E> clone =
+                (CopyOnWriteArrayList<E>) super.clone();
+            clone.resetLock();
+            return clone;
         } catch (CloneNotSupportedException e) {
-            throw new AssertionError(e);
+            // this shouldn't happen, since we are Cloneable
+            throw new InternalError();
         }
     }
 
-    public int size() {
-        return elements.length;
+    /**
+     * Returns an array containing all of the elements in this list
+     * in proper sequence (from first to last element).
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this list.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all the elements in this list
+     */
+    public Object[] toArray() {
+        Object[] elements = getArray();
+        return Arrays.copyOf(elements, elements.length);
     }
 
+    /**
+     * Returns an array containing all of the elements in this list in
+     * proper sequence (from first to last element); the runtime type of
+     * the returned array is that of the specified array.  If the list fits
+     * in the specified array, it is returned therein.  Otherwise, a new
+     * array is allocated with the runtime type of the specified array and
+     * the size of this list.
+     *
+     * <p>If this list fits in the specified array with room to spare
+     * (i.e., the array has more elements than this list), the element in
+     * the array immediately following the end of the list is set to
+     * {@code null}.  (This is useful in determining the length of this
+     * list <i>only</i> if the caller knows that this list does not contain
+     * any null elements.)
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose {@code x} is a list known to contain only strings.
+     * The following code can be used to dump the list into a newly
+     * allocated array of {@code String}:
+     *
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     *
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
+     *
+     * @param a the array into which the elements of the list are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose.
+     * @return an array containing all the elements in this list
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this list
+     * @throws NullPointerException if the specified array is null
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T[] toArray(T[] a) {
+        Object[] elements = getArray();
+        int len = elements.length;
+        if (a.length < len)
+            return (T[]) Arrays.copyOf(elements, len, a.getClass());
+        else {
+            System.arraycopy(elements, 0, a, 0, len);
+            if (a.length > len)
+                a[len] = null;
+            return a;
+        }
+    }
+
+    // Positional Access Operations
+
     @SuppressWarnings("unchecked")
+    private E get(Object[] a, int index) {
+        return (E) a[index];
+    }
+
+    static String outOfBounds(int index, int size) {
+        return "Index: " + index + ", Size: " + size;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
     public E get(int index) {
-        return (E) elements[index];
+        return get(getArray(), index);
     }
 
-    public boolean contains(Object o) {
-        return indexOf(o) != -1;
-    }
+    /**
+     * Replaces the element at the specified position in this list with the
+     * specified element.
+     *
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    public E set(int index, E element) {
+        synchronized (lock) {
+            Object[] elements = getArray();
+            E oldValue = get(elements, index);
 
-    public boolean containsAll(Collection<?> collection) {
-        Object[] snapshot = elements;
-        return containsAll(collection, snapshot, 0, snapshot.length);
-    }
-
-    static boolean containsAll(Collection<?> collection, Object[] snapshot, int from, int to) {
-        for (Object o : collection) {
-            if (indexOf(o, snapshot, from, to) == -1) {
-                return false;
+            if (oldValue != element) {
+                int len = elements.length;
+                Object[] newElements = Arrays.copyOf(elements, len);
+                newElements[index] = element;
+                setArray(newElements);
+            } else {
+                // Not quite a no-op; ensures volatile write semantics
+                setArray(elements);
             }
+            return oldValue;
+        }
+    }
+
+    /**
+     * Appends the specified element to the end of this list.
+     *
+     * @param e element to be appended to this list
+     * @return {@code true} (as specified by {@link Collection#add})
+     */
+    public boolean add(E e) {
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            Object[] newElements = Arrays.copyOf(elements, len + 1);
+            newElements[len] = e;
+            setArray(newElements);
+            return true;
+        }
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this
+     * list. Shifts the element currently at that position (if any) and
+     * any subsequent elements to the right (adds one to their indices).
+     *
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    public void add(int index, E element) {
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (index > len || index < 0)
+                throw new IndexOutOfBoundsException(outOfBounds(index, len));
+            Object[] newElements;
+            int numMoved = len - index;
+            if (numMoved == 0)
+                newElements = Arrays.copyOf(elements, len + 1);
+            else {
+                newElements = new Object[len + 1];
+                System.arraycopy(elements, 0, newElements, 0, index);
+                System.arraycopy(elements, index, newElements, index + 1,
+                                 numMoved);
+            }
+            newElements[index] = element;
+            setArray(newElements);
+        }
+    }
+
+    /**
+     * Removes the element at the specified position in this list.
+     * Shifts any subsequent elements to the left (subtracts one from their
+     * indices).  Returns the element that was removed from the list.
+     *
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    public E remove(int index) {
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            E oldValue = get(elements, index);
+            int numMoved = len - index - 1;
+            if (numMoved == 0)
+                setArray(Arrays.copyOf(elements, len - 1));
+            else {
+                Object[] newElements = new Object[len - 1];
+                System.arraycopy(elements, 0, newElements, 0, index);
+                System.arraycopy(elements, index + 1, newElements, index,
+                                 numMoved);
+                setArray(newElements);
+            }
+            return oldValue;
+        }
+    }
+
+    /**
+     * Removes the first occurrence of the specified element from this list,
+     * if it is present.  If this list does not contain the element, it is
+     * unchanged.  More formally, removes the element with the lowest index
+     * {@code i} such that {@code Objects.equals(o, get(i))}
+     * (if such an element exists).  Returns {@code true} if this list
+     * contained the specified element (or equivalently, if this list
+     * changed as a result of the call).
+     *
+     * @param o element to be removed from this list, if present
+     * @return {@code true} if this list contained the specified element
+     */
+    public boolean remove(Object o) {
+        Object[] snapshot = getArray();
+        int index = indexOf(o, snapshot, 0, snapshot.length);
+        return (index < 0) ? false : remove(o, snapshot, index);
+    }
+
+    /**
+     * A version of remove(Object) using the strong hint that given
+     * recent snapshot contains o at the given index.
+     */
+    private boolean remove(Object o, Object[] snapshot, int index) {
+        synchronized (lock) {
+            Object[] current = getArray();
+            int len = current.length;
+            if (snapshot != current) findIndex: {
+                int prefix = Math.min(index, len);
+                for (int i = 0; i < prefix; i++) {
+                    if (current[i] != snapshot[i]
+                        && Objects.equals(o, current[i])) {
+                        index = i;
+                        break findIndex;
+                    }
+                }
+                if (index >= len)
+                    return false;
+                if (current[index] == o)
+                    break findIndex;
+                index = indexOf(o, current, index, len);
+                if (index < 0)
+                    return false;
+            }
+            Object[] newElements = new Object[len - 1];
+            System.arraycopy(current, 0, newElements, 0, index);
+            System.arraycopy(current, index + 1,
+                             newElements, index,
+                             len - index - 1);
+            setArray(newElements);
+            return true;
+        }
+    }
+
+    /**
+     * Removes from this list all of the elements whose index is between
+     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
+     * Shifts any succeeding elements to the left (reduces their index).
+     * This call shortens the list by {@code (toIndex - fromIndex)} elements.
+     * (If {@code toIndex==fromIndex}, this operation has no effect.)
+     *
+     * @param fromIndex index of first element to be removed
+     * @param toIndex index after last element to be removed
+     * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
+     *         ({@code fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
+     */
+    void removeRange(int fromIndex, int toIndex) {
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+
+            if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
+                throw new IndexOutOfBoundsException();
+            int newlen = len - (toIndex - fromIndex);
+            int numMoved = len - toIndex;
+            if (numMoved == 0)
+                setArray(Arrays.copyOf(elements, newlen));
+            else {
+                Object[] newElements = new Object[newlen];
+                System.arraycopy(elements, 0, newElements, 0, fromIndex);
+                System.arraycopy(elements, toIndex, newElements,
+                                 fromIndex, numMoved);
+                setArray(newElements);
+            }
+        }
+    }
+
+    /**
+     * Appends the element, if not present.
+     *
+     * @param e element to be added to this list, if absent
+     * @return {@code true} if the element was added
+     */
+    public boolean addIfAbsent(E e) {
+        Object[] snapshot = getArray();
+        return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
+            addIfAbsent(e, snapshot);
+    }
+
+    /**
+     * A version of addIfAbsent using the strong hint that given
+     * recent snapshot does not contain e.
+     */
+    private boolean addIfAbsent(E e, Object[] snapshot) {
+        synchronized (lock) {
+            Object[] current = getArray();
+            int len = current.length;
+            if (snapshot != current) {
+                // Optimize for lost race to another addXXX operation
+                int common = Math.min(snapshot.length, len);
+                for (int i = 0; i < common; i++)
+                    if (current[i] != snapshot[i]
+                        && Objects.equals(e, current[i]))
+                        return false;
+                if (indexOf(e, current, common, len) >= 0)
+                        return false;
+            }
+            Object[] newElements = Arrays.copyOf(current, len + 1);
+            newElements[len] = e;
+            setArray(newElements);
+            return true;
+        }
+    }
+
+    /**
+     * Returns {@code true} if this list contains all of the elements of the
+     * specified collection.
+     *
+     * @param c collection to be checked for containment in this list
+     * @return {@code true} if this list contains all of the elements of the
+     *         specified collection
+     * @throws NullPointerException if the specified collection is null
+     * @see #contains(Object)
+     */
+    public boolean containsAll(Collection<?> c) {
+        Object[] elements = getArray();
+        int len = elements.length;
+        for (Object e : c) {
+            if (indexOf(e, elements, 0, len) < 0)
+                return false;
         }
         return true;
     }
 
     /**
-     * Searches this list for {@code object} and returns the index of the first
-     * occurrence that is at or after {@code from}.
+     * Removes from this list all of its elements that are contained in
+     * the specified collection. This is a particularly expensive operation
+     * in this class because of the need for an internal temporary array.
      *
-     * @return the index or -1 if the object was not found.
+     * @param c collection containing elements to be removed from this list
+     * @return {@code true} if this list changed as a result of the call
+     * @throws ClassCastException if the class of an element of this list
+     *         is incompatible with the specified collection
+     * (<a href="{@docRoot}/../api/java/util/Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if this list contains a null element and the
+     *         specified collection does not permit null elements
+     * (<a href="{@docRoot}/../api/java/util/Collection.html#optional-restrictions">optional</a>),
+     *         or if the specified collection is null
+     * @see #remove(Object)
      */
-    public int indexOf(E object, int from) {
-        Object[] snapshot = elements;
-        return indexOf(object, snapshot, from, snapshot.length);
-    }
-
-    public int indexOf(Object object) {
-        Object[] snapshot = elements;
-        return indexOf(object, snapshot, 0, snapshot.length);
+    public boolean removeAll(Collection<?> c) {
+        if (c == null) throw new NullPointerException();
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (len != 0) {
+                // temp array holds those elements we know we want to keep
+                int newlen = 0;
+                Object[] temp = new Object[len];
+                for (int i = 0; i < len; ++i) {
+                    Object element = elements[i];
+                    if (!c.contains(element))
+                        temp[newlen++] = element;
+                }
+                if (newlen != len) {
+                    setArray(Arrays.copyOf(temp, newlen));
+                    return true;
+                }
+            }
+            return false;
+        }
     }
 
     /**
-     * Searches this list for {@code object} and returns the index of the last
-     * occurrence that is before {@code to}.
+     * Retains only the elements in this list that are contained in the
+     * specified collection.  In other words, removes from this list all of
+     * its elements that are not contained in the specified collection.
      *
-     * @return the index or -1 if the object was not found.
+     * @param c collection containing elements to be retained in this list
+     * @return {@code true} if this list changed as a result of the call
+     * @throws ClassCastException if the class of an element of this list
+     *         is incompatible with the specified collection
+     * (<a href="{@docRoot}/../api/java/util/Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if this list contains a null element and the
+     *         specified collection does not permit null elements
+     * (<a href="{@docRoot}/../api/java/util/Collection.html#optional-restrictions">optional</a>),
+     *         or if the specified collection is null
+     * @see #remove(Object)
      */
-    public int lastIndexOf(E object, int to) {
-        Object[] snapshot = elements;
-        return lastIndexOf(object, snapshot, 0, to);
-    }
-
-    public int lastIndexOf(Object object) {
-        Object[] snapshot = elements;
-        return lastIndexOf(object, snapshot, 0, snapshot.length);
-    }
-
-    public boolean isEmpty() {
-        return elements.length == 0;
+    public boolean retainAll(Collection<?> c) {
+        if (c == null) throw new NullPointerException();
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (len != 0) {
+                // temp array holds those elements we know we want to keep
+                int newlen = 0;
+                Object[] temp = new Object[len];
+                for (int i = 0; i < len; ++i) {
+                    Object element = elements[i];
+                    if (c.contains(element))
+                        temp[newlen++] = element;
+                }
+                if (newlen != len) {
+                    setArray(Arrays.copyOf(temp, newlen));
+                    return true;
+                }
+            }
+            return false;
+        }
     }
 
     /**
-     * Returns an {@link Iterator} that iterates over the elements of this list
-     * as they were at the time of this method call. Changes to the list made
-     * after this method call will not be reflected by the iterator, nor will
-     * they trigger a {@link ConcurrentModificationException}.
+     * Appends all of the elements in the specified collection that
+     * are not already contained in this list, to the end of
+     * this list, in the order that they are returned by the
+     * specified collection's iterator.
      *
-     * <p>The returned iterator does not support {@link Iterator#remove()}.
+     * @param c collection containing elements to be added to this list
+     * @return the number of elements added
+     * @throws NullPointerException if the specified collection is null
+     * @see #addIfAbsent(Object)
+     */
+    public int addAllAbsent(Collection<? extends E> c) {
+        Object[] cs = c.toArray();
+        if (cs.length == 0)
+            return 0;
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            int added = 0;
+            // uniquify and compact elements in cs
+            for (int i = 0; i < cs.length; ++i) {
+                Object e = cs[i];
+                if (indexOf(e, elements, 0, len) < 0 &&
+                    indexOf(e, cs, 0, added) < 0)
+                    cs[added++] = e;
+            }
+            if (added > 0) {
+                Object[] newElements = Arrays.copyOf(elements, len + added);
+                System.arraycopy(cs, 0, newElements, len, added);
+                setArray(newElements);
+            }
+            return added;
+        }
+    }
+
+    /**
+     * Removes all of the elements from this list.
+     * The list will be empty after this call returns.
+     */
+    public void clear() {
+        synchronized (lock) {
+            setArray(new Object[0]);
+        }
+    }
+
+    /**
+     * Appends all of the elements in the specified collection to the end
+     * of this list, in the order that they are returned by the specified
+     * collection's iterator.
+     *
+     * @param c collection containing elements to be added to this list
+     * @return {@code true} if this list changed as a result of the call
+     * @throws NullPointerException if the specified collection is null
+     * @see #add(Object)
+     */
+    public boolean addAll(Collection<? extends E> c) {
+        Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ?
+            ((CopyOnWriteArrayList<?>)c).getArray() : c.toArray();
+        if (cs.length == 0)
+            return false;
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (len == 0 && cs.getClass() == Object[].class)
+                setArray(cs);
+            else {
+                Object[] newElements = Arrays.copyOf(elements, len + cs.length);
+                System.arraycopy(cs, 0, newElements, len, cs.length);
+                setArray(newElements);
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Inserts all of the elements in the specified collection into this
+     * list, starting at the specified position.  Shifts the element
+     * currently at that position (if any) and any subsequent elements to
+     * the right (increases their indices).  The new elements will appear
+     * in this list in the order that they are returned by the
+     * specified collection's iterator.
+     *
+     * @param index index at which to insert the first element
+     *        from the specified collection
+     * @param c collection containing elements to be added to this list
+     * @return {@code true} if this list changed as a result of the call
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     * @throws NullPointerException if the specified collection is null
+     * @see #add(int,Object)
+     */
+    public boolean addAll(int index, Collection<? extends E> c) {
+        Object[] cs = c.toArray();
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (index > len || index < 0)
+                throw new IndexOutOfBoundsException(outOfBounds(index, len));
+            if (cs.length == 0)
+                return false;
+            int numMoved = len - index;
+            Object[] newElements;
+            if (numMoved == 0)
+                newElements = Arrays.copyOf(elements, len + cs.length);
+            else {
+                newElements = new Object[len + cs.length];
+                System.arraycopy(elements, 0, newElements, 0, index);
+                System.arraycopy(elements, index,
+                                 newElements, index + cs.length,
+                                 numMoved);
+            }
+            System.arraycopy(cs, 0, newElements, index, cs.length);
+            setArray(newElements);
+            return true;
+        }
+    }
+
+    public void forEach(Consumer<? super E> action) {
+        if (action == null) throw new NullPointerException();
+        for (Object x : getArray()) {
+            @SuppressWarnings("unchecked") E e = (E) x;
+            action.accept(e);
+        }
+    }
+
+    public boolean removeIf(Predicate<? super E> filter) {
+        if (filter == null) throw new NullPointerException();
+        synchronized (lock) {
+            final Object[] elements = getArray();
+            final int len = elements.length;
+            int i;
+            for (i = 0; i < len; i++) {
+                @SuppressWarnings("unchecked") E e = (E) elements[i];
+                if (filter.test(e)) {
+                    int newlen = i;
+                    final Object[] newElements = new Object[len - 1];
+                    System.arraycopy(elements, 0, newElements, 0, newlen);
+                    for (i++; i < len; i++) {
+                        @SuppressWarnings("unchecked") E x = (E) elements[i];
+                        if (!filter.test(x))
+                            newElements[newlen++] = x;
+                    }
+                    setArray((newlen == len - 1)
+                             ? newElements // one match => one copy
+                             : Arrays.copyOf(newElements, newlen));
+                    return true;
+                }
+            }
+            return false;       // zero matches => zero copies
+        }
+    }
+
+    public void replaceAll(UnaryOperator<E> operator) {
+        if (operator == null) throw new NullPointerException();
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            Object[] newElements = Arrays.copyOf(elements, len);
+            for (int i = 0; i < len; ++i) {
+                @SuppressWarnings("unchecked") E e = (E) elements[i];
+                newElements[i] = operator.apply(e);
+            }
+            setArray(newElements);
+        }
+    }
+
+    public void sort(Comparator<? super E> c) {
+        synchronized (lock) {
+            Object[] elements = getArray();
+            Object[] newElements = Arrays.copyOf(elements, elements.length);
+            @SuppressWarnings("unchecked") E[] es = (E[])newElements;
+            Arrays.sort(es, c);
+            setArray(newElements);
+        }
+    }
+
+    /**
+     * Saves this list to a stream (that is, serializes it).
+     *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
+     * @serialData The length of the array backing the list is emitted
+     *               (int), followed by all of its elements (each an Object)
+     *               in the proper order.
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+
+        s.defaultWriteObject();
+
+        Object[] elements = getArray();
+        // Write out array length
+        s.writeInt(elements.length);
+
+        // Write out all elements in the proper order.
+        for (Object element : elements)
+            s.writeObject(element);
+    }
+
+    /**
+     * Reconstitutes this list from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+
+        s.defaultReadObject();
+
+        // bind to new lock
+        resetLock();
+
+        // Read in array length and allocate array
+        int len = s.readInt();
+        Object[] elements = new Object[len];
+
+        // Read in all elements in the proper order.
+        for (int i = 0; i < len; i++)
+            elements[i] = s.readObject();
+        setArray(elements);
+    }
+
+    /**
+     * Returns a string representation of this list.  The string
+     * representation consists of the string representations of the list's
+     * elements in the order they are returned by its iterator, enclosed in
+     * square brackets ({@code "[]"}).  Adjacent elements are separated by
+     * the characters {@code ", "} (comma and space).  Elements are
+     * converted to strings as by {@link String#valueOf(Object)}.
+     *
+     * @return a string representation of this list
+     */
+    public String toString() {
+        return Arrays.toString(getArray());
+    }
+
+    /**
+     * Compares the specified object with this list for equality.
+     * Returns {@code true} if the specified object is the same object
+     * as this object, or if it is also a {@link List} and the sequence
+     * of elements returned by an {@linkplain List#iterator() iterator}
+     * over the specified list is the same as the sequence returned by
+     * an iterator over this list.  The two sequences are considered to
+     * be the same if they have the same length and corresponding
+     * elements at the same position in the sequence are <em>equal</em>.
+     * Two elements {@code e1} and {@code e2} are considered
+     * <em>equal</em> if {@code Objects.equals(e1, e2)}.
+     *
+     * @param o the object to be compared for equality with this list
+     * @return {@code true} if the specified object is equal to this list
+     */
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (!(o instanceof List))
+            return false;
+
+        List<?> list = (List<?>)o;
+        Iterator<?> it = list.iterator();
+        Object[] elements = getArray();
+        for (int i = 0, len = elements.length; i < len; i++)
+            if (!it.hasNext() || !Objects.equals(elements[i], it.next()))
+                return false;
+        if (it.hasNext())
+            return false;
+        return true;
+    }
+
+    /**
+     * Returns the hash code value for this list.
+     *
+     * <p>This implementation uses the definition in {@link List#hashCode}.
+     *
+     * @return the hash code value for this list
+     */
+    public int hashCode() {
+        int hashCode = 1;
+        for (Object x : getArray())
+            hashCode = 31 * hashCode + (x == null ? 0 : x.hashCode());
+        return hashCode;
+    }
+
+    /**
+     * Returns an iterator over the elements in this list in proper sequence.
+     *
+     * <p>The returned iterator provides a snapshot of the state of the list
+     * when the iterator was constructed. No synchronization is needed while
+     * traversing the iterator. The iterator does <em>NOT</em> support the
+     * {@code remove} method.
+     *
+     * @return an iterator over the elements in this list in proper sequence
      */
     public Iterator<E> iterator() {
-        Object[] snapshot = elements;
-        return new CowIterator<E>(snapshot, 0, snapshot.length);
+        return new COWIterator<E>(getArray(), 0);
     }
 
     /**
-     * Returns a {@link ListIterator} that iterates over the elements of this
-     * list as they were at the time of this method call. Changes to the list
-     * made after this method call will not be reflected by the iterator, nor
-     * will they trigger a {@link ConcurrentModificationException}.
+     * {@inheritDoc}
      *
-     * <p>The returned iterator does not support {@link ListIterator#add},
-     * {@link ListIterator#set} or {@link Iterator#remove()},
-     */
-    public ListIterator<E> listIterator(int index) {
-        Object[] snapshot = elements;
-        if (index < 0 || index > snapshot.length) {
-            throw new IndexOutOfBoundsException("index=" + index + ", length=" + snapshot.length);
-        }
-        CowIterator<E> result = new CowIterator<E>(snapshot, 0, snapshot.length);
-        result.index = index;
-        return result;
-    }
-
-    /**
-     * Equivalent to {@code listIterator(0)}.
+     * <p>The returned iterator provides a snapshot of the state of the list
+     * when the iterator was constructed. No synchronization is needed while
+     * traversing the iterator. The iterator does <em>NOT</em> support the
+     * {@code remove}, {@code set} or {@code add} methods.
      */
     public ListIterator<E> listIterator() {
-        Object[] snapshot = elements;
-        return new CowIterator<E>(snapshot, 0, snapshot.length);
-    }
-
-    public List<E> subList(int from, int to) {
-        Object[] snapshot = elements;
-        if (from < 0 || from > to || to > snapshot.length) {
-            throw new IndexOutOfBoundsException("from=" + from + ", to=" + to +
-                    ", list size=" + snapshot.length);
-        }
-        return new CowSubList(snapshot, from, to);
-    }
-
-    public Object[] toArray() {
-        return elements.clone();
-    }
-
-    @SuppressWarnings({"unchecked","SuspiciousSystemArraycopy"})
-    public <T> T[] toArray(T[] contents) {
-        Object[] snapshot = elements;
-        if (snapshot.length > contents.length) {
-            return (T[]) Arrays.copyOf(snapshot, snapshot.length, contents.getClass());
-        }
-        System.arraycopy(snapshot, 0, contents, 0, snapshot.length);
-        if (snapshot.length < contents.length) {
-            contents[snapshot.length] = null;
-        }
-        return contents;
-    }
-
-    @Override public boolean equals(Object other) {
-        if (other instanceof CopyOnWriteArrayList) {
-            return this == other
-                    || Arrays.equals(elements, ((CopyOnWriteArrayList<?>) other).elements);
-        } else if (other instanceof List) {
-            Object[] snapshot = elements;
-            Iterator<?> i = ((List<?>) other).iterator();
-            for (Object o : snapshot) {
-                if (!i.hasNext() || !Objects.equal(o, i.next())) {
-                    return false;
-                }
-            }
-            return !i.hasNext();
-        } else {
-            return false;
-        }
-    }
-
-    @Override public int hashCode() {
-        return Arrays.hashCode(elements);
-    }
-
-    @Override public String toString() {
-        return Arrays.toString(elements);
-    }
-
-    public synchronized boolean add(E e) {
-        Object[] newElements = new Object[elements.length + 1];
-        System.arraycopy(elements, 0, newElements, 0, elements.length);
-        newElements[elements.length] = e;
-        elements = newElements;
-        return true;
-    }
-
-    public synchronized void add(int index, E e) {
-        Object[] newElements = new Object[elements.length + 1];
-        System.arraycopy(elements, 0, newElements, 0, index);
-        newElements[index] = e;
-        System.arraycopy(elements, index, newElements, index + 1, elements.length - index);
-        elements = newElements;
-    }
-
-    public synchronized boolean addAll(Collection<? extends E> collection) {
-        return addAll(elements.length, collection);
-    }
-
-    public synchronized boolean addAll(int index, Collection<? extends E> collection) {
-        Object[] toAdd = collection.toArray();
-        Object[] newElements = new Object[elements.length + toAdd.length];
-        System.arraycopy(elements, 0, newElements, 0, index);
-        System.arraycopy(toAdd, 0, newElements, index, toAdd.length);
-        System.arraycopy(elements, index,
-                newElements, index + toAdd.length, elements.length - index);
-        elements = newElements;
-        return toAdd.length > 0;
+        return new COWIterator<E>(getArray(), 0);
     }
 
     /**
-     * Adds the elements of {@code collection} that are not already present in
-     * this list. If {@code collection} includes a repeated value, at most one
-     * occurrence of that value will be added to this list. Elements are added
-     * at the end of this list.
+     * {@inheritDoc}
      *
-     * <p>Callers of this method may prefer {@link CopyOnWriteArraySet}, whose
-     * API is more appropriate for set operations.
-     */
-    public synchronized int addAllAbsent(Collection<? extends E> collection) {
-        Object[] toAdd = collection.toArray();
-        Object[] newElements = new Object[elements.length + toAdd.length];
-        System.arraycopy(elements, 0, newElements, 0, elements.length);
-        int addedCount = 0;
-        for (Object o : toAdd) {
-            if (indexOf(o, newElements, 0, elements.length + addedCount) == -1) {
-                newElements[elements.length + addedCount++] = o;
-            }
-        }
-        if (addedCount < toAdd.length) {
-            newElements = Arrays.copyOfRange(
-                    newElements, 0, elements.length + addedCount); // trim to size
-        }
-        elements = newElements;
-        return addedCount;
-    }
-
-    /**
-     * Adds {@code object} to the end of this list if it is not already present.
+     * <p>The returned iterator provides a snapshot of the state of the list
+     * when the iterator was constructed. No synchronization is needed while
+     * traversing the iterator. The iterator does <em>NOT</em> support the
+     * {@code remove}, {@code set} or {@code add} methods.
      *
-     * <p>Callers of this method may prefer {@link CopyOnWriteArraySet}, whose
-     * API is more appropriate for set operations.
+     * @throws IndexOutOfBoundsException {@inheritDoc}
      */
-    public synchronized boolean addIfAbsent(E object) {
-        if (contains(object)) {
-            return false;
-        }
-        add(object);
-        return true;
-    }
+    public ListIterator<E> listIterator(int index) {
+        Object[] elements = getArray();
+        int len = elements.length;
+        if (index < 0 || index > len)
+            throw new IndexOutOfBoundsException(outOfBounds(index, len));
 
-    @Override public synchronized void clear() {
-        elements = EmptyArray.OBJECT;
-    }
-
-    public synchronized E remove(int index) {
-        @SuppressWarnings("unchecked")
-        E removed = (E) elements[index];
-        removeRange(index, index + 1);
-        return removed;
-    }
-
-    public synchronized boolean remove(Object o) {
-        int index = indexOf(o);
-        if (index == -1) {
-            return false;
-        }
-        remove(index);
-        return true;
-    }
-
-    public synchronized boolean removeAll(Collection<?> collection) {
-        return removeOrRetain(collection, false, 0, elements.length) != 0;
-    }
-
-    public synchronized boolean retainAll(Collection<?> collection) {
-        return removeOrRetain(collection, true, 0, elements.length) != 0;
+        return new COWIterator<E>(elements, index);
     }
 
     /**
-     * Removes or retains the elements in {@code collection}. Returns the number
-     * of elements removed.
-     */
-    private int removeOrRetain(Collection<?> collection, boolean retain, int from, int to) {
-        for (int i = from; i < to; i++) {
-            if (collection.contains(elements[i]) == retain) {
-                continue;
-            }
-
-            /*
-             * We've encountered an element that must be removed! Create a new
-             * array and copy in the surviving elements one by one.
-             */
-            Object[] newElements = new Object[elements.length - 1];
-            System.arraycopy(elements, 0, newElements, 0, i);
-            int newSize = i;
-            for (int j = i + 1; j < to; j++) {
-                if (collection.contains(elements[j]) == retain) {
-                    newElements[newSize++] = elements[j];
-                }
-            }
-
-            /*
-             * Copy the elements after 'to'. This is only useful for sub lists,
-             * where 'to' will be less than elements.length.
-             */
-            System.arraycopy(elements, to, newElements, newSize, elements.length - to);
-            newSize += (elements.length - to);
-
-            if (newSize < newElements.length) {
-                newElements = Arrays.copyOfRange(newElements, 0, newSize); // trim to size
-            }
-            int removed = elements.length - newElements.length;
-            elements = newElements;
-            return removed;
-        }
-
-        // we made it all the way through the loop without making any changes
-        return 0;
-    }
-
-    public synchronized E set(int index, E e) {
-        Object[] newElements = elements.clone();
-        @SuppressWarnings("unchecked")
-        E result = (E) newElements[index];
-        newElements[index] = e;
-        elements = newElements;
-        return result;
-    }
-
-    private void removeRange(int from, int to) {
-        Object[] newElements = new Object[elements.length - (to - from)];
-        System.arraycopy(elements, 0, newElements, 0, from);
-        System.arraycopy(elements, to, newElements, from, elements.length - to);
-        elements = newElements;
-    }
-
-    static int lastIndexOf(Object o, Object[] data, int from, int to) {
-        if (o == null) {
-            for (int i = to - 1; i >= from; i--) {
-                if (data[i] == null) {
-                    return i;
-                }
-            }
-        } else {
-            for (int i = to - 1; i >= from; i--) {
-                if (o.equals(data[i])) {
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-    static int indexOf(Object o, Object[] data, int from, int to) {
-        if (o == null) {
-            for (int i = from; i < to; i++) {
-                if (data[i] == null) {
-                    return i;
-                }
-            }
-        } else {
-            for (int i = from; i < to; i++) {
-                if (o.equals(data[i])) {
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-    final Object[] getArray() {
-        // CopyOnWriteArraySet needs this.
-        return elements;
-    }
-
-    /**
-     * The sub list is thread safe and supports non-blocking reads. Doing so is
-     * more difficult than in the full list, because each read needs to examine
-     * four fields worth of state:
-     *  - the elements array of the full list
-     *  - two integers for the bounds of this sub list
-     *  - the expected elements array (to detect concurrent modification)
+     * Returns a {@link Spliterator} over the elements in this list.
      *
-     * This is accomplished by aggregating the sub list's three fields into a
-     * single snapshot object representing the current slice. This permits reads
-     * to be internally consistent without synchronization. This takes advantage
-     * of Java's concurrency semantics for final fields.
+     * <p>The {@code Spliterator} reports {@link Spliterator#IMMUTABLE},
+     * {@link Spliterator#ORDERED}, {@link Spliterator#SIZED}, and
+     * {@link Spliterator#SUBSIZED}.
+     *
+     * <p>The spliterator provides a snapshot of the state of the list
+     * when the spliterator was constructed. No synchronization is needed while
+     * operating on the spliterator.
+     *
+     * @return a {@code Spliterator} over the elements in this list
+     * @since 1.8
      */
-    class CowSubList extends AbstractList<E> {
-
-        /*
-         * An immutable snapshot of a sub list's state. By gathering all three
-         * of the sub list's fields in an immutable object,
-         */
-        private volatile Slice slice;
-
-        public CowSubList(Object[] expectedElements, int from, int to) {
-            this.slice = new Slice(expectedElements, from, to);
-        }
-
-        @Override public int size() {
-            Slice slice = this.slice;
-            return slice.to - slice.from;
-        }
-
-        @Override public boolean isEmpty() {
-            Slice slice = this.slice;
-            return slice.from == slice.to;
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override public E get(int index) {
-            Slice slice = this.slice;
-            Object[] snapshot = elements;
-            slice.checkElementIndex(index);
-            slice.checkConcurrentModification(snapshot);
-            return (E) snapshot[index + slice.from];
-        }
-
-        @Override public Iterator<E> iterator() {
-            return listIterator(0);
-        }
-
-        @Override public ListIterator<E> listIterator() {
-            return listIterator(0);
-        }
-
-        @Override public ListIterator<E> listIterator(int index) {
-            Slice slice = this.slice;
-            Object[] snapshot = elements;
-            slice.checkPositionIndex(index);
-            slice.checkConcurrentModification(snapshot);
-            CowIterator<E> result = new CowIterator<E>(snapshot, slice.from, slice.to);
-            result.index = slice.from + index;
-            return result;
-        }
-
-        @Override public int indexOf(Object object) {
-            Slice slice = this.slice;
-            Object[] snapshot = elements;
-            slice.checkConcurrentModification(snapshot);
-            int result = CopyOnWriteArrayList.indexOf(object, snapshot, slice.from, slice.to);
-            return (result != -1) ? (result - slice.from) : -1;
-        }
-
-        @Override public int lastIndexOf(Object object) {
-            Slice slice = this.slice;
-            Object[] snapshot = elements;
-            slice.checkConcurrentModification(snapshot);
-            int result = CopyOnWriteArrayList.lastIndexOf(object, snapshot, slice.from, slice.to);
-            return (result != -1) ? (result - slice.from) : -1;
-        }
-
-        @Override public boolean contains(Object object) {
-            return indexOf(object) != -1;
-        }
-
-        @Override public boolean containsAll(Collection<?> collection) {
-            Slice slice = this.slice;
-            Object[] snapshot = elements;
-            slice.checkConcurrentModification(snapshot);
-            return CopyOnWriteArrayList.containsAll(collection, snapshot, slice.from, slice.to);
-        }
-
-        @Override public List<E> subList(int from, int to) {
-            Slice slice = this.slice;
-            if (from < 0 || from > to || to > size()) {
-                throw new IndexOutOfBoundsException("from=" + from + ", to=" + to +
-                        ", list size=" + size());
-            }
-            return new CowSubList(slice.expectedElements, slice.from + from, slice.from + to);
-        }
-
-        @Override public E remove(int index) {
-            synchronized (CopyOnWriteArrayList.this) {
-                slice.checkElementIndex(index);
-                slice.checkConcurrentModification(elements);
-                E removed = CopyOnWriteArrayList.this.remove(slice.from + index);
-                slice = new Slice(elements, slice.from, slice.to - 1);
-                return removed;
-            }
-        }
-
-        @Override public void clear() {
-            synchronized (CopyOnWriteArrayList.this) {
-                slice.checkConcurrentModification(elements);
-                CopyOnWriteArrayList.this.removeRange(slice.from, slice.to);
-                slice = new Slice(elements, slice.from, slice.from);
-            }
-        }
-
-        @Override public void add(int index, E object) {
-            synchronized (CopyOnWriteArrayList.this) {
-                slice.checkPositionIndex(index);
-                slice.checkConcurrentModification(elements);
-                CopyOnWriteArrayList.this.add(index + slice.from, object);
-                slice = new Slice(elements, slice.from, slice.to + 1);
-            }
-        }
-
-        @Override public boolean add(E object) {
-            synchronized (CopyOnWriteArrayList.this) {
-                add(slice.to - slice.from, object);
-                return true;
-            }
-        }
-
-        @Override public boolean addAll(int index, Collection<? extends E> collection) {
-            synchronized (CopyOnWriteArrayList.this) {
-                slice.checkPositionIndex(index);
-                slice.checkConcurrentModification(elements);
-                int oldSize = elements.length;
-                boolean result = CopyOnWriteArrayList.this.addAll(index + slice.from, collection);
-                slice = new Slice(elements, slice.from, slice.to + (elements.length - oldSize));
-                return result;
-            }
-        }
-
-        @Override public boolean addAll(Collection<? extends E> collection) {
-            synchronized (CopyOnWriteArrayList.this) {
-                return addAll(size(), collection);
-            }
-        }
-
-        @Override public E set(int index, E object) {
-            synchronized (CopyOnWriteArrayList.this) {
-                slice.checkElementIndex(index);
-                slice.checkConcurrentModification(elements);
-                E result = CopyOnWriteArrayList.this.set(index + slice.from, object);
-                slice = new Slice(elements, slice.from, slice.to);
-                return result;
-            }
-        }
-
-        @Override public boolean remove(Object object) {
-            synchronized (CopyOnWriteArrayList.this) {
-                int index = indexOf(object);
-                if (index == -1) {
-                    return false;
-                }
-                remove(index);
-                return true;
-            }
-        }
-
-        @Override public boolean removeAll(Collection<?> collection) {
-            synchronized (CopyOnWriteArrayList.this) {
-                slice.checkConcurrentModification(elements);
-                int removed = removeOrRetain(collection, false, slice.from, slice.to);
-                slice = new Slice(elements, slice.from, slice.to - removed);
-                return removed != 0;
-            }
-        }
-
-        @Override public boolean retainAll(Collection<?> collection) {
-            synchronized (CopyOnWriteArrayList.this) {
-                slice.checkConcurrentModification(elements);
-                int removed = removeOrRetain(collection, true, slice.from, slice.to);
-                slice = new Slice(elements, slice.from, slice.to - removed);
-                return removed != 0;
-            }
-        }
+    public Spliterator<E> spliterator() {
+        return Spliterators.spliterator
+            (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED);
     }
 
-    static class Slice {
-        private final Object[] expectedElements;
-        private final int from;
-        private final int to;
-
-        Slice(Object[] expectedElements, int from, int to) {
-            this.expectedElements = expectedElements;
-            this.from = from;
-            this.to = to;
-        }
-
-        /**
-         * Throws if {@code index} doesn't identify an element in the array.
-         */
-        void checkElementIndex(int index) {
-            if (index < 0 || index >= to - from) {
-                throw new IndexOutOfBoundsException("index=" + index + ", size=" + (to - from));
-            }
-        }
-
-        /**
-         * Throws if {@code index} doesn't identify an insertion point in the
-         * array. Unlike element index, it's okay to add or iterate at size().
-         */
-        void checkPositionIndex(int index) {
-            if (index < 0 || index > to - from) {
-                throw new IndexOutOfBoundsException("index=" + index + ", size=" + (to - from));
-            }
-        }
-
-        void checkConcurrentModification(Object[] snapshot) {
-            if (expectedElements != snapshot) {
-                throw new ConcurrentModificationException();
-            }
-        }
-    }
-
-    /**
-     * Iterates an immutable snapshot of the list.
-     */
-    static class CowIterator<E> implements ListIterator<E> {
+    static final class COWIterator<E> implements ListIterator<E> {
+        /** Snapshot of the array */
         private final Object[] snapshot;
-        private final int from;
-        private final int to;
-        private int index = 0;
+        /** Index of element to be returned by subsequent call to next.  */
+        private int cursor;
 
-        CowIterator(Object[] snapshot, int from, int to) {
-            this.snapshot = snapshot;
-            this.from = from;
-            this.to = to;
-            this.index = from;
-        }
-
-        public void add(E object) {
-            throw new UnsupportedOperationException();
+        COWIterator(Object[] elements, int initialCursor) {
+            cursor = initialCursor;
+            snapshot = elements;
         }
 
         public boolean hasNext() {
-            return index < to;
+            return cursor < snapshot.length;
         }
 
         public boolean hasPrevious() {
-            return index > from;
+            return cursor > 0;
         }
 
         @SuppressWarnings("unchecked")
         public E next() {
-            if (index < to) {
-                return (E) snapshot[index++];
-            } else {
+            if (! hasNext())
                 throw new NoSuchElementException();
-            }
-        }
-
-        public int nextIndex() {
-            return index;
+            return (E) snapshot[cursor++];
         }
 
         @SuppressWarnings("unchecked")
         public E previous() {
-            if (index > from) {
-                return (E) snapshot[--index];
-            } else {
+            if (! hasPrevious())
                 throw new NoSuchElementException();
-            }
+            return (E) snapshot[--cursor];
+        }
+
+        public int nextIndex() {
+            return cursor;
         }
 
         public int previousIndex() {
-            return index - 1;
+            return cursor-1;
+        }
+
+        /**
+         * Not supported. Always throws UnsupportedOperationException.
+         * @throws UnsupportedOperationException always; {@code remove}
+         *         is not supported by this iterator.
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Not supported. Always throws UnsupportedOperationException.
+         * @throws UnsupportedOperationException always; {@code set}
+         *         is not supported by this iterator.
+         */
+        public void set(E e) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Not supported. Always throws UnsupportedOperationException.
+         * @throws UnsupportedOperationException always; {@code add}
+         *         is not supported by this iterator.
+         */
+        public void add(E e) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+            final int size = snapshot.length;
+            for (int i = cursor; i < size; i++) {
+                action.accept((E) snapshot[i]);
+            }
+            cursor = size;
+        }
+    }
+
+    /**
+     * Returns a view of the portion of this list between
+     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
+     * The returned list is backed by this list, so changes in the
+     * returned list are reflected in this list.
+     *
+     * <p>The semantics of the list returned by this method become
+     * undefined if the backing list (i.e., this list) is modified in
+     * any way other than via the returned list.
+     *
+     * @param fromIndex low endpoint (inclusive) of the subList
+     * @param toIndex high endpoint (exclusive) of the subList
+     * @return a view of the specified range within this list
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    public List<E> subList(int fromIndex, int toIndex) {
+        synchronized (lock) {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
+                throw new IndexOutOfBoundsException();
+            return new COWSubList<E>(this, fromIndex, toIndex);
+        }
+    }
+
+    /**
+     * Sublist for CopyOnWriteArrayList.
+     * This class extends AbstractList merely for convenience, to
+     * avoid having to define addAll, etc. This doesn't hurt, but
+     * is wasteful.  This class does not need or use modCount
+     * mechanics in AbstractList, but does need to check for
+     * concurrent modification using similar mechanics.  On each
+     * operation, the array that we expect the backing list to use
+     * is checked and updated.  Since we do this for all of the
+     * base operations invoked by those defined in AbstractList,
+     * all is well.  While inefficient, this is not worth
+     * improving.  The kinds of list operations inherited from
+     * AbstractList are already so slow on COW sublists that
+     * adding a bit more space/time doesn't seem even noticeable.
+     */
+    private static class COWSubList<E>
+        extends AbstractList<E>
+        implements RandomAccess
+    {
+        private final CopyOnWriteArrayList<E> l;
+        private final int offset;
+        private int size;
+        private Object[] expectedArray;
+
+        // only call this holding l's lock
+        COWSubList(CopyOnWriteArrayList<E> list,
+                   int fromIndex, int toIndex) {
+            // assert Thread.holdsLock(list.lock);
+            l = list;
+            expectedArray = l.getArray();
+            offset = fromIndex;
+            size = toIndex - fromIndex;
+        }
+
+        // only call this holding l's lock
+        private void checkForComodification() {
+            // assert Thread.holdsLock(l.lock);
+            if (l.getArray() != expectedArray)
+                throw new ConcurrentModificationException();
+        }
+
+        // only call this holding l's lock
+        private void rangeCheck(int index) {
+            // assert Thread.holdsLock(l.lock);
+            if (index < 0 || index >= size)
+                throw new IndexOutOfBoundsException(outOfBounds(index, size));
+        }
+
+        public E set(int index, E element) {
+            synchronized (l.lock) {
+                rangeCheck(index);
+                checkForComodification();
+                E x = l.set(index+offset, element);
+                expectedArray = l.getArray();
+                return x;
+            }
+        }
+
+        public E get(int index) {
+            synchronized (l.lock) {
+                rangeCheck(index);
+                checkForComodification();
+                return l.get(index+offset);
+            }
+        }
+
+        public int size() {
+            synchronized (l.lock) {
+                checkForComodification();
+                return size;
+            }
+        }
+
+        public void add(int index, E element) {
+            synchronized (l.lock) {
+                checkForComodification();
+                if (index < 0 || index > size)
+                    throw new IndexOutOfBoundsException
+                        (outOfBounds(index, size));
+                l.add(index+offset, element);
+                expectedArray = l.getArray();
+                size++;
+            }
+        }
+
+        public void clear() {
+            synchronized (l.lock) {
+                checkForComodification();
+                l.removeRange(offset, offset+size);
+                expectedArray = l.getArray();
+                size = 0;
+            }
+        }
+
+        public E remove(int index) {
+            synchronized (l.lock) {
+                rangeCheck(index);
+                checkForComodification();
+                E result = l.remove(index+offset);
+                expectedArray = l.getArray();
+                size--;
+                return result;
+            }
+        }
+
+        public boolean remove(Object o) {
+            int index = indexOf(o);
+            if (index == -1)
+                return false;
+            remove(index);
+            return true;
+        }
+
+        public Iterator<E> iterator() {
+            synchronized (l.lock) {
+                checkForComodification();
+                return new COWSubListIterator<E>(l, 0, offset, size);
+            }
+        }
+
+        public ListIterator<E> listIterator(int index) {
+            synchronized (l.lock) {
+                checkForComodification();
+                if (index < 0 || index > size)
+                    throw new IndexOutOfBoundsException
+                        (outOfBounds(index, size));
+                return new COWSubListIterator<E>(l, index, offset, size);
+            }
+        }
+
+        public List<E> subList(int fromIndex, int toIndex) {
+            synchronized (l.lock) {
+                checkForComodification();
+                if (fromIndex < 0 || toIndex > size || fromIndex > toIndex)
+                    throw new IndexOutOfBoundsException();
+                return new COWSubList<E>(l, fromIndex + offset,
+                                         toIndex + offset);
+            }
+        }
+
+        public void forEach(Consumer<? super E> action) {
+            if (action == null) throw new NullPointerException();
+            int lo = offset;
+            int hi = offset + size;
+            Object[] a = expectedArray;
+            if (l.getArray() != a)
+                throw new ConcurrentModificationException();
+            if (lo < 0 || hi > a.length)
+                throw new IndexOutOfBoundsException();
+            for (int i = lo; i < hi; ++i) {
+                @SuppressWarnings("unchecked") E e = (E) a[i];
+                action.accept(e);
+            }
+        }
+
+        public void replaceAll(UnaryOperator<E> operator) {
+            if (operator == null) throw new NullPointerException();
+            synchronized (l.lock) {
+                int lo = offset;
+                int hi = offset + size;
+                Object[] elements = expectedArray;
+                if (l.getArray() != elements)
+                    throw new ConcurrentModificationException();
+                int len = elements.length;
+                if (lo < 0 || hi > len)
+                    throw new IndexOutOfBoundsException();
+                Object[] newElements = Arrays.copyOf(elements, len);
+                for (int i = lo; i < hi; ++i) {
+                    @SuppressWarnings("unchecked") E e = (E) elements[i];
+                    newElements[i] = operator.apply(e);
+                }
+                l.setArray(expectedArray = newElements);
+            }
+        }
+
+        public void sort(Comparator<? super E> c) {
+            synchronized (l.lock) {
+                int lo = offset;
+                int hi = offset + size;
+                Object[] elements = expectedArray;
+                if (l.getArray() != elements)
+                    throw new ConcurrentModificationException();
+                int len = elements.length;
+                if (lo < 0 || hi > len)
+                    throw new IndexOutOfBoundsException();
+                Object[] newElements = Arrays.copyOf(elements, len);
+                @SuppressWarnings("unchecked") E[] es = (E[])newElements;
+                Arrays.sort(es, lo, hi, c);
+                l.setArray(expectedArray = newElements);
+            }
+        }
+
+        public boolean removeAll(Collection<?> c) {
+            if (c == null) throw new NullPointerException();
+            boolean removed = false;
+            synchronized (l.lock) {
+                int n = size;
+                if (n > 0) {
+                    int lo = offset;
+                    int hi = offset + n;
+                    Object[] elements = expectedArray;
+                    if (l.getArray() != elements)
+                        throw new ConcurrentModificationException();
+                    int len = elements.length;
+                    if (lo < 0 || hi > len)
+                        throw new IndexOutOfBoundsException();
+                    int newSize = 0;
+                    Object[] temp = new Object[n];
+                    for (int i = lo; i < hi; ++i) {
+                        Object element = elements[i];
+                        if (!c.contains(element))
+                            temp[newSize++] = element;
+                    }
+                    if (newSize != n) {
+                        Object[] newElements = new Object[len - n + newSize];
+                        System.arraycopy(elements, 0, newElements, 0, lo);
+                        System.arraycopy(temp, 0, newElements, lo, newSize);
+                        System.arraycopy(elements, hi, newElements,
+                                         lo + newSize, len - hi);
+                        size = newSize;
+                        removed = true;
+                        l.setArray(expectedArray = newElements);
+                    }
+                }
+            }
+            return removed;
+        }
+
+        public boolean retainAll(Collection<?> c) {
+            if (c == null) throw new NullPointerException();
+            boolean removed = false;
+            synchronized (l.lock) {
+                int n = size;
+                if (n > 0) {
+                    int lo = offset;
+                    int hi = offset + n;
+                    Object[] elements = expectedArray;
+                    if (l.getArray() != elements)
+                        throw new ConcurrentModificationException();
+                    int len = elements.length;
+                    if (lo < 0 || hi > len)
+                        throw new IndexOutOfBoundsException();
+                    int newSize = 0;
+                    Object[] temp = new Object[n];
+                    for (int i = lo; i < hi; ++i) {
+                        Object element = elements[i];
+                        if (c.contains(element))
+                            temp[newSize++] = element;
+                    }
+                    if (newSize != n) {
+                        Object[] newElements = new Object[len - n + newSize];
+                        System.arraycopy(elements, 0, newElements, 0, lo);
+                        System.arraycopy(temp, 0, newElements, lo, newSize);
+                        System.arraycopy(elements, hi, newElements,
+                                         lo + newSize, len - hi);
+                        size = newSize;
+                        removed = true;
+                        l.setArray(expectedArray = newElements);
+                    }
+                }
+            }
+            return removed;
+        }
+
+        public boolean removeIf(Predicate<? super E> filter) {
+            if (filter == null) throw new NullPointerException();
+            boolean removed = false;
+            synchronized (l.lock) {
+                int n = size;
+                if (n > 0) {
+                    int lo = offset;
+                    int hi = offset + n;
+                    Object[] elements = expectedArray;
+                    if (l.getArray() != elements)
+                        throw new ConcurrentModificationException();
+                    int len = elements.length;
+                    if (lo < 0 || hi > len)
+                        throw new IndexOutOfBoundsException();
+                    int newSize = 0;
+                    Object[] temp = new Object[n];
+                    for (int i = lo; i < hi; ++i) {
+                        @SuppressWarnings("unchecked") E e = (E) elements[i];
+                        if (!filter.test(e))
+                            temp[newSize++] = e;
+                    }
+                    if (newSize != n) {
+                        Object[] newElements = new Object[len - n + newSize];
+                        System.arraycopy(elements, 0, newElements, 0, lo);
+                        System.arraycopy(temp, 0, newElements, lo, newSize);
+                        System.arraycopy(elements, hi, newElements,
+                                         lo + newSize, len - hi);
+                        size = newSize;
+                        removed = true;
+                        l.setArray(expectedArray = newElements);
+                    }
+                }
+            }
+            return removed;
+        }
+
+        public Spliterator<E> spliterator() {
+            int lo = offset;
+            int hi = offset + size;
+            Object[] a = expectedArray;
+            if (l.getArray() != a)
+                throw new ConcurrentModificationException();
+            if (lo < 0 || hi > a.length)
+                throw new IndexOutOfBoundsException();
+            return Spliterators.spliterator
+                (a, lo, hi, Spliterator.IMMUTABLE | Spliterator.ORDERED);
+        }
+
+    }
+
+    private static class COWSubListIterator<E> implements ListIterator<E> {
+        private final ListIterator<E> it;
+        private final int offset;
+        private final int size;
+
+        COWSubListIterator(List<E> l, int index, int offset, int size) {
+            this.offset = offset;
+            this.size = size;
+            it = l.listIterator(index+offset);
+        }
+
+        public boolean hasNext() {
+            return nextIndex() < size;
+        }
+
+        public E next() {
+            if (hasNext())
+                return it.next();
+            else
+                throw new NoSuchElementException();
+        }
+
+        public boolean hasPrevious() {
+            return previousIndex() >= 0;
+        }
+
+        public E previous() {
+            if (hasPrevious())
+                return it.previous();
+            else
+                throw new NoSuchElementException();
+        }
+
+        public int nextIndex() {
+            return it.nextIndex() - offset;
+        }
+
+        public int previousIndex() {
+            return it.previousIndex() - offset;
         }
 
         public void remove() {
             throw new UnsupportedOperationException();
         }
 
-        public void set(E object) {
+        public void set(E e) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void add(E e) {
             throw new UnsupportedOperationException();
         }
 
         @Override
+        @SuppressWarnings("unchecked")
         public void forEachRemaining(Consumer<? super E> action) {
-            java.util.Objects.requireNonNull(action);
-            Object[] elements = snapshot;
-            for (int i = index; i < to; i++) {
-                @SuppressWarnings("unchecked") E e = (E) elements[i];
-                action.accept(e);
+            Objects.requireNonNull(action);
+            while (nextIndex() < size) {
+                action.accept(it.next());
             }
-            index = to;
         }
     }
 
-    private void writeObject(ObjectOutputStream out) throws IOException {
-        Object[] snapshot = elements;
-        out.defaultWriteObject();
-        out.writeInt(snapshot.length);
-        for (Object o : snapshot) {
-            out.writeObject(o);
-        }
+    // Support for resetting lock while deserializing
+    private void resetLock() {
+        U.putObjectVolatile(this, LOCK, new Object());
     }
-
-    private synchronized void readObject(ObjectInputStream in)
-            throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-        Object[] snapshot = new Object[in.readInt()];
-        for (int i = 0; i < snapshot.length; i++) {
-            snapshot[i] = in.readObject();
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long LOCK;
+    static {
+        try {
+            LOCK = U.objectFieldOffset
+                (CopyOnWriteArrayList.class.getDeclaredField("lock"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
         }
-        elements = snapshot;
     }
 }
diff --git a/luni/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java b/luni/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
index 347ed14..0cf8558 100644
--- a/luni/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
+++ b/luni/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
@@ -6,10 +6,19 @@
 
 package java.util.concurrent;
 
-import java.util.*;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 // BEGIN android-note
 // removed link to collections framework docs
+// fixed framework docs link to "Collection#optional"
 // END android-note
 
 /**
@@ -35,12 +44,12 @@
  * copy-on-write set to maintain a set of Handler objects that
  * perform some action upon state updates.
  *
- *  <pre> {@code
+ * <pre> {@code
  * class Handler { void handle(); ... }
  *
  * class X {
  *   private final CopyOnWriteArraySet<Handler> handlers
- *     = new CopyOnWriteArraySet<Handler>();
+ *     = new CopyOnWriteArraySet<>();
  *   public void addHandler(Handler h) { handlers.add(h); }
  *
  *   private long internalState;
@@ -56,7 +65,7 @@
  * @see CopyOnWriteArrayList
  * @since 1.5
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this set
  */
 public class CopyOnWriteArraySet<E> extends AbstractSet<E>
         implements java.io.Serializable {
@@ -79,8 +88,15 @@
      * @throws NullPointerException if the specified collection is null
      */
     public CopyOnWriteArraySet(Collection<? extends E> c) {
-        al = new CopyOnWriteArrayList<E>();
-        al.addAllAbsent(c);
+        if (c.getClass() == CopyOnWriteArraySet.class) {
+            @SuppressWarnings("unchecked") CopyOnWriteArraySet<E> cc =
+                (CopyOnWriteArraySet<E>)c;
+            al = new CopyOnWriteArrayList<E>(cc.al);
+        }
+        else {
+            al = new CopyOnWriteArrayList<E>();
+            al.addAllAbsent(c);
+        }
     }
 
     /**
@@ -104,8 +120,7 @@
     /**
      * Returns {@code true} if this set contains the specified element.
      * More formally, returns {@code true} if and only if this set
-     * contains an element {@code e} such that
-     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
+     * contains an element {@code e} such that {@code Objects.equals(o, e)}.
      *
      * @param o element whose presence in this set is to be tested
      * @return {@code true} if this set contains the specified element
@@ -161,7 +176,7 @@
      * The following code can be used to dump the set into a newly allocated
      * array of {@code String}:
      *
-     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -190,11 +205,10 @@
     /**
      * Removes the specified element from this set if it is present.
      * More formally, removes an element {@code e} such that
-     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>,
-     * if this set contains such an element.  Returns {@code true} if
-     * this set contained the element (or equivalently, if this set
-     * changed as a result of the call).  (This set will not contain the
-     * element once the call returns.)
+     * {@code Objects.equals(o, e)}, if this set contains such an element.
+     * Returns {@code true} if this set contained the element (or
+     * equivalently, if this set changed as a result of the call).
+     * (This set will not contain the element once the call returns.)
      *
      * @param o object to be removed from this set, if present
      * @return {@code true} if this set contained the specified element
@@ -207,7 +221,7 @@
      * Adds the specified element to this set if it is not already present.
      * More formally, adds the specified element {@code e} to this set if
      * the set contains no element {@code e2} such that
-     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
+     * {@code Objects.equals(e, e2)}.
      * If this set already contains the element, the call leaves the set
      * unchanged and returns {@code false}.
      *
@@ -231,7 +245,44 @@
      * @see #contains(Object)
      */
     public boolean containsAll(Collection<?> c) {
-        return al.containsAll(c);
+        return (c instanceof Set)
+            ? compareSets(al.getArray(), (Set<?>) c) >= 0
+            : al.containsAll(c);
+    }
+
+    /**
+     * Tells whether the objects in snapshot (regarded as a set) are a
+     * superset of the given set.
+     *
+     * @return -1 if snapshot is not a superset, 0 if the two sets
+     * contain precisely the same elements, and 1 if snapshot is a
+     * proper superset of the given set
+     */
+    private static int compareSets(Object[] snapshot, Set<?> set) {
+        // Uses O(n^2) algorithm, that is only appropriate for small
+        // sets, which CopyOnWriteArraySets should be.
+        //
+        // Optimize up to O(n) if the two sets share a long common prefix,
+        // as might happen if one set was created as a copy of the other set.
+
+        final int len = snapshot.length;
+        // Mark matched elements to avoid re-checking
+        final boolean[] matched = new boolean[len];
+
+        // j is the largest int with matched[i] true for { i | 0 <= i < j }
+        int j = 0;
+        outer: for (Object x : set) {
+            for (int i = j; i < len; i++) {
+                if (!matched[i] && Objects.equals(x, snapshot[i])) {
+                    matched[i] = true;
+                    if (i == j)
+                        do { j++; } while (j < len && matched[j]);
+                    continue outer;
+                }
+            }
+            return -1;
+        }
+        return (j == len) ? 0 : 1;
     }
 
     /**
@@ -260,9 +311,11 @@
      * @param  c collection containing elements to be removed from this set
      * @return {@code true} if this set changed as a result of the call
      * @throws ClassCastException if the class of an element of this set
-     *         is incompatible with the specified collection (optional)
+     *         is incompatible with the specified collection
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if this set contains a null element and the
-     *         specified collection does not permit null elements (optional),
+     *         specified collection does not permit null elements
+     * (<a href="../Collection.html#optional-restrictions">optional</a>),
      *         or if the specified collection is null
      * @see #remove(Object)
      */
@@ -281,9 +334,11 @@
      * @param  c collection containing elements to be retained in this set
      * @return {@code true} if this set changed as a result of the call
      * @throws ClassCastException if the class of an element of this set
-     *         is incompatible with the specified collection (optional)
+     *         is incompatible with the specified collection
+     * (<a href="../Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if this set contains a null element and the
-     *         specified collection does not permit null elements (optional),
+     *         specified collection does not permit null elements
+     * (<a href="../Collection.html#optional-restrictions">optional</a>),
      *         or if the specified collection is null
      * @see #remove(Object)
      */
@@ -310,54 +365,49 @@
      * Compares the specified object with this set for equality.
      * Returns {@code true} if the specified object is the same object
      * as this object, or if it is also a {@link Set} and the elements
-     * returned by an {@linkplain List#iterator() iterator} over the
+     * returned by an {@linkplain Set#iterator() iterator} over the
      * specified set are the same as the elements returned by an
      * iterator over this set.  More formally, the two iterators are
      * considered to return the same elements if they return the same
      * number of elements and for every element {@code e1} returned by
      * the iterator over the specified set, there is an element
      * {@code e2} returned by the iterator over this set such that
-     * {@code (e1==null ? e2==null : e1.equals(e2))}.
+     * {@code Objects.equals(e1, e2)}.
      *
      * @param o object to be compared for equality with this set
      * @return {@code true} if the specified object is equal to this set
      */
     public boolean equals(Object o) {
-        if (o == this)
-            return true;
-        if (!(o instanceof Set))
-            return false;
-        Set<?> set = (Set<?>)(o);
-        Iterator<?> it = set.iterator();
+        return (o == this)
+            || ((o instanceof Set)
+                && compareSets(al.getArray(), (Set<?>) o) == 0);
+    }
 
-        // Uses O(n^2) algorithm that is only appropriate
-        // for small sets, which CopyOnWriteArraySets should be.
+    public boolean removeIf(Predicate<? super E> filter) {
+        return al.removeIf(filter);
+    }
 
-        //  Use a single snapshot of underlying array
-        Object[] elements = al.getArray();
-        int len = elements.length;
-        // Mark matched elements to avoid re-checking
-        boolean[] matched = new boolean[len];
-        int k = 0;
-        outer: while (it.hasNext()) {
-            if (++k > len)
-                return false;
-            Object x = it.next();
-            for (int i = 0; i < len; ++i) {
-                if (!matched[i] && eq(x, elements[i])) {
-                    matched[i] = true;
-                    continue outer;
-                }
-            }
-            return false;
-        }
-        return k == len;
+    public void forEach(Consumer<? super E> action) {
+        al.forEach(action);
     }
 
     /**
-     * Tests for equality, coping with nulls.
+     * Returns a {@link Spliterator} over the elements in this set in the order
+     * in which these elements were added.
+     *
+     * <p>The {@code Spliterator} reports {@link Spliterator#IMMUTABLE},
+     * {@link Spliterator#DISTINCT}, {@link Spliterator#SIZED}, and
+     * {@link Spliterator#SUBSIZED}.
+     *
+     * <p>The spliterator provides a snapshot of the state of the set
+     * when the spliterator was constructed. No synchronization is needed while
+     * operating on the spliterator.
+     *
+     * @return a {@code Spliterator} over the elements in this set
+     * @since 1.8
      */
-    private static boolean eq(Object o1, Object o2) {
-        return (o1 == null) ? o2 == null : o1.equals(o2);
+    public Spliterator<E> spliterator() {
+        return Spliterators.spliterator
+            (al.getArray(), Spliterator.IMMUTABLE | Spliterator.DISTINCT);
     }
 }
diff --git a/luni/src/main/java/java/util/concurrent/CountDownLatch.java b/luni/src/main/java/java/util/concurrent/CountDownLatch.java
index 77093f7..680ea16 100644
--- a/luni/src/main/java/java/util/concurrent/CountDownLatch.java
+++ b/luni/src/main/java/java/util/concurrent/CountDownLatch.java
@@ -44,7 +44,7 @@
  * until all workers have completed.
  * </ul>
  *
- *  <pre> {@code
+ * <pre> {@code
  * class Driver { // ...
  *   void main() throws InterruptedException {
  *     CountDownLatch startSignal = new CountDownLatch(1);
@@ -85,7 +85,7 @@
  * will be able to pass through await. (When threads must repeatedly
  * count down in this way, instead use a {@link CyclicBarrier}.)
  *
- *  <pre> {@code
+ * <pre> {@code
  * class Driver2 { // ...
  *   void main() throws InterruptedException {
  *     CountDownLatch doneSignal = new CountDownLatch(N);
@@ -151,7 +151,7 @@
                 int c = getState();
                 if (c == 0)
                     return false;
-                int nextc = c-1;
+                int nextc = c - 1;
                 if (compareAndSetState(c, nextc))
                     return nextc == 0;
             }
diff --git a/luni/src/main/java/java/util/concurrent/CountedCompleter.java b/luni/src/main/java/java/util/concurrent/CountedCompleter.java
index b868037..9c8b1b2 100644
--- a/luni/src/main/java/java/util/concurrent/CountedCompleter.java
+++ b/luni/src/main/java/java/util/concurrent/CountedCompleter.java
@@ -13,7 +13,7 @@
  * presence of subtask stalls and blockage than are other forms of
  * ForkJoinTasks, but are less intuitive to program.  Uses of
  * CountedCompleter are similar to those of other completion based
- * components (such as {@link java.nio.channels.CompletionHandler})
+ * components
  * except that multiple <em>pending</em> completions may be necessary
  * to trigger the completion action {@link #onCompletion(CountedCompleter)},
  * not just one.
@@ -139,7 +139,8 @@
  * {@code tryComplete}) the pending count is set to one:
  *
  * <pre> {@code
- * class ForEach<E> ...
+ * class ForEach<E> ... {
+ *   ...
  *   public void compute() { // version 2
  *     if (hi - lo >= 2) {
  *       int mid = (lo + hi) >>> 1;
@@ -153,18 +154,19 @@
  *       tryComplete();
  *     }
  *   }
- * }</pre>
+ * }}</pre>
  *
- * As a further improvement, notice that the left task need not even exist.
+ * As a further optimization, notice that the left task need not even exist.
  * Instead of creating a new one, we can iterate using the original task,
  * and add a pending count for each fork.  Additionally, because no task
  * in this tree implements an {@link #onCompletion(CountedCompleter)} method,
  * {@code tryComplete()} can be replaced with {@link #propagateCompletion}.
  *
  * <pre> {@code
- * class ForEach<E> ...
+ * class ForEach<E> ... {
+ *   ...
  *   public void compute() { // version 3
- *     int l = lo,  h = hi;
+ *     int l = lo, h = hi;
  *     while (h - l >= 2) {
  *       int mid = (l + h) >>> 1;
  *       addToPendingCount(1);
@@ -175,9 +177,9 @@
  *       op.apply(array[l]);
  *     propagateCompletion();
  *   }
- * }</pre>
+ * }}</pre>
  *
- * Additional improvements of such classes might entail precomputing
+ * Additional optimizations of such classes might entail precomputing
  * pending counts so that they can be established in constructors,
  * specializing classes for leaf steps, subdividing by say, four,
  * instead of two per iteration, and using an adaptive threshold
@@ -204,7 +206,7 @@
  *   }
  *   public E getRawResult() { return result.get(); }
  *   public void compute() { // similar to ForEach version 3
- *     int l = lo,  h = hi;
+ *     int l = lo, h = hi;
  *     while (result.get() == null && h >= l) {
  *       if (h - l >= 2) {
  *         int mid = (l + h) >>> 1;
@@ -229,9 +231,9 @@
  * }}</pre>
  *
  * In this example, as well as others in which tasks have no other
- * effects except to compareAndSet a common result, the trailing
- * unconditional invocation of {@code tryComplete} could be made
- * conditional ({@code if (result.get() == null) tryComplete();})
+ * effects except to {@code compareAndSet} a common result, the
+ * trailing unconditional invocation of {@code tryComplete} could be
+ * made conditional ({@code if (result.get() == null) tryComplete();})
  * because no further bookkeeping is required to manage completions
  * once the root task completes.
  *
@@ -334,7 +336,7 @@
  *     this.next = next;
  *   }
  *   public void compute() {
- *     int l = lo,  h = hi;
+ *     int l = lo, h = hi;
  *     while (h - l >= 2) {
  *       int mid = (l + h) >>> 1;
  *       addToPendingCount(1);
@@ -345,7 +347,7 @@
  *       result = mapper.apply(array[l]);
  *     // process completions by reducing along and advancing subtask links
  *     for (CountedCompleter<?> c = firstComplete(); c != null; c = c.nextComplete()) {
- *       for (MapReducer t = (MapReducer)c, s = t.forks;  s != null; s = t.forks = s.next)
+ *       for (MapReducer t = (MapReducer)c, s = t.forks; s != null; s = t.forks = s.next)
  *         t.result = reducer.apply(t.result, s.result);
  *     }
  *   }
@@ -373,11 +375,9 @@
  * // sample use:
  * PacketSender p = new PacketSender();
  * new HeaderBuilder(p, ...).fork();
- * new BodyBuilder(p, ...).fork();
- * }</pre>
+ * new BodyBuilder(p, ...).fork();}</pre>
  *
  * @since 1.8
- * @hide
  * @author Doug Lea
  */
 public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
@@ -495,8 +495,7 @@
      * @param delta the value to add
      */
     public final void addToPendingCount(int delta) {
-        int c;
-        do {} while (!U.compareAndSwapInt(this, PENDING, c = pending, c+delta));
+        U.getAndAddInt(this, PENDING, delta);
     }
 
     /**
@@ -596,7 +595,7 @@
      * any one (versus all) of several subtask results are obtained.
      * However, in the common (and recommended) case in which {@code
      * setRawResult} is not overridden, this effect can be obtained
-     * more simply using {@code quietlyCompleteRoot();}.
+     * more simply using {@link #quietlyCompleteRoot()}.
      *
      * @param rawResult the raw result
      */
@@ -611,9 +610,9 @@
 
     /**
      * If this task's pending count is zero, returns this task;
-     * otherwise decrements its pending count and returns {@code
-     * null}. This method is designed to be used with {@link
-     * #nextComplete} in completion traversal loops.
+     * otherwise decrements its pending count and returns {@code null}.
+     * This method is designed to be used with {@link #nextComplete} in
+     * completion traversal loops.
      *
      * @return this task, if pending count was zero, else {@code null}
      */
@@ -667,6 +666,26 @@
     }
 
     /**
+     * If this task has not completed, attempts to process at most the
+     * given number of other unprocessed tasks for which this task is
+     * on the completion path, if any are known to exist.
+     *
+     * @param maxTasks the maximum number of tasks to process.  If
+     *                 less than or equal to zero, then no tasks are
+     *                 processed.
+     */
+    public final void helpComplete(int maxTasks) {
+        Thread t; ForkJoinWorkerThread wt;
+        if (maxTasks > 0 && status >= 0) {
+            if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)
+                (wt = (ForkJoinWorkerThread)t).pool.
+                    helpComplete(wt.workQueue, this, maxTasks);
+            else
+                ForkJoinPool.common.externalHelpComplete(this, maxTasks);
+        }
+    }
+
+    /**
      * Supports ForkJoinTask exception propagation.
      */
     void internalPropagateException(Throwable ex) {
@@ -706,14 +725,13 @@
     protected void setRawResult(T t) { }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
     private static final long PENDING;
     static {
         try {
-            U = sun.misc.Unsafe.getUnsafe();
             PENDING = U.objectFieldOffset
                 (CountedCompleter.class.getDeclaredField("pending"));
-        } catch (Exception e) {
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
     }
diff --git a/luni/src/main/java/java/util/concurrent/CyclicBarrier.java b/luni/src/main/java/java/util/concurrent/CyclicBarrier.java
index d698501..7219c93 100644
--- a/luni/src/main/java/java/util/concurrent/CyclicBarrier.java
+++ b/luni/src/main/java/java/util/concurrent/CyclicBarrier.java
@@ -23,10 +23,10 @@
  * This <em>barrier action</em> is useful
  * for updating shared-state before any of the parties continue.
  *
- * <p><b>Sample usage:</b> Here is an example of
- *  using a barrier in a parallel decomposition design:
+ * <p><b>Sample usage:</b> Here is an example of using a barrier in a
+ * parallel decomposition design:
  *
- *  <pre> {@code
+ * <pre> {@code
  * class Solver {
  *   final int N;
  *   final float[][] data;
@@ -53,16 +53,20 @@
  *   public Solver(float[][] matrix) {
  *     data = matrix;
  *     N = matrix.length;
- *     barrier = new CyclicBarrier(N,
- *                                 new Runnable() {
- *                                   public void run() {
- *                                     mergeRows(...);
- *                                   }
- *                                 });
- *     for (int i = 0; i < N; ++i)
- *       new Thread(new Worker(i)).start();
+ *     Runnable barrierAction =
+ *       new Runnable() { public void run() { mergeRows(...); }};
+ *     barrier = new CyclicBarrier(N, barrierAction);
  *
- *     waitUntilDone();
+ *     List<Thread> threads = new ArrayList<>(N);
+ *     for (int i = 0; i < N; i++) {
+ *       Thread thread = new Thread(new Worker(i));
+ *       threads.add(thread);
+ *       thread.start();
+ *     }
+ *
+ *     // wait until done
+ *     for (Thread thread : threads)
+ *       thread.join();
  *   }
  * }}</pre>
  *
@@ -79,7 +83,7 @@
  * {@link #await} returns the arrival index of that thread at the barrier.
  * You can then choose which thread should execute the barrier action, for
  * example:
- *  <pre> {@code
+ * <pre> {@code
  * if (barrier.await() == 0) {
  *   // log the completion of this iteration
  * }}</pre>
@@ -117,7 +121,7 @@
      * but no subsequent reset.
      */
     private static class Generation {
-        boolean broken = false;
+        boolean broken;         // initially false
     }
 
     /** The lock for guarding barrier entry */
@@ -388,7 +392,8 @@
      *         to arrive and zero indicates the last to arrive
      * @throws InterruptedException if the current thread was interrupted
      *         while waiting
-     * @throws TimeoutException if the specified timeout elapses
+     * @throws TimeoutException if the specified timeout elapses.
+     *         In this case the barrier will be broken.
      * @throws BrokenBarrierException if <em>another</em> thread was
      *         interrupted or timed out while the current thread was
      *         waiting, or the barrier was reset, or the barrier was broken
diff --git a/luni/src/main/java/java/util/concurrent/DelayQueue.java b/luni/src/main/java/java/util/concurrent/DelayQueue.java
index e4a715e..d100a9c 100644
--- a/luni/src/main/java/java/util/concurrent/DelayQueue.java
+++ b/luni/src/main/java/java/util/concurrent/DelayQueue.java
@@ -7,9 +7,14 @@
 package java.util.concurrent;
 
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.util.AbstractQueue;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.PriorityQueue;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.*;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -37,7 +42,7 @@
  *
  * @since 1.5
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
     implements BlockingQueue<E> {
@@ -157,10 +162,9 @@
         lock.lock();
         try {
             E first = q.peek();
-            if (first == null || first.getDelay(NANOSECONDS) > 0)
-                return null;
-            else
-                return q.poll();
+            return (first == null || first.getDelay(NANOSECONDS) > 0)
+                ? null
+                : q.poll();
         } finally {
             lock.unlock();
         }
@@ -183,7 +187,7 @@
                     available.await();
                 else {
                     long delay = first.getDelay(NANOSECONDS);
-                    if (delay <= 0)
+                    if (delay <= 0L)
                         return q.poll();
                     first = null; // don't retain ref while waiting
                     if (leader != null)
@@ -225,15 +229,15 @@
             for (;;) {
                 E first = q.peek();
                 if (first == null) {
-                    if (nanos <= 0)
+                    if (nanos <= 0L)
                         return null;
                     else
                         nanos = available.awaitNanos(nanos);
                 } else {
                     long delay = first.getDelay(NANOSECONDS);
-                    if (delay <= 0)
+                    if (delay <= 0L)
                         return q.poll();
-                    if (nanos <= 0)
+                    if (nanos <= 0L)
                         return null;
                     first = null; // don't retain ref while waiting
                     if (nanos < delay || leader != null)
@@ -462,7 +466,7 @@
     }
 
     /**
-     * Identity-based version for use in Itr.remove
+     * Identity-based version for use in Itr.remove.
      */
     void removeEQ(Object o) {
         final ReentrantLock lock = this.lock;
@@ -484,12 +488,8 @@
      * unexpired) in this queue. The iterator does not return the
      * elements in any particular order.
      *
-     * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException}, and guarantees to traverse
-     * elements as they existed upon construction of the iterator, and
-     * may (but is not guaranteed to) reflect any modifications
-     * subsequent to construction.
+     * <p>The returned iterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return an iterator over the elements in this queue
      */
diff --git a/luni/src/main/java/java/util/concurrent/Exchanger.java b/luni/src/main/java/java/util/concurrent/Exchanger.java
index 60871b4..5f4c534 100644
--- a/luni/src/main/java/java/util/concurrent/Exchanger.java
+++ b/luni/src/main/java/java/util/concurrent/Exchanger.java
@@ -21,9 +21,9 @@
  * to swap buffers between threads so that the thread filling the
  * buffer gets a freshly emptied one when it needs it, handing off the
  * filled one to the thread emptying the buffer.
- *  <pre> {@code
+ * <pre> {@code
  * class FillAndEmpty {
- *   Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
+ *   Exchanger<DataBuffer> exchanger = new Exchanger<>();
  *   DataBuffer initialEmptyBuffer = ... a made-up type
  *   DataBuffer initialFullBuffer = ...
  *
@@ -125,9 +125,10 @@
      * writing, there is no way to determine cacheline size, we define
      * a value that is enough for common platforms.  Additionally,
      * extra care elsewhere is taken to avoid other false/unintended
-     * sharing and to enhance locality, including adding padding to
-     * Nodes, embedding "bound" as an Exchanger field, and reworking
-     * some park/unpark mechanics compared to LockSupport versions.
+     * sharing and to enhance locality, including adding padding (via
+     * @Contended) to Nodes, embedding "bound" as an Exchanger field,
+     * and reworking some park/unpark mechanics compared to
+     * LockSupport versions.
      *
      * The arena starts out with only one used slot. We expand the
      * effective arena size by tracking collisions; i.e., failed CASes
@@ -274,8 +275,9 @@
 
     /**
      * Nodes hold partially exchanged data, plus other per-thread
-     * bookkeeping.
+     * bookkeeping. Padded via @Contended to reduce memory contention.
      */
+    //@jdk.internal.vm.annotation.Contended // android-removed
     static final class Node {
         int index;              // Arena index
         int bound;              // Last recorded value of Exchanger.bound
@@ -284,10 +286,6 @@
         Object item;            // This thread's current item
         volatile Object match;  // Item provided by releasing thread
         volatile Thread parked; // Set to this thread when parked, else null
-
-        // Padding to ameliorate unfortunate memory placements
-        Object p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa, pb, pc, pd, pe, pf;
-        Object q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe, qf;
     }
 
     /** The corresponding thread local class */
@@ -296,7 +294,7 @@
     }
 
     /**
-     * Per-thread state
+     * Per-thread state.
      */
     private final Participant participant;
 
@@ -598,37 +596,33 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
     private static final long BOUND;
     private static final long SLOT;
     private static final long MATCH;
     private static final long BLOCKER;
     private static final int ABASE;
     static {
-        int s;
         try {
-            U = sun.misc.Unsafe.getUnsafe();
-            Class<?> ek = Exchanger.class;
-            Class<?> nk = Node.class;
-            Class<?> ak = Node[].class;
-            Class<?> tk = Thread.class;
             BOUND = U.objectFieldOffset
-                (ek.getDeclaredField("bound"));
+                (Exchanger.class.getDeclaredField("bound"));
             SLOT = U.objectFieldOffset
-                (ek.getDeclaredField("slot"));
-            MATCH = U.objectFieldOffset
-                (nk.getDeclaredField("match"));
-            BLOCKER = U.objectFieldOffset
-                (tk.getDeclaredField("parkBlocker"));
-            s = U.arrayIndexScale(ak);
-            // ABASE absorbs padding in front of element 0
-            ABASE = U.arrayBaseOffset(ak) + (1 << ASHIFT);
+                (Exchanger.class.getDeclaredField("slot"));
 
-        } catch (Exception e) {
+            MATCH = U.objectFieldOffset
+                (Node.class.getDeclaredField("match"));
+
+            BLOCKER = U.objectFieldOffset
+                (Thread.class.getDeclaredField("parkBlocker"));
+
+            int scale = U.arrayIndexScale(Node[].class);
+            if ((scale & (scale - 1)) != 0 || scale > (1 << ASHIFT))
+                throw new Error("Unsupported array scale");
+            // ABASE absorbs padding in front of element 0
+            ABASE = U.arrayBaseOffset(Node[].class) + (1 << ASHIFT);
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
-        if ((s & (s-1)) != 0 || s > (1 << ASHIFT))
-            throw new Error("Unsupported array scale");
     }
 
 }
diff --git a/luni/src/main/java/java/util/concurrent/Executor.java b/luni/src/main/java/java/util/concurrent/Executor.java
index 095ebfc..9dd3efb 100644
--- a/luni/src/main/java/java/util/concurrent/Executor.java
+++ b/luni/src/main/java/java/util/concurrent/Executor.java
@@ -15,30 +15,28 @@
  * invoking {@code new Thread(new RunnableTask()).start()} for each
  * of a set of tasks, you might use:
  *
- * <pre>
- * Executor executor = <em>anExecutor</em>;
+ * <pre> {@code
+ * Executor executor = anExecutor();
  * executor.execute(new RunnableTask1());
  * executor.execute(new RunnableTask2());
- * ...
- * </pre>
+ * ...}</pre>
  *
- * However, the {@code Executor} interface does not strictly
- * require that execution be asynchronous. In the simplest case, an
- * executor can run the submitted task immediately in the caller's
- * thread:
+ * However, the {@code Executor} interface does not strictly require
+ * that execution be asynchronous. In the simplest case, an executor
+ * can run the submitted task immediately in the caller's thread:
  *
- *  <pre> {@code
+ * <pre> {@code
  * class DirectExecutor implements Executor {
  *   public void execute(Runnable r) {
  *     r.run();
  *   }
  * }}</pre>
  *
- * More typically, tasks are executed in some thread other
- * than the caller's thread.  The executor below spawns a new thread
- * for each task.
+ * More typically, tasks are executed in some thread other than the
+ * caller's thread.  The executor below spawns a new thread for each
+ * task.
  *
- *  <pre> {@code
+ * <pre> {@code
  * class ThreadPerTaskExecutor implements Executor {
  *   public void execute(Runnable r) {
  *     new Thread(r).start();
@@ -50,7 +48,7 @@
  * serializes the submission of tasks to a second executor,
  * illustrating a composite executor.
  *
- *  <pre> {@code
+ * <pre> {@code
  * class SerialExecutor implements Executor {
  *   final Queue<Runnable> tasks = new ArrayDeque<>();
  *   final Executor executor;
diff --git a/luni/src/main/java/java/util/concurrent/ExecutorCompletionService.java b/luni/src/main/java/java/util/concurrent/ExecutorCompletionService.java
index 9514246..cea0384 100644
--- a/luni/src/main/java/java/util/concurrent/ExecutorCompletionService.java
+++ b/luni/src/main/java/java/util/concurrent/ExecutorCompletionService.java
@@ -27,16 +27,16 @@
  * void solve(Executor e,
  *            Collection<Callable<Result>> solvers)
  *     throws InterruptedException, ExecutionException {
- *     CompletionService<Result> ecs
- *         = new ExecutorCompletionService<Result>(e);
- *     for (Callable<Result> s : solvers)
- *         ecs.submit(s);
- *     int n = solvers.size();
- *     for (int i = 0; i < n; ++i) {
- *         Result r = ecs.take().get();
- *         if (r != null)
- *             use(r);
- *     }
+ *   CompletionService<Result> ecs
+ *       = new ExecutorCompletionService<Result>(e);
+ *   for (Callable<Result> s : solvers)
+ *     ecs.submit(s);
+ *   int n = solvers.size();
+ *   for (int i = 0; i < n; ++i) {
+ *     Result r = ecs.take().get();
+ *     if (r != null)
+ *       use(r);
+ *   }
  * }}</pre>
  *
  * Suppose instead that you would like to use the first non-null result
@@ -47,32 +47,31 @@
  * void solve(Executor e,
  *            Collection<Callable<Result>> solvers)
  *     throws InterruptedException {
- *     CompletionService<Result> ecs
- *         = new ExecutorCompletionService<Result>(e);
- *     int n = solvers.size();
- *     List<Future<Result>> futures
- *         = new ArrayList<Future<Result>>(n);
- *     Result result = null;
- *     try {
- *         for (Callable<Result> s : solvers)
- *             futures.add(ecs.submit(s));
- *         for (int i = 0; i < n; ++i) {
- *             try {
- *                 Result r = ecs.take().get();
- *                 if (r != null) {
- *                     result = r;
- *                     break;
- *                 }
- *             } catch (ExecutionException ignore) {}
+ *   CompletionService<Result> ecs
+ *       = new ExecutorCompletionService<Result>(e);
+ *   int n = solvers.size();
+ *   List<Future<Result>> futures = new ArrayList<>(n);
+ *   Result result = null;
+ *   try {
+ *     for (Callable<Result> s : solvers)
+ *       futures.add(ecs.submit(s));
+ *     for (int i = 0; i < n; ++i) {
+ *       try {
+ *         Result r = ecs.take().get();
+ *         if (r != null) {
+ *           result = r;
+ *           break;
  *         }
+ *       } catch (ExecutionException ignore) {}
  *     }
- *     finally {
- *         for (Future<Result> f : futures)
- *             f.cancel(true);
- *     }
+ *   }
+ *   finally {
+ *     for (Future<Result> f : futures)
+ *       f.cancel(true);
+ *   }
  *
- *     if (result != null)
- *         use(result);
+ *   if (result != null)
+ *     use(result);
  * }}</pre>
  */
 public class ExecutorCompletionService<V> implements CompletionService<V> {
@@ -81,15 +80,18 @@
     private final BlockingQueue<Future<V>> completionQueue;
 
     /**
-     * FutureTask extension to enqueue upon completion
+     * FutureTask extension to enqueue upon completion.
      */
-    private class QueueingFuture extends FutureTask<Void> {
-        QueueingFuture(RunnableFuture<V> task) {
+    private static class QueueingFuture<V> extends FutureTask<Void> {
+        QueueingFuture(RunnableFuture<V> task,
+                       BlockingQueue<Future<V>> completionQueue) {
             super(task, null);
             this.task = task;
+            this.completionQueue = completionQueue;
         }
-        protected void done() { completionQueue.add(task); }
         private final Future<V> task;
+        private final BlockingQueue<Future<V>> completionQueue;
+        protected void done() { completionQueue.add(task); }
     }
 
     private RunnableFuture<V> newTaskFor(Callable<V> task) {
@@ -149,14 +151,14 @@
     public Future<V> submit(Callable<V> task) {
         if (task == null) throw new NullPointerException();
         RunnableFuture<V> f = newTaskFor(task);
-        executor.execute(new QueueingFuture(f));
+        executor.execute(new QueueingFuture<V>(f, completionQueue));
         return f;
     }
 
     public Future<V> submit(Runnable task, V result) {
         if (task == null) throw new NullPointerException();
         RunnableFuture<V> f = newTaskFor(task, result);
-        executor.execute(new QueueingFuture(f));
+        executor.execute(new QueueingFuture<V>(f, completionQueue));
         return f;
     }
 
diff --git a/luni/src/main/java/java/util/concurrent/ExecutorService.java b/luni/src/main/java/java/util/concurrent/ExecutorService.java
index 58a2113..ce7b2c6 100644
--- a/luni/src/main/java/java/util/concurrent/ExecutorService.java
+++ b/luni/src/main/java/java/util/concurrent/ExecutorService.java
@@ -6,8 +6,8 @@
 
 package java.util.concurrent;
 
-import java.util.List;
 import java.util.Collection;
+import java.util.List;
 
 // BEGIN android-note
 // removed security manager docs
@@ -47,7 +47,7 @@
  * pool service incoming requests. It uses the preconfigured {@link
  * Executors#newFixedThreadPool} factory method:
  *
- *  <pre> {@code
+ * <pre> {@code
  * class NetworkService implements Runnable {
  *   private final ServerSocket serverSocket;
  *   private final ExecutorService pool;
@@ -81,7 +81,7 @@
  * first by calling {@code shutdown} to reject incoming tasks, and then
  * calling {@code shutdownNow}, if necessary, to cancel any lingering tasks:
  *
- *  <pre> {@code
+ * <pre> {@code
  * void shutdownAndAwaitTermination(ExecutorService pool) {
  *   pool.shutdown(); // Disable new tasks from being submitted
  *   try {
diff --git a/luni/src/main/java/java/util/concurrent/Executors.java b/luni/src/main/java/java/util/concurrent/Executors.java
index 2068fd7..3d49b82 100644
--- a/luni/src/main/java/java/util/concurrent/Executors.java
+++ b/luni/src/main/java/java/util/concurrent/Executors.java
@@ -6,17 +6,21 @@
 
 package java.util.concurrent;
 
-import java.util.*;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.security.AccessControlContext;
+import java.security.AccessControlException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
 import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import sun.security.util.SecurityConstants;
 
 // BEGIN android-note
 // removed security manager docs
 // END android-note
+
 /**
  * Factory and utility methods for {@link Executor}, {@link
  * ExecutorService}, {@link ScheduledExecutorService}, {@link
@@ -24,18 +28,18 @@
  * package. This class supports the following kinds of methods:
  *
  * <ul>
- *   <li> Methods that create and return an {@link ExecutorService}
- *        set up with commonly useful configuration settings.
- *   <li> Methods that create and return a {@link ScheduledExecutorService}
- *        set up with commonly useful configuration settings.
- *   <li> Methods that create and return a "wrapped" ExecutorService, that
- *        disables reconfiguration by making implementation-specific methods
- *        inaccessible.
- *   <li> Methods that create and return a {@link ThreadFactory}
- *        that sets newly created threads to a known state.
- *   <li> Methods that create and return a {@link Callable}
- *        out of other closure-like forms, so they can be used
- *        in execution methods requiring {@code Callable}.
+ *   <li>Methods that create and return an {@link ExecutorService}
+ *       set up with commonly useful configuration settings.
+ *   <li>Methods that create and return a {@link ScheduledExecutorService}
+ *       set up with commonly useful configuration settings.
+ *   <li>Methods that create and return a "wrapped" ExecutorService, that
+ *       disables reconfiguration by making implementation-specific methods
+ *       inaccessible.
+ *   <li>Methods that create and return a {@link ThreadFactory}
+ *       that sets newly created threads to a known state.
+ *   <li>Methods that create and return a {@link Callable}
+ *       out of other closure-like forms, so they can be used
+ *       in execution methods requiring {@code Callable}.
  * </ul>
  *
  * @since 1.5
@@ -78,7 +82,6 @@
      * @return the newly created thread pool
      * @throws IllegalArgumentException if {@code parallelism <= 0}
      * @since 1.8
-     * @hide
      */
     public static ExecutorService newWorkStealingPool(int parallelism) {
         return new ForkJoinPool
@@ -88,12 +91,13 @@
     }
 
     /**
-     * Creates a work-stealing thread pool using all
-     * {@link Runtime#availableProcessors available processors}
+     * Creates a work-stealing thread pool using the number of
+     * {@linkplain Runtime#availableProcessors available processors}
      * as its target parallelism level.
+     *
      * @return the newly created thread pool
+     * @see #newWorkStealingPool(int)
      * @since 1.8
-     * @hide
      */
     public static ExecutorService newWorkStealingPool() {
         return new ForkJoinPool
@@ -411,11 +415,11 @@
     // Non-public classes supporting the public methods
 
     /**
-     * A callable that runs given task and returns given result
+     * A callable that runs given task and returns given result.
      */
-    static final class RunnableAdapter<T> implements Callable<T> {
-        final Runnable task;
-        final T result;
+    private static final class RunnableAdapter<T> implements Callable<T> {
+        private final Runnable task;
+        private final T result;
         RunnableAdapter(Runnable task, T result) {
             this.task = task;
             this.result = result;
@@ -427,11 +431,11 @@
     }
 
     /**
-     * A callable that runs under established access control settings
+     * A callable that runs under established access control settings.
      */
-    static final class PrivilegedCallable<T> implements Callable<T> {
-        private final Callable<T> task;
-        private final AccessControlContext acc;
+    private static final class PrivilegedCallable<T> implements Callable<T> {
+        final Callable<T> task;
+        final AccessControlContext acc;
 
         PrivilegedCallable(Callable<T> task) {
             this.task = task;
@@ -454,12 +458,13 @@
 
     /**
      * A callable that runs under established access control settings and
-     * current ClassLoader
+     * current ClassLoader.
      */
-    static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
-        private final Callable<T> task;
-        private final AccessControlContext acc;
-        private final ClassLoader ccl;
+    private static final class PrivilegedCallableUsingCurrentClassLoader<T>
+            implements Callable<T> {
+        final Callable<T> task;
+        final AccessControlContext acc;
+        final ClassLoader ccl;
 
         PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
             // BEGIN android-removed
@@ -469,7 +474,7 @@
             //     // never trigger a security check, but we check
             //     // whether our callers have this permission anyways.
             //     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
-            //
+
             //     // Whether setContextClassLoader turns out to be necessary
             //     // or not, we fail fast if permission is not available.
             //     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
@@ -506,9 +511,9 @@
     }
 
     /**
-     * The default thread factory
+     * The default thread factory.
      */
-    static class DefaultThreadFactory implements ThreadFactory {
+    private static class DefaultThreadFactory implements ThreadFactory {
         private static final AtomicInteger poolNumber = new AtomicInteger(1);
         private final ThreadGroup group;
         private final AtomicInteger threadNumber = new AtomicInteger(1);
@@ -536,11 +541,11 @@
     }
 
     /**
-     * Thread factory capturing access control context and class loader
+     * Thread factory capturing access control context and class loader.
      */
-    static class PrivilegedThreadFactory extends DefaultThreadFactory {
-        private final AccessControlContext acc;
-        private final ClassLoader ccl;
+    private static class PrivilegedThreadFactory extends DefaultThreadFactory {
+        final AccessControlContext acc;
+        final ClassLoader ccl;
 
         PrivilegedThreadFactory() {
             super();
@@ -551,7 +556,7 @@
             //     // never trigger a security check, but we check
             //     // whether our callers have this permission anyways.
             //     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
-            //
+
             //     // Fail fast
             //     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
             // }
@@ -579,7 +584,8 @@
      * A wrapper class that exposes only the ExecutorService methods
      * of an ExecutorService implementation.
      */
-    static class DelegatedExecutorService extends AbstractExecutorService {
+    private static class DelegatedExecutorService
+            extends AbstractExecutorService {
         private final ExecutorService e;
         DelegatedExecutorService(ExecutorService executor) { e = executor; }
         public void execute(Runnable command) { e.execute(command); }
@@ -620,8 +626,8 @@
         }
     }
 
-    static class FinalizableDelegatedExecutorService
-        extends DelegatedExecutorService {
+    private static class FinalizableDelegatedExecutorService
+            extends DelegatedExecutorService {
         FinalizableDelegatedExecutorService(ExecutorService executor) {
             super(executor);
         }
@@ -634,7 +640,7 @@
      * A wrapper class that exposes only the ScheduledExecutorService
      * methods of a ScheduledExecutorService implementation.
      */
-    static class DelegatedScheduledExecutorService
+    private static class DelegatedScheduledExecutorService
             extends DelegatedExecutorService
             implements ScheduledExecutorService {
         private final ScheduledExecutorService e;
diff --git a/luni/src/main/java/java/util/concurrent/ForkJoinPool.java b/luni/src/main/java/java/util/concurrent/ForkJoinPool.java
index 41dd161..184d07a 100644
--- a/luni/src/main/java/java/util/concurrent/ForkJoinPool.java
+++ b/luni/src/main/java/java/util/concurrent/ForkJoinPool.java
@@ -7,11 +7,16 @@
 package java.util.concurrent;
 
 import java.lang.Thread.UncaughtExceptionHandler;
+import java.security.AccessControlContext;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.LockSupport;
 
 /**
  * An {@link ExecutorService} for running {@link ForkJoinTask}s.
@@ -31,7 +36,7 @@
  * ForkJoinPool}s may also be appropriate for use with event-style
  * tasks that are never joined.
  *
- * <p>A static {@code commonPool()} is available and appropriate for
+ * <p>A static {@link #commonPool()} is available and appropriate for
  * most applications. The common pool is used by any ForkJoinTask that
  * is not explicitly submitted to a specified pool. Using the common
  * pool normally reduces resource usage (its threads are slowly
@@ -40,9 +45,9 @@
  *
  * <p>For applications that require separate or custom pools, a {@code
  * ForkJoinPool} may be constructed with a given target parallelism
- * level; by default, equal to the number of available processors. The
- * pool attempts to maintain enough active (or available) threads by
- * dynamically adding, suspending, or resuming internal worker
+ * level; by default, equal to the number of available processors.
+ * The pool attempts to maintain enough active (or available) threads
+ * by dynamically adding, suspending, or resuming internal worker
  * threads, even if some tasks are stalled waiting to join others.
  * However, no such adjustments are guaranteed in the face of blocked
  * I/O or other unmanaged synchronization. The nested {@link
@@ -102,12 +107,19 @@
  * - the class name of a {@link ForkJoinWorkerThreadFactory}
  * <li>{@code java.util.concurrent.ForkJoinPool.common.exceptionHandler}
  * - the class name of a {@link UncaughtExceptionHandler}
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.maximumSpares}
+ * - the maximum number of allowed extra threads to maintain target
+ * parallelism (default 256).
  * </ul>
+ * If a {@link SecurityManager} is present and no factory is
+ * specified, then the default pool uses a factory supplying
+ * threads that have no {@link Permissions} enabled.
  * The system class loader is used to load these classes.
  * Upon any error in establishing these settings, default parameters
  * are used. It is possible to disable or limit the use of threads in
  * the common pool by setting the parallelism property to zero, and/or
- * using a factory that may return {@code null}.
+ * using a factory that may return {@code null}. However doing so may
+ * cause unjoined tasks to never be executed.
  *
  * <p><b>Implementation notes</b>: This implementation restricts the
  * maximum number of running threads to 32767. Attempts to create
@@ -121,6 +133,7 @@
  * @since 1.7
  * @author Doug Lea
  */
+//@jdk.internal.vm.annotation.Contended   // android-removed
 public class ForkJoinPool extends AbstractExecutorService {
 
     /*
@@ -133,7 +146,14 @@
      * that may be stolen by other workers.  Preference rules give
      * first priority to processing tasks from their own queues (LIFO
      * or FIFO, depending on mode), then to randomized FIFO steals of
-     * tasks in other queues.
+     * tasks in other queues.  This framework began as vehicle for
+     * supporting tree-structured parallelism using work-stealing.
+     * Over time, its scalability advantages led to extensions and
+     * changes to better support more diverse usage contexts.  Because
+     * most internal methods and nested classes are interrelated,
+     * their main rationale and descriptions are presented here;
+     * individual methods and nested classes contain only brief
+     * comments about details.
      *
      * WorkQueues
      * ==========
@@ -153,200 +173,305 @@
      * (http://research.sun.com/scalable/pubs/index.html) and
      * "Idempotent work stealing" by Michael, Saraswat, and Vechev,
      * PPoPP 2009 (http://portal.acm.org/citation.cfm?id=1504186).
-     * See also "Correct and Efficient Work-Stealing for Weak Memory
-     * Models" by Le, Pop, Cohen, and Nardelli, PPoPP 2013
+     * The main differences ultimately stem from GC requirements that
+     * we null out taken slots as soon as we can, to maintain as small
+     * a footprint as possible even in programs generating huge
+     * numbers of tasks. To accomplish this, we shift the CAS
+     * arbitrating pop vs poll (steal) from being on the indices
+     * ("base" and "top") to the slots themselves.
+     *
+     * Adding tasks then takes the form of a classic array push(task)
+     * in a circular buffer:
+     *    q.array[q.top++ % length] = task;
+     *
+     * (The actual code needs to null-check and size-check the array,
+     * uses masking, not mod, for indexing a power-of-two-sized array,
+     * properly fences accesses, and possibly signals waiting workers
+     * to start scanning -- see below.)  Both a successful pop and
+     * poll mainly entail a CAS of a slot from non-null to null.
+     *
+     * The pop operation (always performed by owner) is:
+     *   if ((the task at top slot is not null) and
+     *        (CAS slot to null))
+     *           decrement top and return task;
+     *
+     * And the poll operation (usually by a stealer) is
+     *    if ((the task at base slot is not null) and
+     *        (CAS slot to null))
+     *           increment base and return task;
+     *
+     * There are several variants of each of these; for example most
+     * versions of poll pre-screen the CAS by rechecking that the base
+     * has not changed since reading the slot, and most methods only
+     * attempt the CAS if base appears not to be equal to top.
+     *
+     * Memory ordering.  See "Correct and Efficient Work-Stealing for
+     * Weak Memory Models" by Le, Pop, Cohen, and Nardelli, PPoPP 2013
      * (http://www.di.ens.fr/~zappa/readings/ppopp13.pdf) for an
-     * analysis of memory ordering (atomic, volatile etc) issues.  The
-     * main differences ultimately stem from GC requirements that we
-     * null out taken slots as soon as we can, to maintain as small a
-     * footprint as possible even in programs generating huge numbers
-     * of tasks. To accomplish this, we shift the CAS arbitrating pop
-     * vs poll (steal) from being on the indices ("base" and "top") to
-     * the slots themselves.  So, both a successful pop and poll
-     * mainly entail a CAS of a slot from non-null to null.  Because
-     * we rely on CASes of references, we do not need tag bits on base
-     * or top.  They are simple ints as used in any circular
-     * array-based queue (see for example ArrayDeque).  Updates to the
-     * indices must still be ordered in a way that guarantees that top
-     * == base means the queue is empty, but otherwise may err on the
-     * side of possibly making the queue appear nonempty when a push,
-     * pop, or poll have not fully committed. Note that this means
-     * that the poll operation, considered individually, is not
-     * wait-free. One thief cannot successfully continue until another
-     * in-progress one (or, if previously empty, a push) completes.
+     * analysis of memory ordering requirements in work-stealing
+     * algorithms similar to (but different than) the one used here.
+     * Extracting tasks in array slots via (fully fenced) CAS provides
+     * primary synchronization. The base and top indices imprecisely
+     * guide where to extract from. We do not always require strict
+     * orderings of array and index updates, so sometimes let them be
+     * subject to compiler and processor reorderings. However, the
+     * volatile "base" index also serves as a basis for memory
+     * ordering: Slot accesses are preceded by a read of base,
+     * ensuring happens-before ordering with respect to stealers (so
+     * the slots themselves can be read via plain array reads.)  The
+     * only other memory orderings relied on are maintained in the
+     * course of signalling and activation (see below).  A check that
+     * base == top indicates (momentary) emptiness, but otherwise may
+     * err on the side of possibly making the queue appear nonempty
+     * when a push, pop, or poll have not fully committed, or making
+     * it appear empty when an update of top has not yet been visibly
+     * written.  (Method isEmpty() checks the case of a partially
+     * completed removal of the last element.)  Because of this, the
+     * poll operation, considered individually, is not wait-free. One
+     * thief cannot successfully continue until another in-progress
+     * one (or, if previously empty, a push) visibly completes.
      * However, in the aggregate, we ensure at least probabilistic
-     * non-blockingness.  If an attempted steal fails, a thief always
-     * chooses a different random victim target to try next. So, in
-     * order for one thief to progress, it suffices for any
+     * non-blockingness.  If an attempted steal fails, a scanning
+     * thief chooses a different random victim target to try next. So,
+     * in order for one thief to progress, it suffices for any
      * in-progress poll or new push on any empty queue to
      * complete. (This is why we normally use method pollAt and its
      * variants that try once at the apparent base index, else
-     * consider alternative actions, rather than method poll.)
+     * consider alternative actions, rather than method poll, which
+     * retries.)
      *
-     * This approach also enables support of a user mode in which local
-     * task processing is in FIFO, not LIFO order, simply by using
-     * poll rather than pop.  This can be useful in message-passing
-     * frameworks in which tasks are never joined.  However neither
-     * mode considers affinities, loads, cache localities, etc, so
-     * rarely provide the best possible performance on a given
-     * machine, but portably provide good throughput by averaging over
-     * these factors.  (Further, even if we did try to use such
-     * information, we do not usually have a basis for exploiting it.
-     * For example, some sets of tasks profit from cache affinities,
-     * but others are harmed by cache pollution effects.)
+     * This approach also enables support of a user mode in which
+     * local task processing is in FIFO, not LIFO order, simply by
+     * using poll rather than pop.  This can be useful in
+     * message-passing frameworks in which tasks are never joined.
      *
      * WorkQueues are also used in a similar way for tasks submitted
      * to the pool. We cannot mix these tasks in the same queues used
-     * for work-stealing (this would contaminate lifo/fifo
-     * processing). Instead, we randomly associate submission queues
+     * by workers. Instead, we randomly associate submission queues
      * with submitting threads, using a form of hashing.  The
-     * Submitter probe value serves as a hash code for
+     * ThreadLocalRandom probe value serves as a hash code for
      * choosing existing queues, and may be randomly repositioned upon
      * contention with other submitters.  In essence, submitters act
      * like workers except that they are restricted to executing local
-     * tasks that they submitted. However, because most
-     * shared/external queue operations are more expensive than
-     * internal, and because, at steady state, external submitters
-     * will compete for CPU with workers, ForkJoinTask.join and
-     * related methods disable them from repeatedly helping to process
-     * tasks if all workers are active.  Insertion of tasks in shared
-     * mode requires a lock (mainly to protect in the case of
-     * resizing) but we use only a simple spinlock (using bits in
+     * tasks that they submitted (or in the case of CountedCompleters,
+     * others with the same root task).  Insertion of tasks in shared
+     * mode requires a lock but we use only a simple spinlock (using
      * field qlock), because submitters encountering a busy queue move
      * on to try or create other queues -- they block only when
-     * creating and registering new queues.
+     * creating and registering new queues. Because it is used only as
+     * a spinlock, unlocking requires only a "releasing" store (using
+     * putOrderedInt).  The qlock is also used during termination
+     * detection, in which case it is forced to a negative
+     * non-lockable value.
      *
      * Management
      * ==========
      *
      * The main throughput advantages of work-stealing stem from
      * decentralized control -- workers mostly take tasks from
-     * themselves or each other. We cannot negate this in the
-     * implementation of other management responsibilities. The main
-     * tactic for avoiding bottlenecks is packing nearly all
-     * essentially atomic control state into two volatile variables
-     * that are by far most often read (not written) as status and
-     * consistency checks.
+     * themselves or each other, at rates that can exceed a billion
+     * per second.  The pool itself creates, activates (enables
+     * scanning for and running tasks), deactivates, blocks, and
+     * terminates threads, all with minimal central information.
+     * There are only a few properties that we can globally track or
+     * maintain, so we pack them into a small number of variables,
+     * often maintaining atomicity without blocking or locking.
+     * Nearly all essentially atomic control state is held in two
+     * volatile variables that are by far most often read (not
+     * written) as status and consistency checks. (Also, field
+     * "config" holds unchanging configuration state.)
      *
-     * Field "ctl" contains 64 bits holding all the information needed
-     * to atomically decide to add, inactivate, enqueue (on an event
+     * Field "ctl" contains 64 bits holding information needed to
+     * atomically decide to add, inactivate, enqueue (on an event
      * queue), dequeue, and/or re-activate workers.  To enable this
      * packing, we restrict maximum parallelism to (1<<15)-1 (which is
      * far in excess of normal operating range) to allow ids, counts,
      * and their negations (used for thresholding) to fit into 16bit
-     * fields.
+     * subfields.
      *
-     * Field "plock" is a form of sequence lock with a saturating
-     * shutdown bit (similarly for per-queue "qlocks"), mainly
-     * protecting updates to the workQueues array, as well as to
-     * enable shutdown.  When used as a lock, it is normally only very
-     * briefly held, so is nearly always available after at most a
-     * brief spin, but we use a monitor-based backup strategy to
-     * block when needed.
+     * Field "runState" holds lifetime status, atomically and
+     * monotonically setting STARTED, SHUTDOWN, STOP, and finally
+     * TERMINATED bits.
      *
-     * Recording WorkQueues.  WorkQueues are recorded in the
-     * "workQueues" array that is created upon first use and expanded
-     * if necessary.  Updates to the array while recording new workers
-     * and unrecording terminated ones are protected from each other
-     * by a lock but the array is otherwise concurrently readable, and
-     * accessed directly.  To simplify index-based operations, the
-     * array size is always a power of two, and all readers must
-     * tolerate null slots. Worker queues are at odd indices. Shared
-     * (submission) queues are at even indices, up to a maximum of 64
-     * slots, to limit growth even if array needs to expand to add
-     * more workers. Grouping them together in this way simplifies and
+     * Field "auxState" is a ReentrantLock subclass that also
+     * opportunistically holds some other bookkeeping fields accessed
+     * only when locked.  It is mainly used to lock (infrequent)
+     * updates to workQueues.  The auxState instance is itself lazily
+     * constructed (see tryInitialize), requiring a double-check-style
+     * bootstrapping use of field runState, and locking a private
+     * static.
+     *
+     * Field "workQueues" holds references to WorkQueues.  It is
+     * updated (only during worker creation and termination) under the
+     * lock, but is otherwise concurrently readable, and accessed
+     * directly. We also ensure that reads of the array reference
+     * itself never become too stale (for example, re-reading before
+     * each scan). To simplify index-based operations, the array size
+     * is always a power of two, and all readers must tolerate null
+     * slots. Worker queues are at odd indices. Shared (submission)
+     * queues are at even indices, up to a maximum of 64 slots, to
+     * limit growth even if array needs to expand to add more
+     * workers. Grouping them together in this way simplifies and
      * speeds up task scanning.
      *
      * All worker thread creation is on-demand, triggered by task
      * submissions, replacement of terminated workers, and/or
      * compensation for blocked workers. However, all other support
      * code is set up to work with other policies.  To ensure that we
-     * do not hold on to worker references that would prevent GC, ALL
+     * do not hold on to worker references that would prevent GC, all
      * accesses to workQueues are via indices into the workQueues
      * array (which is one source of some of the messy code
      * constructions here). In essence, the workQueues array serves as
-     * a weak reference mechanism. Thus for example the wait queue
-     * field of ctl stores indices, not references.  Access to the
-     * workQueues in associated methods (for example signalWork) must
-     * both index-check and null-check the IDs. All such accesses
-     * ignore bad IDs by returning out early from what they are doing,
-     * since this can only be associated with termination, in which
-     * case it is OK to give up.  All uses of the workQueues array
-     * also check that it is non-null (even if previously
-     * non-null). This allows nulling during termination, which is
-     * currently not necessary, but remains an option for
-     * resource-revocation-based shutdown schemes. It also helps
-     * reduce JIT issuance of uncommon-trap code, which tends to
-     * unnecessarily complicate control flow in some methods.
+     * a weak reference mechanism. Thus for example the stack top
+     * subfield of ctl stores indices, not references.
      *
-     * Event Queuing. Unlike HPC work-stealing frameworks, we cannot
-     * let workers spin indefinitely scanning for tasks when none can
-     * be found immediately, and we cannot start/resume workers unless
-     * there appear to be tasks available.  On the other hand, we must
-     * quickly prod them into action when new tasks are submitted or
-     * generated. In many usages, ramp-up time to activate workers is
-     * the main limiting factor in overall performance (this is
-     * compounded at program start-up by JIT compilation and
-     * allocation). So we try to streamline this as much as possible.
-     * We park/unpark workers after placing in an event wait queue
-     * when they cannot find work. This "queue" is actually a simple
-     * Treiber stack, headed by the "id" field of ctl, plus a 15bit
-     * counter value (that reflects the number of times a worker has
-     * been inactivated) to avoid ABA effects (we need only as many
-     * version numbers as worker threads). Successors are held in
-     * field WorkQueue.nextWait.  Queuing deals with several intrinsic
-     * races, mainly that a task-producing thread can miss seeing (and
-     * signalling) another thread that gave up looking for work but
-     * has not yet entered the wait queue. We solve this by requiring
-     * a full sweep of all workers (via repeated calls to method
-     * scan()) both before and after a newly waiting worker is added
-     * to the wait queue.  Because enqueued workers may actually be
-     * rescanning rather than waiting, we set and clear the "parker"
-     * field of WorkQueues to reduce unnecessary calls to unpark.
-     * (This requires a secondary recheck to avoid missed signals.)
-     * Note the unusual conventions about Thread.interrupts
-     * surrounding parking and other blocking: Because interrupts are
-     * used solely to alert threads to check termination, which is
-     * checked anyway upon blocking, we clear status (using
-     * Thread.interrupted) before any call to park, so that park does
-     * not immediately return due to status being set via some other
-     * unrelated call to interrupt in user code.
+     * Queuing Idle Workers. Unlike HPC work-stealing frameworks, we
+     * cannot let workers spin indefinitely scanning for tasks when
+     * none can be found immediately, and we cannot start/resume
+     * workers unless there appear to be tasks available.  On the
+     * other hand, we must quickly prod them into action when new
+     * tasks are submitted or generated. In many usages, ramp-up time
+     * to activate workers is the main limiting factor in overall
+     * performance, which is compounded at program start-up by JIT
+     * compilation and allocation. So we streamline this as much as
+     * possible.
      *
-     * Signalling.  We create or wake up workers only when there
-     * appears to be at least one task they might be able to find and
-     * execute.  When a submission is added or another worker adds a
-     * task to a queue that has fewer than two tasks, they signal
-     * waiting workers (or trigger creation of new ones if fewer than
-     * the given parallelism level -- signalWork).  These primary
-     * signals are buttressed by others whenever other threads remove
-     * a task from a queue and notice that there are other tasks there
-     * as well.  So in general, pools will be over-signalled. On most
-     * platforms, signalling (unpark) overhead time is noticeably
-     * long, and the time between signalling a thread and it actually
-     * making progress can be very noticeably long, so it is worth
-     * offloading these delays from critical paths as much as
-     * possible. Additionally, workers spin-down gradually, by staying
-     * alive so long as they see the ctl state changing.  Similar
-     * stability-sensing techniques are also used before blocking in
-     * awaitJoin and helpComplete.
+     * The "ctl" field atomically maintains active and total worker
+     * counts as well as a queue to place waiting threads so they can
+     * be located for signalling. Active counts also play the role of
+     * quiescence indicators, so are decremented when workers believe
+     * that there are no more tasks to execute. The "queue" is
+     * actually a form of Treiber stack.  A stack is ideal for
+     * activating threads in most-recently used order. This improves
+     * performance and locality, outweighing the disadvantages of
+     * being prone to contention and inability to release a worker
+     * unless it is topmost on stack.  We block/unblock workers after
+     * pushing on the idle worker stack (represented by the lower
+     * 32bit subfield of ctl) when they cannot find work.  The top
+     * stack state holds the value of the "scanState" field of the
+     * worker: its index and status, plus a version counter that, in
+     * addition to the count subfields (also serving as version
+     * stamps) provide protection against Treiber stack ABA effects.
+     *
+     * Creating workers. To create a worker, we pre-increment total
+     * count (serving as a reservation), and attempt to construct a
+     * ForkJoinWorkerThread via its factory. Upon construction, the
+     * new thread invokes registerWorker, where it constructs a
+     * WorkQueue and is assigned an index in the workQueues array
+     * (expanding the array if necessary). The thread is then started.
+     * Upon any exception across these steps, or null return from
+     * factory, deregisterWorker adjusts counts and records
+     * accordingly.  If a null return, the pool continues running with
+     * fewer than the target number workers. If exceptional, the
+     * exception is propagated, generally to some external caller.
+     * Worker index assignment avoids the bias in scanning that would
+     * occur if entries were sequentially packed starting at the front
+     * of the workQueues array. We treat the array as a simple
+     * power-of-two hash table, expanding as needed. The seedIndex
+     * increment ensures no collisions until a resize is needed or a
+     * worker is deregistered and replaced, and thereafter keeps
+     * probability of collision low. We cannot use
+     * ThreadLocalRandom.getProbe() for similar purposes here because
+     * the thread has not started yet, but do so for creating
+     * submission queues for existing external threads (see
+     * externalPush).
+     *
+     * WorkQueue field scanState is used by both workers and the pool
+     * to manage and track whether a worker is UNSIGNALLED (possibly
+     * blocked waiting for a signal).  When a worker is inactivated,
+     * its scanState field is set, and is prevented from executing
+     * tasks, even though it must scan once for them to avoid queuing
+     * races. Note that scanState updates lag queue CAS releases so
+     * usage requires care. When queued, the lower 16 bits of
+     * scanState must hold its pool index. So we place the index there
+     * upon initialization (see registerWorker) and otherwise keep it
+     * there or restore it when necessary.
+     *
+     * The ctl field also serves as the basis for memory
+     * synchronization surrounding activation. This uses a more
+     * efficient version of a Dekker-like rule that task producers and
+     * consumers sync with each other by both writing/CASing ctl (even
+     * if to its current value).  This would be extremely costly. So
+     * we relax it in several ways: (1) Producers only signal when
+     * their queue is empty. Other workers propagate this signal (in
+     * method scan) when they find tasks. (2) Workers only enqueue
+     * after scanning (see below) and not finding any tasks.  (3)
+     * Rather than CASing ctl to its current value in the common case
+     * where no action is required, we reduce write contention by
+     * equivalently prefacing signalWork when called by an external
+     * task producer using a memory access with full-volatile
+     * semantics or a "fullFence". (4) For internal task producers we
+     * rely on the fact that even if no other workers awaken, the
+     * producer itself will eventually see the task and execute it.
+     *
+     * Almost always, too many signals are issued. A task producer
+     * cannot in general tell if some existing worker is in the midst
+     * of finishing one task (or already scanning) and ready to take
+     * another without being signalled. So the producer might instead
+     * activate a different worker that does not find any work, and
+     * then inactivates. This scarcely matters in steady-state
+     * computations involving all workers, but can create contention
+     * and bookkeeping bottlenecks during ramp-up, ramp-down, and small
+     * computations involving only a few workers.
+     *
+     * Scanning. Method scan() performs top-level scanning for tasks.
+     * Each scan traverses (and tries to poll from) each queue in
+     * pseudorandom permutation order by randomly selecting an origin
+     * index and a step value.  (The pseudorandom generator need not
+     * have high-quality statistical properties in the long term, but
+     * just within computations; We use 64bit and 32bit Marsaglia
+     * XorShifts, which are cheap and suffice here.)  Scanning also
+     * employs contention reduction: When scanning workers fail a CAS
+     * polling for work, they soon restart with a different
+     * pseudorandom scan order (thus likely retrying at different
+     * intervals). This improves throughput when many threads are
+     * trying to take tasks from few queues.  Scans do not otherwise
+     * explicitly take into account core affinities, loads, cache
+     * localities, etc, However, they do exploit temporal locality
+     * (which usually approximates these) by preferring to re-poll (up
+     * to POLL_LIMIT times) from the same queue after a successful
+     * poll before trying others.  Restricted forms of scanning occur
+     * in methods helpComplete and findNonEmptyStealQueue, and take
+     * similar but simpler forms.
+     *
+     * Deactivation and waiting. Queuing encounters several intrinsic
+     * races; most notably that an inactivating scanning worker can
+     * miss seeing a task produced during a scan.  So when a worker
+     * cannot find a task to steal, it inactivates and enqueues, and
+     * then rescans to ensure that it didn't miss one, reactivating
+     * upon seeing one with probability approximately proportional to
+     * probability of a miss.  (In most cases, the worker will be
+     * signalled before self-signalling, avoiding cascades of multiple
+     * signals for the same task).
+     *
+     * Workers block (in method awaitWork) using park/unpark;
+     * advertising the need for signallers to unpark by setting their
+     * "parker" fields.
      *
      * Trimming workers. To release resources after periods of lack of
      * use, a worker starting to wait when the pool is quiescent will
-     * time out and terminate if the pool has remained quiescent for a
-     * given period -- a short period if there are more threads than
-     * parallelism, longer as the number of threads decreases. This
-     * will slowly propagate, eventually terminating all workers after
-     * periods of non-use.
+     * time out and terminate (see awaitWork) if the pool has remained
+     * quiescent for period given by IDLE_TIMEOUT_MS, increasing the
+     * period as the number of threads decreases, eventually removing
+     * all workers.
      *
-     * Shutdown and Termination. A call to shutdownNow atomically sets
-     * a plock bit and then (non-atomically) sets each worker's
-     * qlock status, cancels all unprocessed tasks, and wakes up
-     * all waiting workers.  Detecting whether termination should
-     * commence after a non-abrupt shutdown() call requires more work
-     * and bookkeeping. We need consensus about quiescence (i.e., that
-     * there is no more work). The active count provides a primary
-     * indication but non-abrupt shutdown still requires a rechecking
-     * scan for any workers that are inactive but not queued.
+     * Shutdown and Termination. A call to shutdownNow invokes
+     * tryTerminate to atomically set a runState bit. The calling
+     * thread, as well as every other worker thereafter terminating,
+     * helps terminate others by setting their (qlock) status,
+     * cancelling their unprocessed tasks, and waking them up, doing
+     * so repeatedly until stable. Calls to non-abrupt shutdown()
+     * preface this by checking whether termination should commence.
+     * This relies primarily on the active count bits of "ctl"
+     * maintaining consensus -- tryTerminate is called from awaitWork
+     * whenever quiescent. However, external submitters do not take
+     * part in this consensus.  So, tryTerminate sweeps through queues
+     * (until stable) to ensure lack of in-flight submissions and
+     * workers about to process them before triggering the "STOP"
+     * phase of termination. (Note: there is an intrinsic conflict if
+     * helpQuiescePool is called when shutdown is enabled. Both wait
+     * for quiescence, but tryTerminate is biased to not trigger until
+     * helpQuiescePool completes.)
      *
      * Joining Tasks
      * =============
@@ -357,9 +482,9 @@
      * just let them block (as in Thread.join).  We also cannot just
      * reassign the joiner's run-time stack with another and replace
      * it later, which would be a form of "continuation", that even if
-     * possible is not necessarily a good idea since we sometimes need
-     * both an unblocked task and its continuation to progress.
-     * Instead we combine two tactics:
+     * possible is not necessarily a good idea since we may need both
+     * an unblocked task and its continuation to progress.  Instead we
+     * combine two tactics:
      *
      *   Helping: Arranging for the joiner to execute some task that it
      *      would be running if the steal had not occurred.
@@ -379,16 +504,16 @@
      * The ManagedBlocker extension API can't use helping so relies
      * only on compensation in method awaitBlocker.
      *
-     * The algorithm in tryHelpStealer entails a form of "linear"
-     * helping: Each worker records (in field currentSteal) the most
-     * recent task it stole from some other worker. Plus, it records
-     * (in field currentJoin) the task it is currently actively
-     * joining. Method tryHelpStealer uses these markers to try to
-     * find a worker to help (i.e., steal back a task from and execute
-     * it) that could hasten completion of the actively joined task.
-     * In essence, the joiner executes a task that would be on its own
-     * local deque had the to-be-joined task not been stolen. This may
-     * be seen as a conservative variant of the approach in Wagner &
+     * The algorithm in helpStealer entails a form of "linear
+     * helping".  Each worker records (in field currentSteal) the most
+     * recent task it stole from some other worker (or a submission).
+     * It also records (in field currentJoin) the task it is currently
+     * actively joining. Method helpStealer uses these markers to try
+     * to find a worker to help (i.e., steal back a task from and
+     * execute it) that could hasten completion of the actively joined
+     * task.  Thus, the joiner executes a task that would be on its
+     * own local deque had the to-be-joined task not been stolen. This
+     * is a conservative variant of the approach described in Wagner &
      * Calder "Leapfrogging: a portable technique for implementing
      * efficient futures" SIGPLAN Notices, 1993
      * (http://portal.acm.org/citation.cfm?id=155354). It differs in
@@ -406,31 +531,45 @@
      * which means that we miss links in the chain during long-lived
      * tasks, GC stalls etc (which is OK since blocking in such cases
      * is usually a good idea).  (4) We bound the number of attempts
-     * to find work (see MAX_HELP) and fall back to suspending the
+     * to find work using checksums and fall back to suspending the
      * worker and if necessary replacing it with another.
      *
-     * It is impossible to keep exactly the target parallelism number
-     * of threads running at any given time.  Determining the
-     * existence of conservatively safe helping targets, the
-     * availability of already-created spares, and the apparent need
-     * to create new spares are all racy, so we rely on multiple
-     * retries of each.  Compensation in the apparent absence of
-     * helping opportunities is challenging to control on JVMs, where
-     * GC and other activities can stall progress of tasks that in
-     * turn stall out many other dependent tasks, without us being
-     * able to determine whether they will ever require compensation.
-     * Even though work-stealing otherwise encounters little
-     * degradation in the presence of more threads than cores,
-     * aggressively adding new threads in such cases entails risk of
-     * unwanted positive feedback control loops in which more threads
-     * cause more dependent stalls (as well as delayed progress of
-     * unblocked threads to the point that we know they are available)
-     * leading to more situations requiring more threads, and so
-     * on. This aspect of control can be seen as an (analytically
-     * intractable) game with an opponent that may choose the worst
-     * (for us) active thread to stall at any time.  We take several
-     * precautions to bound losses (and thus bound gains), mainly in
-     * methods tryCompensate and awaitJoin.
+     * Helping actions for CountedCompleters do not require tracking
+     * currentJoins: Method helpComplete takes and executes any task
+     * with the same root as the task being waited on (preferring
+     * local pops to non-local polls). However, this still entails
+     * some traversal of completer chains, so is less efficient than
+     * using CountedCompleters without explicit joins.
+     *
+     * Compensation does not aim to keep exactly the target
+     * parallelism number of unblocked threads running at any given
+     * time. Some previous versions of this class employed immediate
+     * compensations for any blocked join. However, in practice, the
+     * vast majority of blockages are transient byproducts of GC and
+     * other JVM or OS activities that are made worse by replacement.
+     * Currently, compensation is attempted only after validating that
+     * all purportedly active threads are processing tasks by checking
+     * field WorkQueue.scanState, which eliminates most false
+     * positives.  Also, compensation is bypassed (tolerating fewer
+     * threads) in the most common case in which it is rarely
+     * beneficial: when a worker with an empty queue (thus no
+     * continuation tasks) blocks on a join and there still remain
+     * enough threads to ensure liveness.
+     *
+     * Spare threads are removed as soon as they notice that the
+     * target parallelism level has been exceeded, in method
+     * tryDropSpare. (Method scan arranges returns for rechecks upon
+     * each probe via the "bound" parameter.)
+     *
+     * The compensation mechanism may be bounded.  Bounds for the
+     * commonPool (see COMMON_MAX_SPARES) better enable JVMs to cope
+     * with programming errors and abuse before running out of
+     * resources to do so. In other cases, users may supply factories
+     * that limit thread construction. The effects of bounding in this
+     * pool (like all others) is imprecise.  Total worker counts are
+     * decremented when threads deregister, not when they exit and
+     * resources are reclaimed by the JVM and OS. So the number of
+     * simultaneously live threads may transiently exceed bounds.
      *
      * Common Pool
      * ===========
@@ -440,24 +579,52 @@
      * never be used, we minimize initial construction overhead and
      * footprint to the setup of about a dozen fields, with no nested
      * allocation. Most bootstrapping occurs within method
-     * fullExternalPush during the first submission to the pool.
+     * externalSubmit during the first submission to the pool.
      *
      * When external threads submit to the common pool, they can
-     * perform subtask processing (see externalHelpJoin and related
-     * methods).  This caller-helps policy makes it sensible to set
-     * common pool parallelism level to one (or more) less than the
-     * total number of available cores, or even zero for pure
-     * caller-runs.  We do not need to record whether external
-     * submissions are to the common pool -- if not, externalHelpJoin
-     * returns quickly (at the most helping to signal some common pool
-     * workers). These submitters would otherwise be blocked waiting
-     * for completion, so the extra effort (with liberally sprinkled
-     * task status checks) in inapplicable cases amounts to an odd
-     * form of limited spin-wait before blocking in ForkJoinTask.join.
+     * perform subtask processing (see externalHelpComplete and
+     * related methods) upon joins.  This caller-helps policy makes it
+     * sensible to set common pool parallelism level to one (or more)
+     * less than the total number of available cores, or even zero for
+     * pure caller-runs.  We do not need to record whether external
+     * submissions are to the common pool -- if not, external help
+     * methods return quickly. These submitters would otherwise be
+     * blocked waiting for completion, so the extra effort (with
+     * liberally sprinkled task status checks) in inapplicable cases
+     * amounts to an odd form of limited spin-wait before blocking in
+     * ForkJoinTask.join.
+     *
+     * As a more appropriate default in managed environments, unless
+     * overridden by system properties, we use workers of subclass
+     * InnocuousForkJoinWorkerThread when there is a SecurityManager
+     * present. These workers have no permissions set, do not belong
+     * to any user-defined ThreadGroup, and erase all ThreadLocals
+     * after executing any top-level task (see WorkQueue.runTask).
+     * The associated mechanics (mainly in ForkJoinWorkerThread) may
+     * be JVM-dependent and must access particular Thread class fields
+     * to achieve this effect.
      *
      * Style notes
      * ===========
      *
+     * Memory ordering relies mainly on Unsafe intrinsics that carry
+     * the further responsibility of explicitly performing null- and
+     * bounds- checks otherwise carried out implicitly by JVMs.  This
+     * can be awkward and ugly, but also reflects the need to control
+     * outcomes across the unusual cases that arise in very racy code
+     * with very few invariants. So these explicit checks would exist
+     * in some form anyway.  All fields are read into locals before
+     * use, and null-checked if they are references.  This is usually
+     * done in a "C"-like style of listing declarations at the heads
+     * of methods or blocks, and using inline assignments on first
+     * encounter.  Array bounds-checks are usually performed by
+     * masking with array.length-1, which relies on the invariant that
+     * these arrays are created with positive lengths, which is itself
+     * paranoically checked. Nearly all explicit checks lead to
+     * bypass/return, not exception throws, because they may
+     * legitimately arise due to cancellation/revocation during
+     * shutdown.
+     *
      * There is a lot of representation-level coupling among classes
      * ForkJoinPool, ForkJoinWorkerThread, and ForkJoinTask.  The
      * fields of WorkQueue maintain data structures managed by
@@ -465,22 +632,13 @@
      * trying to reduce this, since any associated future changes in
      * representations will need to be accompanied by algorithmic
      * changes anyway. Several methods intrinsically sprawl because
-     * they must accumulate sets of consistent reads of volatiles held
-     * in local variables.  Methods signalWork() and scan() are the
-     * main bottlenecks, so are especially heavily
-     * micro-optimized/mangled.  There are lots of inline assignments
-     * (of form "while ((local = field) != 0)") which are usually the
-     * simplest way to ensure the required read orderings (which are
-     * sometimes critical). This leads to a "C"-like style of listing
-     * declarations of these locals at the heads of methods or blocks.
-     * There are several occurrences of the unusual "do {} while
-     * (!cas...)"  which is the simplest way to force an update of a
-     * CAS'ed variable. There are also other coding oddities (including
-     * several unnecessary-looking hoisted null checks) that help
-     * some methods perform reasonably even when interpreted (not
-     * compiled).
+     * they must accumulate sets of consistent reads of fields held in
+     * local variables.  There are also other coding oddities
+     * (including several unnecessary-looking hoisted null checks)
+     * that help some methods perform reasonably even when interpreted
+     * (not compiled).
      *
-     * The order of declarations in this file is:
+     * The order of declarations in this file is (with a few exceptions):
      * (1) Static utility functions
      * (2) Nested (static) classes
      * (3) Static fields
@@ -490,7 +648,6 @@
      * (7) Exported methods
      * (8) Static block initializing statics in minimally dependent order
      */
-    // android-note: Removed references to CountedCompleters.
 
     // Static utilities
 
@@ -517,7 +674,8 @@
          * Returns a new worker thread operating in the given pool.
          *
          * @param pool the pool this thread works in
-         * @return the new worker thread
+         * @return the new worker thread, or {@code null} if the request
+         *         to create a thread is rejected
          * @throws NullPointerException if the pool is null
          */
         public ForkJoinWorkerThread newThread(ForkJoinPool pool);
@@ -527,7 +685,7 @@
      * Default ForkJoinWorkerThreadFactory implementation; creates a
      * new ForkJoinWorkerThread.
      */
-    static final class DefaultForkJoinWorkerThreadFactory
+    private static final class DefaultForkJoinWorkerThreadFactory
         implements ForkJoinWorkerThreadFactory {
         public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
             return new ForkJoinWorkerThread(pool);
@@ -540,7 +698,7 @@
      * in WorkQueue.tryRemoveAndExec. We don't need the proxy to
      * actually do anything beyond having a unique identity.
      */
-    static final class EmptyTask extends ForkJoinTask<Void> {
+    private static final class EmptyTask extends ForkJoinTask<Void> {
         private static final long serialVersionUID = -7721805057305804111L;
         EmptyTask() { status = ForkJoinTask.NORMAL; } // force done
         public final Void getRawResult() { return null; }
@@ -549,54 +707,54 @@
     }
 
     /**
+     * Additional fields and lock created upon initialization.
+     */
+    private static final class AuxState extends ReentrantLock {
+        private static final long serialVersionUID = -6001602636862214147L;
+        volatile long stealCount;     // cumulative steal count
+        long indexSeed;               // index bits for registerWorker
+        AuxState() {}
+    }
+
+    // Constants shared across ForkJoinPool and WorkQueue
+
+    // Bounds
+    static final int SMASK        = 0xffff;        // short bits == max index
+    static final int MAX_CAP      = 0x7fff;        // max #workers - 1
+    static final int EVENMASK     = 0xfffe;        // even short bits
+    static final int SQMASK       = 0x007e;        // max 64 (even) slots
+
+    // Masks and units for WorkQueue.scanState and ctl sp subfield
+    static final int UNSIGNALLED  = 1 << 31;       // must be negative
+    static final int SS_SEQ       = 1 << 16;       // version count
+
+    // Mode bits for ForkJoinPool.config and WorkQueue.config
+    static final int MODE_MASK    = 0xffff << 16;  // top half of int
+    static final int SPARE_WORKER = 1 << 17;       // set if tc > 0 on creation
+    static final int UNREGISTERED = 1 << 18;       // to skip some of deregister
+    static final int FIFO_QUEUE   = 1 << 31;       // must be negative
+    static final int LIFO_QUEUE   = 0;             // for clarity
+    static final int IS_OWNED     = 1;             // low bit 0 if shared
+
+    /**
+     * The maximum number of task executions from the same queue
+     * before checking other queues, bounding unfairness and impact of
+     * infinite user task recursion.  Must be a power of two minus 1.
+     */
+    static final int POLL_LIMIT = (1 << 10) - 1;
+
+    /**
      * Queues supporting work-stealing as well as external task
-     * submission. See above for main rationale and algorithms.
-     * Implementation relies heavily on "Unsafe" intrinsics
-     * and selective use of "volatile":
-     *
-     * Field "base" is the index (mod array.length) of the least valid
-     * queue slot, which is always the next position to steal (poll)
-     * from if nonempty. Reads and writes require volatile orderings
-     * but not CAS, because updates are only performed after slot
-     * CASes.
-     *
-     * Field "top" is the index (mod array.length) of the next queue
-     * slot to push to or pop from. It is written only by owner thread
-     * for push, or under lock for external/shared push, and accessed
-     * by other threads only after reading (volatile) base.  Both top
-     * and base are allowed to wrap around on overflow, but (top -
-     * base) (or more commonly -(base - top) to force volatile read of
-     * base before top) still estimates size. The lock ("qlock") is
-     * forced to -1 on termination, causing all further lock attempts
-     * to fail. (Note: we don't need CAS for termination state because
-     * upon pool shutdown, all shared-queues will stop being used
-     * anyway.)  Nearly all lock bodies are set up so that exceptions
-     * within lock bodies are "impossible" (modulo JVM errors that
-     * would cause failure anyway.)
-     *
-     * The array slots are read and written using the emulation of
-     * volatiles/atomics provided by Unsafe. Insertions must in
-     * general use putOrderedObject as a form of releasing store to
-     * ensure that all writes to the task object are ordered before
-     * its publication in the queue.  All removals entail a CAS to
-     * null.  The array is always a power of two. To ensure safety of
-     * Unsafe array operations, all accesses perform explicit null
-     * checks and implicit bounds checks via power-of-two masking.
-     *
-     * In addition to basic queuing support, this class contains
-     * fields described elsewhere to control execution. It turns out
-     * to work better memory-layout-wise to include them in this class
-     * rather than a separate class.
-     *
+     * submission. See above for descriptions and algorithms.
      * Performance on most platforms is very sensitive to placement of
      * instances of both WorkQueues and their arrays -- we absolutely
      * do not want multiple WorkQueue instances or multiple queue
-     * arrays sharing cache lines. (It would be best for queue objects
-     * and their arrays to share, but there is nothing available to
-     * help arrange that). The @Contended annotation alerts JVMs to
-     * try to keep instances apart.
+     * arrays sharing cache lines. The @Contended annotation alerts
+     * JVMs to try to keep instances apart.
      */
+    //@jdk.internal.vm.annotation.Contended   // android-removed
     static final class WorkQueue {
+
         /**
          * Capacity of work-stealing queue array upon initialization.
          * Must be a power of two; at least 4, but should be larger to
@@ -617,43 +775,44 @@
          */
         static final int MAXIMUM_QUEUE_CAPACITY = 1 << 26; // 64M
 
-        // Heuristic padding to ameliorate unfortunate memory placements
-        volatile long pad00, pad01, pad02, pad03, pad04, pad05, pad06;
+        // Instance fields
 
-        volatile int eventCount;   // encoded inactivation count; < 0 if inactive
-        int nextWait;              // encoded record of next event waiter
+        volatile int scanState;    // versioned, negative if inactive
+        int stackPred;             // pool stack (ctl) predecessor
         int nsteals;               // number of steals
-        int hint;                  // steal index hint
-        short poolIndex;           // index of this queue in pool
-        final short mode;          // 0: lifo, > 0: fifo, < 0: shared
-        volatile int qlock;        // 1: locked, -1: terminate; else 0
+        int hint;                  // randomization and stealer index hint
+        int config;                // pool index and mode
+        volatile int qlock;        // 1: locked, < 0: terminate; else 0
         volatile int base;         // index of next slot for poll
         int top;                   // index of next slot for push
         ForkJoinTask<?>[] array;   // the elements (initially unallocated)
         final ForkJoinPool pool;   // the containing pool (may be null)
         final ForkJoinWorkerThread owner; // owning thread or null if shared
         volatile Thread parker;    // == owner during call to park; else null
-        volatile ForkJoinTask<?> currentJoin;  // task being joined in awaitJoin
-        ForkJoinTask<?> currentSteal; // current non-local task being executed
+        volatile ForkJoinTask<?> currentJoin; // task being joined in awaitJoin
 
-        volatile Object pad10, pad11, pad12, pad13, pad14, pad15, pad16, pad17;
-        volatile Object pad18, pad19, pad1a, pad1b, pad1c, pad1d;
+      // @jdk.internal.vm.annotation.Contended("group2") // segregate // android-removed
+        volatile ForkJoinTask<?> currentSteal; // nonnull when running some task
 
-        WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner, int mode,
-                  int seed) {
+        WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner) {
             this.pool = pool;
             this.owner = owner;
-            this.mode = (short)mode;
-            this.hint = seed; // store initial seed for runWorker
             // Place indices in the center of array (that is not yet allocated)
             base = top = INITIAL_QUEUE_CAPACITY >>> 1;
         }
 
         /**
+         * Returns an exportable index (used by ForkJoinWorkerThread).
+         */
+        final int getPoolIndex() {
+            return (config & 0xffff) >>> 1; // ignore odd/even tag bit
+        }
+
+        /**
          * Returns the approximate number of tasks in the queue.
          */
         final int queueSize() {
-            int n = base - top;       // non-owner callers must read base first
+            int n = base - top;       // read base first
             return (n >= 0) ? 0 : -n; // ignore transient negative
         }
 
@@ -663,32 +822,31 @@
          * near-empty queue has at least one unclaimed task.
          */
         final boolean isEmpty() {
-            ForkJoinTask<?>[] a; int m, s;
-            int n = base - (s = top);
-            return (n >= 0 ||
-                    (n == -1 &&
-                     ((a = array) == null ||
-                      (m = a.length - 1) < 0 ||
-                      U.getObject
-                      (a, (long)((m & (s - 1)) << ASHIFT) + ABASE) == null)));
+            ForkJoinTask<?>[] a; int n, al, s;
+            return ((n = base - (s = top)) >= 0 || // possibly one task
+                    (n == -1 && ((a = array) == null ||
+                                 (al = a.length) == 0 ||
+                                 a[(al - 1) & (s - 1)] == null)));
         }
 
         /**
-         * Pushes a task. Call only by owner in unshared queues.  (The
-         * shared-queue version is embedded in method externalPush.)
+         * Pushes a task. Call only by owner in unshared queues.
          *
          * @param task the task. Caller must ensure non-null.
          * @throws RejectedExecutionException if array cannot be resized
          */
         final void push(ForkJoinTask<?> task) {
-            ForkJoinTask<?>[] a; ForkJoinPool p;
-            int s = top, n;
-            if ((a = array) != null) {    // ignore if queue removed
-                int m = a.length - 1;
-                U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task);
-                if ((n = (top = s + 1) - base) <= 2)
-                    (p = pool).signalWork(p.workQueues, this);
-                else if (n >= m)
+            U.storeFence();              // ensure safe publication
+            int s = top, al, d; ForkJoinTask<?>[] a;
+            if ((a = array) != null && (al = a.length) > 0) {
+                a[(al - 1) & s] = task;  // relaxed writes OK
+                top = s + 1;
+                ForkJoinPool p = pool;
+                if ((d = base - s) == 0 && p != null) {
+                    U.fullFence();
+                    p.signalWork();
+                }
+                else if (al + d == 1)
                     growArray();
             }
         }
@@ -701,22 +859,23 @@
         final ForkJoinTask<?>[] growArray() {
             ForkJoinTask<?>[] oldA = array;
             int size = oldA != null ? oldA.length << 1 : INITIAL_QUEUE_CAPACITY;
-            if (size > MAXIMUM_QUEUE_CAPACITY)
+            if (size < INITIAL_QUEUE_CAPACITY || size > MAXIMUM_QUEUE_CAPACITY)
                 throw new RejectedExecutionException("Queue capacity exceeded");
             int oldMask, t, b;
             ForkJoinTask<?>[] a = array = new ForkJoinTask<?>[size];
-            if (oldA != null && (oldMask = oldA.length - 1) >= 0 &&
+            if (oldA != null && (oldMask = oldA.length - 1) > 0 &&
                 (t = top) - (b = base) > 0) {
                 int mask = size - 1;
-                do {
-                    ForkJoinTask<?> x;
-                    int oldj = ((b & oldMask) << ASHIFT) + ABASE;
-                    int j    = ((b &    mask) << ASHIFT) + ABASE;
-                    x = (ForkJoinTask<?>)U.getObjectVolatile(oldA, oldj);
+                do { // emulate poll from old array, push to new array
+                    int index = b & oldMask;
+                    long offset = ((long)index << ASHIFT) + ABASE;
+                    ForkJoinTask<?> x = (ForkJoinTask<?>)
+                        U.getObjectVolatile(oldA, offset);
                     if (x != null &&
-                        U.compareAndSwapObject(oldA, oldj, x, null))
-                        U.putObjectVolatile(a, j, x);
+                        U.compareAndSwapObject(oldA, offset, x, null))
+                        a[b & mask] = x;
                 } while (++b != t);
+                U.storeFence();
             }
             return a;
         }
@@ -726,16 +885,16 @@
          * by owner in unshared queues.
          */
         final ForkJoinTask<?> pop() {
-            ForkJoinTask<?>[] a; ForkJoinTask<?> t; int m;
-            if ((a = array) != null && (m = a.length - 1) >= 0) {
-                for (int s; (s = top - 1) - base >= 0;) {
-                    long j = ((m & s) << ASHIFT) + ABASE;
-                    if ((t = (ForkJoinTask<?>)U.getObject(a, j)) == null)
-                        break;
-                    if (U.compareAndSwapObject(a, j, t, null)) {
-                        top = s;
-                        return t;
-                    }
+            int b = base, s = top, al, i; ForkJoinTask<?>[] a;
+            if ((a = array) != null && b != s && (al = a.length) > 0) {
+                int index = (al - 1) & --s;
+                long offset = ((long)index << ASHIFT) + ABASE;
+                ForkJoinTask<?> t = (ForkJoinTask<?>)
+                    U.getObject(a, offset);
+                if (t != null &&
+                    U.compareAndSwapObject(a, offset, t, null)) {
+                    top = s;
+                    return t;
                 }
             }
             return null;
@@ -744,15 +903,18 @@
         /**
          * Takes a task in FIFO order if b is base of queue and a task
          * can be claimed without contention. Specialized versions
-         * appear in ForkJoinPool methods scan and tryHelpStealer.
+         * appear in ForkJoinPool methods scan and helpStealer.
          */
         final ForkJoinTask<?> pollAt(int b) {
-            ForkJoinTask<?> t; ForkJoinTask<?>[] a;
-            if ((a = array) != null) {
-                int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
-                if ((t = (ForkJoinTask<?>)U.getObjectVolatile(a, j)) != null &&
-                    base == b && U.compareAndSwapObject(a, j, t, null)) {
-                    U.putOrderedInt(this, QBASE, b + 1);
+            ForkJoinTask<?>[] a; int al;
+            if ((a = array) != null && (al = a.length) > 0) {
+                int index = (al - 1) & b;
+                long offset = ((long)index << ASHIFT) + ABASE;
+                ForkJoinTask<?> t = (ForkJoinTask<?>)
+                    U.getObjectVolatile(a, offset);
+                if (t != null && b++ == base &&
+                    U.compareAndSwapObject(a, offset, t, null)) {
+                    base = b;
                     return t;
                 }
             }
@@ -763,21 +925,27 @@
          * Takes next task, if one exists, in FIFO order.
          */
         final ForkJoinTask<?> poll() {
-            ForkJoinTask<?>[] a; int b; ForkJoinTask<?> t;
-            while ((b = base) - top < 0 && (a = array) != null) {
-                int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
-                t = (ForkJoinTask<?>)U.getObjectVolatile(a, j);
-                if (t != null) {
-                    if (U.compareAndSwapObject(a, j, t, null)) {
-                        U.putOrderedInt(this, QBASE, b + 1);
-                        return t;
+            for (;;) {
+                int b = base, s = top, d, al; ForkJoinTask<?>[] a;
+                if ((a = array) != null && (d = b - s) < 0 &&
+                    (al = a.length) > 0) {
+                    int index = (al - 1) & b;
+                    long offset = ((long)index << ASHIFT) + ABASE;
+                    ForkJoinTask<?> t = (ForkJoinTask<?>)
+                        U.getObjectVolatile(a, offset);
+                    if (b++ == base) {
+                        if (t != null) {
+                            if (U.compareAndSwapObject(a, offset, t, null)) {
+                                base = b;
+                                return t;
+                            }
+                        }
+                        else if (d == -1)
+                            break; // now empty
                     }
                 }
-                else if (base == b) {
-                    if (b + 1 == top)
-                        break;
-                    Thread.yield(); // wait for lagging update (very rare)
-                }
+                else
+                    break;
             }
             return null;
         }
@@ -786,218 +954,350 @@
          * Takes next task, if one exists, in order specified by mode.
          */
         final ForkJoinTask<?> nextLocalTask() {
-            return mode == 0 ? pop() : poll();
+            return (config < 0) ? poll() : pop();
         }
 
         /**
          * Returns next task, if one exists, in order specified by mode.
          */
         final ForkJoinTask<?> peek() {
-            ForkJoinTask<?>[] a = array; int m;
-            if (a == null || (m = a.length - 1) < 0)
-                return null;
-            int i = mode == 0 ? top - 1 : base;
-            int j = ((i & m) << ASHIFT) + ABASE;
-            return (ForkJoinTask<?>)U.getObjectVolatile(a, j);
+            int al; ForkJoinTask<?>[] a;
+            return ((a = array) != null && (al = a.length) > 0) ?
+                a[(al - 1) & (config < 0 ? base : top - 1)] : null;
         }
 
         /**
          * Pops the given task only if it is at the current top.
-         * (A shared version is available only via FJP.tryExternalUnpush)
          */
-        final boolean tryUnpush(ForkJoinTask<?> t) {
-            ForkJoinTask<?>[] a; int s;
-            if ((a = array) != null && (s = top) != base &&
-                U.compareAndSwapObject
-                (a, (((a.length - 1) & --s) << ASHIFT) + ABASE, t, null)) {
-                top = s;
-                return true;
+        final boolean tryUnpush(ForkJoinTask<?> task) {
+            int b = base, s = top, al; ForkJoinTask<?>[] a;
+            if ((a = array) != null && b != s && (al = a.length) > 0) {
+                int index = (al - 1) & --s;
+                long offset = ((long)index << ASHIFT) + ABASE;
+                if (U.compareAndSwapObject(a, offset, task, null)) {
+                    top = s;
+                    return true;
+                }
             }
             return false;
         }
 
         /**
+         * Shared version of push. Fails if already locked.
+         *
+         * @return status: > 0 locked, 0 possibly was empty, < 0 was nonempty
+         */
+        final int sharedPush(ForkJoinTask<?> task) {
+            int stat;
+            if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
+                int b = base, s = top, al, d; ForkJoinTask<?>[] a;
+                if ((a = array) != null && (al = a.length) > 0 &&
+                    al - 1 + (d = b - s) > 0) {
+                    a[(al - 1) & s] = task;
+                    top = s + 1;                 // relaxed writes OK here
+                    qlock = 0;
+                    stat = (d < 0 && b == base) ? d : 0;
+                }
+                else {
+                    growAndSharedPush(task);
+                    stat = 0;
+                }
+            }
+            else
+                stat = 1;
+            return stat;
+        }
+
+        /**
+         * Helper for sharedPush; called only when locked and resize
+         * needed.
+         */
+        private void growAndSharedPush(ForkJoinTask<?> task) {
+            try {
+                growArray();
+                int s = top, al; ForkJoinTask<?>[] a;
+                if ((a = array) != null && (al = a.length) > 0) {
+                    a[(al - 1) & s] = task;
+                    top = s + 1;
+                }
+            } finally {
+                qlock = 0;
+            }
+        }
+
+        /**
+         * Shared version of tryUnpush.
+         */
+        final boolean trySharedUnpush(ForkJoinTask<?> task) {
+            boolean popped = false;
+            int s = top - 1, al; ForkJoinTask<?>[] a;
+            if ((a = array) != null && (al = a.length) > 0) {
+                int index = (al - 1) & s;
+                long offset = ((long)index << ASHIFT) + ABASE;
+                ForkJoinTask<?> t = (ForkJoinTask<?>) U.getObject(a, offset);
+                if (t == task &&
+                    U.compareAndSwapInt(this, QLOCK, 0, 1)) {
+                    if (top == s + 1 && array == a &&
+                        U.compareAndSwapObject(a, offset, task, null)) {
+                        popped = true;
+                        top = s;
+                    }
+                    U.putOrderedInt(this, QLOCK, 0);
+                }
+            }
+            return popped;
+        }
+
+        /**
          * Removes and cancels all known tasks, ignoring any exceptions.
          */
         final void cancelAll() {
-            ForkJoinTask.cancelIgnoringExceptions(currentJoin);
-            ForkJoinTask.cancelIgnoringExceptions(currentSteal);
-            for (ForkJoinTask<?> t; (t = poll()) != null; )
+            ForkJoinTask<?> t;
+            if ((t = currentJoin) != null) {
+                currentJoin = null;
+                ForkJoinTask.cancelIgnoringExceptions(t);
+            }
+            if ((t = currentSteal) != null) {
+                currentSteal = null;
+                ForkJoinTask.cancelIgnoringExceptions(t);
+            }
+            while ((t = poll()) != null)
                 ForkJoinTask.cancelIgnoringExceptions(t);
         }
 
         // Specialized execution methods
 
         /**
-         * Polls and runs tasks until empty.
+         * Pops and executes up to POLL_LIMIT tasks or until empty.
          */
-        final void pollAndExecAll() {
-            for (ForkJoinTask<?> t; (t = poll()) != null;)
-                t.doExec();
+        final void localPopAndExec() {
+            for (int nexec = 0;;) {
+                int b = base, s = top, al; ForkJoinTask<?>[] a;
+                if ((a = array) != null && b != s && (al = a.length) > 0) {
+                    int index = (al - 1) & --s;
+                    long offset = ((long)index << ASHIFT) + ABASE;
+                    ForkJoinTask<?> t = (ForkJoinTask<?>)
+                        U.getAndSetObject(a, offset, null);
+                    if (t != null) {
+                        top = s;
+                        (currentSteal = t).doExec();
+                        if (++nexec > POLL_LIMIT)
+                            break;
+                    }
+                    else
+                        break;
+                }
+                else
+                    break;
+            }
         }
 
         /**
-         * Executes a top-level task and any local tasks remaining
-         * after execution.
+         * Polls and executes up to POLL_LIMIT tasks or until empty.
+         */
+        final void localPollAndExec() {
+            for (int nexec = 0;;) {
+                int b = base, s = top, al; ForkJoinTask<?>[] a;
+                if ((a = array) != null && b != s && (al = a.length) > 0) {
+                    int index = (al - 1) & b++;
+                    long offset = ((long)index << ASHIFT) + ABASE;
+                    ForkJoinTask<?> t = (ForkJoinTask<?>)
+                        U.getAndSetObject(a, offset, null);
+                    if (t != null) {
+                        base = b;
+                        t.doExec();
+                        if (++nexec > POLL_LIMIT)
+                            break;
+                    }
+                }
+                else
+                    break;
+            }
+        }
+
+        /**
+         * Executes the given task and (some) remaining local tasks.
          */
         final void runTask(ForkJoinTask<?> task) {
-            if ((currentSteal = task) != null) {
+            if (task != null) {
                 task.doExec();
-                ForkJoinTask<?>[] a = array;
-                int md = mode;
-                ++nsteals;
+                if (config < 0)
+                    localPollAndExec();
+                else
+                    localPopAndExec();
+                int ns = ++nsteals;
+                ForkJoinWorkerThread thread = owner;
                 currentSteal = null;
-                if (md != 0)
-                    pollAndExecAll();
-                else if (a != null) {
-                    int s, m = a.length - 1;
-                    while ((s = top - 1) - base >= 0) {
-                        long i = ((m & s) << ASHIFT) + ABASE;
-                        ForkJoinTask<?> t = (ForkJoinTask<?>)U.getObject(a, i);
-                        if (t == null)
-                            break;
-                        if (U.compareAndSwapObject(a, i, t, null)) {
-                            top = s;
-                            t.doExec();
-                        }
-                    }
+                if (ns < 0)           // collect on overflow
+                    transferStealCount(pool);
+                if (thread != null)
+                    thread.afterTopLevelExec();
+            }
+        }
+
+        /**
+         * Adds steal count to pool steal count if it exists, and resets.
+         */
+        final void transferStealCount(ForkJoinPool p) {
+            AuxState aux;
+            if (p != null && (aux = p.auxState) != null) {
+                long s = nsteals;
+                nsteals = 0;            // if negative, correct for overflow
+                if (s < 0) s = Integer.MAX_VALUE;
+                aux.lock();
+                try {
+                    aux.stealCount += s;
+                } finally {
+                    aux.unlock();
                 }
             }
         }
 
         /**
          * If present, removes from queue and executes the given task,
-         * or any other cancelled task. Returns (true) on any CAS
-         * or consistency check failure so caller can retry.
+         * or any other cancelled task. Used only by awaitJoin.
          *
-         * @return false if no progress can be made, else true
+         * @return true if queue empty and task not known to be done
          */
         final boolean tryRemoveAndExec(ForkJoinTask<?> task) {
-            boolean stat;
-            ForkJoinTask<?>[] a; int m, s, b, n;
-            if (task != null && (a = array) != null && (m = a.length - 1) >= 0 &&
-                (n = (s = top) - (b = base)) > 0) {
-                boolean removed = false, empty = true;
-                stat = true;
-                for (ForkJoinTask<?> t;;) {           // traverse from s to b
-                    long j = ((--s & m) << ASHIFT) + ABASE;
-                    t = (ForkJoinTask<?>)U.getObject(a, j);
-                    if (t == null)                    // inconsistent length
-                        break;
-                    else if (t == task) {
-                        if (s + 1 == top) {           // pop
-                            if (!U.compareAndSwapObject(a, j, task, null))
-                                break;
-                            top = s;
-                            removed = true;
+            if (task != null && task.status >= 0) {
+                int b, s, d, al; ForkJoinTask<?>[] a;
+                while ((d = (b = base) - (s = top)) < 0 &&
+                       (a = array) != null && (al = a.length) > 0) {
+                    for (;;) {      // traverse from s to b
+                        int index = --s & (al - 1);
+                        long offset = (index << ASHIFT) + ABASE;
+                        ForkJoinTask<?> t = (ForkJoinTask<?>)
+                            U.getObjectVolatile(a, offset);
+                        if (t == null)
+                            break;                   // restart
+                        else if (t == task) {
+                            boolean removed = false;
+                            if (s + 1 == top) {      // pop
+                                if (U.compareAndSwapObject(a, offset, t, null)) {
+                                    top = s;
+                                    removed = true;
+                                }
+                            }
+                            else if (base == b)      // replace with proxy
+                                removed = U.compareAndSwapObject(a, offset, t,
+                                                                 new EmptyTask());
+                            if (removed) {
+                                ForkJoinTask<?> ps = currentSteal;
+                                (currentSteal = task).doExec();
+                                currentSteal = ps;
+                            }
+                            break;
                         }
-                        else if (base == b)           // replace with proxy
-                            removed = U.compareAndSwapObject(a, j, task,
-                                                             new EmptyTask());
-                        break;
+                        else if (t.status < 0 && s + 1 == top) {
+                            if (U.compareAndSwapObject(a, offset, t, null)) {
+                                top = s;
+                            }
+                            break;                  // was cancelled
+                        }
+                        else if (++d == 0) {
+                            if (base != b)          // rescan
+                                break;
+                            return false;
+                        }
                     }
-                    else if (t.status >= 0)
-                        empty = false;
-                    else if (s + 1 == top) {          // pop and throw away
-                        if (U.compareAndSwapObject(a, j, t, null))
-                            top = s;
-                        break;
-                    }
-                    if (--n == 0) {
-                        if (!empty && base == b)
-                            stat = false;
-                        break;
+                    if (task.status < 0)
+                        return false;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Pops task if in the same CC computation as the given task,
+         * in either shared or owned mode. Used only by helpComplete.
+         */
+        final CountedCompleter<?> popCC(CountedCompleter<?> task, int mode) {
+            int b = base, s = top, al; ForkJoinTask<?>[] a;
+            if ((a = array) != null && b != s && (al = a.length) > 0) {
+                int index = (al - 1) & (s - 1);
+                long offset = ((long)index << ASHIFT) + ABASE;
+                ForkJoinTask<?> o = (ForkJoinTask<?>)
+                    U.getObjectVolatile(a, offset);
+                if (o instanceof CountedCompleter) {
+                    CountedCompleter<?> t = (CountedCompleter<?>)o;
+                    for (CountedCompleter<?> r = t;;) {
+                        if (r == task) {
+                            if ((mode & IS_OWNED) == 0) {
+                                boolean popped = false;
+                                if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
+                                    if (top == s && array == a &&
+                                        U.compareAndSwapObject(a, offset,
+                                                               t, null)) {
+                                        popped = true;
+                                        top = s - 1;
+                                    }
+                                    U.putOrderedInt(this, QLOCK, 0);
+                                    if (popped)
+                                        return t;
+                                }
+                            }
+                            else if (U.compareAndSwapObject(a, offset,
+                                                            t, null)) {
+                                top = s - 1;
+                                return t;
+                            }
+                            break;
+                        }
+                        else if ((r = r.completer) == null) // try parent
+                            break;
                     }
                 }
-                if (removed)
-                    task.doExec();
+            }
+            return null;
+        }
+
+        /**
+         * Steals and runs a task in the same CC computation as the
+         * given task if one exists and can be taken without
+         * contention. Otherwise returns a checksum/control value for
+         * use by method helpComplete.
+         *
+         * @return 1 if successful, 2 if retryable (lost to another
+         * stealer), -1 if non-empty but no matching task found, else
+         * the base index, forced negative.
+         */
+        final int pollAndExecCC(CountedCompleter<?> task) {
+            ForkJoinTask<?>[] a;
+            int b = base, s = top, al, h;
+            if ((a = array) != null && b != s && (al = a.length) > 0) {
+                int index = (al - 1) & b;
+                long offset = ((long)index << ASHIFT) + ABASE;
+                ForkJoinTask<?> o = (ForkJoinTask<?>)
+                    U.getObjectVolatile(a, offset);
+                if (o == null)
+                    h = 2;                      // retryable
+                else if (!(o instanceof CountedCompleter))
+                    h = -1;                     // unmatchable
+                else {
+                    CountedCompleter<?> t = (CountedCompleter<?>)o;
+                    for (CountedCompleter<?> r = t;;) {
+                        if (r == task) {
+                            if (b++ == base &&
+                                U.compareAndSwapObject(a, offset, t, null)) {
+                                base = b;
+                                t.doExec();
+                                h = 1;          // success
+                            }
+                            else
+                                h = 2;          // lost CAS
+                            break;
+                        }
+                        else if ((r = r.completer) == null) {
+                            h = -1;             // unmatched
+                            break;
+                        }
+                    }
+                }
             }
             else
-                stat = false;
-            return stat;
-        }
-
-        /**
-         * Tries to poll for and execute the given task or any other
-         * task in its CountedCompleter computation.
-         */
-        final boolean pollAndExecCC(CountedCompleter<?> root) {
-            ForkJoinTask<?>[] a; int b; Object o; CountedCompleter<?> t, r;
-            if ((b = base) - top < 0 && (a = array) != null) {
-                long j = (((a.length - 1) & b) << ASHIFT) + ABASE;
-                if ((o = U.getObjectVolatile(a, j)) == null)
-                    return true; // retry
-                if (o instanceof CountedCompleter) {
-                    for (t = (CountedCompleter<?>)o, r = t;;) {
-                        if (r == root) {
-                            if (base == b &&
-                                U.compareAndSwapObject(a, j, t, null)) {
-                                U.putOrderedInt(this, QBASE, b + 1);
-                                t.doExec();
-                            }
-                            return true;
-                        }
-                        else if ((r = r.completer) == null)
-                            break; // not part of root computation
-                    }
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Tries to pop and execute the given task or any other task
-         * in its CountedCompleter computation.
-         */
-        final boolean externalPopAndExecCC(CountedCompleter<?> root) {
-            ForkJoinTask<?>[] a; int s; Object o; CountedCompleter<?> t, r;
-            if (base - (s = top) < 0 && (a = array) != null) {
-                long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
-                if ((o = U.getObject(a, j)) instanceof CountedCompleter) {
-                    for (t = (CountedCompleter<?>)o, r = t;;) {
-                        if (r == root) {
-                            if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
-                                if (top == s && array == a &&
-                                    U.compareAndSwapObject(a, j, t, null)) {
-                                    top = s - 1;
-                                    qlock = 0;
-                                    t.doExec();
-                                }
-                                else
-                                    qlock = 0;
-                            }
-                            return true;
-                        }
-                        else if ((r = r.completer) == null)
-                            break;
-                    }
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Internal version
-         */
-        final boolean internalPopAndExecCC(CountedCompleter<?> root) {
-            ForkJoinTask<?>[] a; int s; Object o; CountedCompleter<?> t, r;
-            if (base - (s = top) < 0 && (a = array) != null) {
-                long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
-                if ((o = U.getObject(a, j)) instanceof CountedCompleter) {
-                    for (t = (CountedCompleter<?>)o, r = t;;) {
-                        if (r == root) {
-                            if (U.compareAndSwapObject(a, j, t, null)) {
-                                top = s - 1;
-                                t.doExec();
-                            }
-                            return true;
-                        }
-                        else if ((r = r.completer) == null)
-                            break;
-                    }
-                }
-            }
-            return false;
+                h = b | Integer.MIN_VALUE;      // to sense movement on re-poll
+            return h;
         }
 
         /**
@@ -1005,34 +1305,28 @@
          */
         final boolean isApparentlyUnblocked() {
             Thread wt; Thread.State s;
-            return (eventCount >= 0 &&
+            return (scanState >= 0 &&
                     (wt = owner) != null &&
                     (s = wt.getState()) != Thread.State.BLOCKED &&
                     s != Thread.State.WAITING &&
                     s != Thread.State.TIMED_WAITING);
         }
 
-        // Unsafe mechanics
-        private static final sun.misc.Unsafe U;
-        private static final long QBASE;
+        // Unsafe mechanics. Note that some are (and must be) the same as in FJP
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
         private static final long QLOCK;
         private static final int ABASE;
         private static final int ASHIFT;
         static {
             try {
-                U = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = WorkQueue.class;
-                Class<?> ak = ForkJoinTask[].class;
-                QBASE = U.objectFieldOffset
-                    (k.getDeclaredField("base"));
                 QLOCK = U.objectFieldOffset
-                    (k.getDeclaredField("qlock"));
-                ABASE = U.arrayBaseOffset(ak);
-                int scale = U.arrayIndexScale(ak);
+                    (WorkQueue.class.getDeclaredField("qlock"));
+                ABASE = U.arrayBaseOffset(ForkJoinTask[].class);
+                int scale = U.arrayIndexScale(ForkJoinTask[].class);
                 if ((scale & (scale - 1)) != 0)
-                    throw new Error("data type scale not a power of two");
+                    throw new Error("array index scale not a power of two");
                 ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
-            } catch (Exception e) {
+            } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
         }
@@ -1041,15 +1335,6 @@
     // static fields (initialized in static initializer below)
 
     /**
-     * Per-thread submission bookkeeping. Shared across all pools
-     * to reduce ThreadLocal pollution and because random motion
-     * to avoid contention in one pool is likely to hold for others.
-     * Lazily initialized on first submission (but null-checked
-     * in other contexts to avoid unnecessary initialization).
-     */
-    static final ThreadLocal<Submitter> submitters;
-
-    /**
      * Creates a new ForkJoinWorkerThread. This factory is used unless
      * overridden in ForkJoinPool constructors.
      */
@@ -1058,9 +1343,9 @@
 
     /**
      * Permission required for callers of methods that may start or
-     * kill threads.
+     * kill threads.  Also used as a static lock in tryInitialize.
      */
-    private static final RuntimePermission modifyThreadPermission;
+    static final RuntimePermission modifyThreadPermission;
 
     /**
      * Common (static) pool. Non-null for public use unless a static
@@ -1076,7 +1361,12 @@
      * common.parallelism field to be zero, but in that case still report
      * parallelism as 1 to reflect resulting caller-runs mechanics.
      */
-    static final int commonParallelism;
+    static final int COMMON_PARALLELISM;
+
+    /**
+     * Limit on spare thread construction in tryCompensate.
+     */
+    private static final int COMMON_MAX_SPARES;
 
     /**
      * Sequence number for creating workerNamePrefix.
@@ -1091,270 +1381,215 @@
         return ++poolNumberSequence;
     }
 
-    // static constants
+    // static configuration constants
 
     /**
-     * Initial timeout value (in nanoseconds) for the thread
+     * Initial timeout value (in milliseconds) for the thread
      * triggering quiescence to park waiting for new work. On timeout,
-     * the thread will instead try to shrink the number of
-     * workers. The value should be large enough to avoid overly
-     * aggressive shrinkage during most transient stalls (long GCs
-     * etc).
+     * the thread will instead try to shrink the number of workers.
+     * The value should be large enough to avoid overly aggressive
+     * shrinkage during most transient stalls (long GCs etc).
      */
-    private static final long IDLE_TIMEOUT      = 2000L * 1000L * 1000L; // 2sec
+    private static final long IDLE_TIMEOUT_MS = 2000L; // 2sec
 
     /**
-     * Timeout value when there are more threads than parallelism level
+     * Tolerance for idle timeouts, to cope with timer undershoots.
      */
-    private static final long FAST_IDLE_TIMEOUT =  200L * 1000L * 1000L;
+    private static final long TIMEOUT_SLOP_MS =   20L; // 20ms
 
     /**
-     * Tolerance for idle timeouts, to cope with timer undershoots
+     * The default value for COMMON_MAX_SPARES.  Overridable using the
+     * "java.util.concurrent.ForkJoinPool.common.maximumSpares" system
+     * property.  The default value is far in excess of normal
+     * requirements, but also far short of MAX_CAP and typical OS
+     * thread limits, so allows JVMs to catch misuse/abuse before
+     * running out of resources needed to do so.
      */
-    private static final long TIMEOUT_SLOP = 2000000L;
-
-    /**
-     * The maximum stolen->joining link depth allowed in method
-     * tryHelpStealer.  Must be a power of two.  Depths for legitimate
-     * chains are unbounded, but we use a fixed constant to avoid
-     * (otherwise unchecked) cycles and to bound staleness of
-     * traversal parameters at the expense of sometimes blocking when
-     * we could be helping.
-     */
-    private static final int MAX_HELP = 64;
+    private static final int DEFAULT_COMMON_MAX_SPARES = 256;
 
     /**
      * Increment for seed generators. See class ThreadLocal for
      * explanation.
      */
-    private static final int SEED_INCREMENT = 0x61c88647;
+    private static final int SEED_INCREMENT = 0x9e3779b9;
 
     /*
-     * Bits and masks for control variables
+     * Bits and masks for field ctl, packed with 4 16 bit subfields:
+     * AC: Number of active running workers minus target parallelism
+     * TC: Number of total workers minus target parallelism
+     * SS: version count and status of top waiting thread
+     * ID: poolIndex of top of Treiber stack of waiters
      *
-     * Field ctl is a long packed with:
-     * AC: Number of active running workers minus target parallelism (16 bits)
-     * TC: Number of total workers minus target parallelism (16 bits)
-     * ST: true if pool is terminating (1 bit)
-     * EC: the wait count of top waiting thread (15 bits)
-     * ID: poolIndex of top of Treiber stack of waiters (16 bits)
+     * When convenient, we can extract the lower 32 stack top bits
+     * (including version bits) as sp=(int)ctl.  The offsets of counts
+     * by the target parallelism and the positionings of fields makes
+     * it possible to perform the most common checks via sign tests of
+     * fields: When ac is negative, there are not enough active
+     * workers, when tc is negative, there are not enough total
+     * workers.  When sp is non-zero, there are waiting workers.  To
+     * deal with possibly negative fields, we use casts in and out of
+     * "short" and/or signed shifts to maintain signedness.
      *
-     * When convenient, we can extract the upper 32 bits of counts and
-     * the lower 32 bits of queue state, u = (int)(ctl >>> 32) and e =
-     * (int)ctl.  The ec field is never accessed alone, but always
-     * together with id and st. The offsets of counts by the target
-     * parallelism and the positionings of fields makes it possible to
-     * perform the most common checks via sign tests of fields: When
-     * ac is negative, there are not enough active workers, when tc is
-     * negative, there are not enough total workers, and when e is
-     * negative, the pool is terminating.  To deal with these possibly
-     * negative fields, we use casts in and out of "short" and/or
-     * signed shifts to maintain signedness.
-     *
-     * When a thread is queued (inactivated), its eventCount field is
-     * set negative, which is the only way to tell if a worker is
-     * prevented from executing tasks, even though it must continue to
-     * scan for them to avoid queuing races. Note however that
-     * eventCount updates lag releases so usage requires care.
-     *
-     * Field plock is an int packed with:
-     * SHUTDOWN: true if shutdown is enabled (1 bit)
-     * SEQ:  a sequence lock, with PL_LOCK bit set if locked (30 bits)
-     * SIGNAL: set when threads may be waiting on the lock (1 bit)
-     *
-     * The sequence number enables simple consistency checks:
-     * Staleness of read-only operations on the workQueues array can
-     * be checked by comparing plock before vs after the reads.
+     * Because it occupies uppermost bits, we can add one active count
+     * using getAndAddLong of AC_UNIT, rather than CAS, when returning
+     * from a blocked join.  Other updates entail multiple subfields
+     * and masking, requiring CAS.
      */
 
-    // bit positions/shifts for fields
+    // Lower and upper word masks
+    private static final long SP_MASK    = 0xffffffffL;
+    private static final long UC_MASK    = ~SP_MASK;
+
+    // Active counts
     private static final int  AC_SHIFT   = 48;
+    private static final long AC_UNIT    = 0x0001L << AC_SHIFT;
+    private static final long AC_MASK    = 0xffffL << AC_SHIFT;
+
+    // Total counts
     private static final int  TC_SHIFT   = 32;
-    private static final int  ST_SHIFT   = 31;
-    private static final int  EC_SHIFT   = 16;
+    private static final long TC_UNIT    = 0x0001L << TC_SHIFT;
+    private static final long TC_MASK    = 0xffffL << TC_SHIFT;
+    private static final long ADD_WORKER = 0x0001L << (TC_SHIFT + 15); // sign
 
-    // bounds
-    private static final int  SMASK      = 0xffff;  // short bits
-    private static final int  MAX_CAP    = 0x7fff;  // max #workers - 1
-    private static final int  EVENMASK   = 0xfffe;  // even short bits
-    private static final int  SQMASK     = 0x007e;  // max 64 (even) slots
-    private static final int  SHORT_SIGN = 1 << 15;
-    private static final int  INT_SIGN   = 1 << 31;
-
-    // masks
-    private static final long STOP_BIT   = 0x0001L << ST_SHIFT;
-    private static final long AC_MASK    = ((long)SMASK) << AC_SHIFT;
-    private static final long TC_MASK    = ((long)SMASK) << TC_SHIFT;
-
-    // units for incrementing and decrementing
-    private static final long TC_UNIT    = 1L << TC_SHIFT;
-    private static final long AC_UNIT    = 1L << AC_SHIFT;
-
-    // masks and units for dealing with u = (int)(ctl >>> 32)
-    private static final int  UAC_SHIFT  = AC_SHIFT - 32;
-    private static final int  UTC_SHIFT  = TC_SHIFT - 32;
-    private static final int  UAC_MASK   = SMASK << UAC_SHIFT;
-    private static final int  UTC_MASK   = SMASK << UTC_SHIFT;
-    private static final int  UAC_UNIT   = 1 << UAC_SHIFT;
-    private static final int  UTC_UNIT   = 1 << UTC_SHIFT;
-
-    // masks and units for dealing with e = (int)ctl
-    private static final int E_MASK      = 0x7fffffff; // no STOP_BIT
-    private static final int E_SEQ       = 1 << EC_SHIFT;
-
-    // plock bits
-    private static final int SHUTDOWN    = 1 << 31;
-    private static final int PL_LOCK     = 2;
-    private static final int PL_SIGNAL   = 1;
-    private static final int PL_SPINS    = 1 << 8;
-
-    // access mode for WorkQueue
-    static final int LIFO_QUEUE          =  0;
-    static final int FIFO_QUEUE          =  1;
-    static final int SHARED_QUEUE        = -1;
-
-    // Heuristic padding to ameliorate unfortunate memory placements
-    volatile long pad00, pad01, pad02, pad03, pad04, pad05, pad06;
+    // runState bits: SHUTDOWN must be negative, others arbitrary powers of two
+    private static final int  STARTED    = 1;
+    private static final int  STOP       = 1 << 1;
+    private static final int  TERMINATED = 1 << 2;
+    private static final int  SHUTDOWN   = 1 << 31;
 
     // Instance fields
-    volatile long stealCount;                  // collects worker counts
-    volatile long ctl;                         // main pool control
-    volatile int plock;                        // shutdown status and seqLock
-    volatile int indexSeed;                    // worker/submitter index seed
-    final short parallelism;                   // parallelism level
-    final short mode;                          // LIFO/FIFO
-    WorkQueue[] workQueues;                    // main registry
+    volatile long ctl;                   // main pool control
+    volatile int runState;
+    final int config;                    // parallelism, mode
+    AuxState auxState;                   // lock, steal counts
+    volatile WorkQueue[] workQueues;     // main registry
+    final String workerNamePrefix;       // to create worker name string
     final ForkJoinWorkerThreadFactory factory;
-    final UncaughtExceptionHandler ueh;        // per-worker UEH
-    final String workerNamePrefix;             // to create worker name string
-
-    volatile Object pad10, pad11, pad12, pad13, pad14, pad15, pad16, pad17;
-    volatile Object pad18, pad19, pad1a, pad1b;
+    final UncaughtExceptionHandler ueh;  // per-worker UEH
 
     /**
-     * Acquires the plock lock to protect worker array and related
-     * updates. This method is called only if an initial CAS on plock
-     * fails. This acts as a spinlock for normal cases, but falls back
-     * to builtin monitor to block when (rarely) needed. This would be
-     * a terrible idea for a highly contended lock, but works fine as
-     * a more conservative alternative to a pure spinlock.
+     * Instantiates fields upon first submission, or upon shutdown if
+     * no submissions. If checkTermination true, also responds to
+     * termination by external calls submitting tasks.
      */
-    private int acquirePlock() {
-        int spins = PL_SPINS, ps, nps;
-        for (;;) {
-            if (((ps = plock) & PL_LOCK) == 0 &&
-                U.compareAndSwapInt(this, PLOCK, ps, nps = ps + PL_LOCK))
-                return nps;
-            else if (spins >= 0) {
-                if (ThreadLocalRandom.current().nextInt() >= 0)
-                    --spins;
-            }
-            else if (U.compareAndSwapInt(this, PLOCK, ps, ps | PL_SIGNAL)) {
-                synchronized (this) {
-                    if ((plock & PL_SIGNAL) != 0) {
-                        try {
-                            wait();
-                        } catch (InterruptedException ie) {
-                            try {
-                                Thread.currentThread().interrupt();
-                            } catch (SecurityException ignore) {
-                            }
-                        }
-                    }
-                    else
-                        notifyAll();
+    private void tryInitialize(boolean checkTermination) {
+        if (runState == 0) { // bootstrap by locking static field
+            int p = config & SMASK;
+            int n = (p > 1) ? p - 1 : 1; // ensure at least 2 slots
+            n |= n >>> 1;    // create workQueues array with size a power of two
+            n |= n >>> 2;
+            n |= n >>> 4;
+            n |= n >>> 8;
+            n |= n >>> 16;
+            n = ((n + 1) << 1) & SMASK;
+            AuxState aux = new AuxState();
+            WorkQueue[] ws = new WorkQueue[n];
+            synchronized (modifyThreadPermission) { // double-check
+                if (runState == 0) {
+                    workQueues = ws;
+                    auxState = aux;
+                    runState = STARTED;
                 }
             }
         }
+        if (checkTermination && runState < 0) {
+            tryTerminate(false, false); // help terminate
+            throw new RejectedExecutionException();
+        }
+    }
+
+    // Creating, registering and deregistering workers
+
+    /**
+     * Tries to construct and start one worker. Assumes that total
+     * count has already been incremented as a reservation.  Invokes
+     * deregisterWorker on any failure.
+     *
+     * @param isSpare true if this is a spare thread
+     * @return true if successful
+     */
+    private boolean createWorker(boolean isSpare) {
+        ForkJoinWorkerThreadFactory fac = factory;
+        Throwable ex = null;
+        ForkJoinWorkerThread wt = null;
+        WorkQueue q;
+        try {
+            if (fac != null && (wt = fac.newThread(this)) != null) {
+                if (isSpare && (q = wt.workQueue) != null)
+                    q.config |= SPARE_WORKER;
+                wt.start();
+                return true;
+            }
+        } catch (Throwable rex) {
+            ex = rex;
+        }
+        deregisterWorker(wt, ex);
+        return false;
     }
 
     /**
-     * Unlocks and signals any thread waiting for plock. Called only
-     * when CAS of seq value for unlock fails.
+     * Tries to add one worker, incrementing ctl counts before doing
+     * so, relying on createWorker to back out on failure.
+     *
+     * @param c incoming ctl value, with total count negative and no
+     * idle workers.  On CAS failure, c is refreshed and retried if
+     * this holds (otherwise, a new worker is not needed).
      */
-    private void releasePlock(int ps) {
-        plock = ps;
-        synchronized (this) { notifyAll(); }
-    }
-
-    /**
-     * Tries to create and start one worker if fewer than target
-     * parallelism level exist. Adjusts counts etc on failure.
-     */
-    private void tryAddWorker() {
-        long c; int u, e;
-        while ((u = (int)((c = ctl) >>> 32)) < 0 &&
-               (u & SHORT_SIGN) != 0 && (e = (int)c) >= 0) {
-            long nc = ((long)(((u + UTC_UNIT) & UTC_MASK) |
-                              ((u + UAC_UNIT) & UAC_MASK)) << 32) | (long)e;
-            if (U.compareAndSwapLong(this, CTL, c, nc)) {
-                ForkJoinWorkerThreadFactory fac;
-                Throwable ex = null;
-                ForkJoinWorkerThread wt = null;
-                try {
-                    if ((fac = factory) != null &&
-                        (wt = fac.newThread(this)) != null) {
-                        wt.start();
-                        break;
-                    }
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-                deregisterWorker(wt, ex);
+    private void tryAddWorker(long c) {
+        do {
+            long nc = ((AC_MASK & (c + AC_UNIT)) |
+                       (TC_MASK & (c + TC_UNIT)));
+            if (ctl == c && U.compareAndSwapLong(this, CTL, c, nc)) {
+                createWorker(false);
                 break;
             }
-        }
+        } while (((c = ctl) & ADD_WORKER) != 0L && (int)c == 0);
     }
 
-    //  Registering and deregistering workers
-
     /**
-     * Callback from ForkJoinWorkerThread to establish and record its
-     * WorkQueue. To avoid scanning bias due to packing entries in
-     * front of the workQueues array, we treat the array as a simple
-     * power-of-two hash table using per-thread seed as hash,
-     * expanding as needed.
+     * Callback from ForkJoinWorkerThread constructor to establish and
+     * record its WorkQueue.
      *
      * @param wt the worker thread
      * @return the worker's queue
      */
     final WorkQueue registerWorker(ForkJoinWorkerThread wt) {
-        UncaughtExceptionHandler handler; WorkQueue[] ws; int s, ps;
-        wt.setDaemon(true);
+        UncaughtExceptionHandler handler;
+        AuxState aux;
+        wt.setDaemon(true);                           // configure thread
         if ((handler = ueh) != null)
             wt.setUncaughtExceptionHandler(handler);
-        do {} while (!U.compareAndSwapInt(this, INDEXSEED, s = indexSeed,
-                                          s += SEED_INCREMENT) ||
-                     s == 0); // skip 0
-        WorkQueue w = new WorkQueue(this, wt, mode, s);
-        if (((ps = plock) & PL_LOCK) != 0 ||
-            !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-            ps = acquirePlock();
-        int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
-        try {
-            if ((ws = workQueues) != null) {    // skip if shutting down
-                int n = ws.length, m = n - 1;
-                int r = (s << 1) | 1;           // use odd-numbered indices
-                if (ws[r &= m] != null) {       // collision
-                    int probes = 0;             // step by approx half size
-                    int step = (n <= 4) ? 2 : ((n >>> 1) & EVENMASK) + 2;
-                    while (ws[r = (r + step) & m] != null) {
-                        if (++probes >= n) {
-                            workQueues = ws = Arrays.copyOf(ws, n <<= 1);
-                            m = n - 1;
-                            probes = 0;
+        WorkQueue w = new WorkQueue(this, wt);
+        int i = 0;                                    // assign a pool index
+        int mode = config & MODE_MASK;
+        if ((aux = auxState) != null) {
+            aux.lock();
+            try {
+                int s = (int)(aux.indexSeed += SEED_INCREMENT), n, m;
+                WorkQueue[] ws = workQueues;
+                if (ws != null && (n = ws.length) > 0) {
+                    i = (m = n - 1) & ((s << 1) | 1); // odd-numbered indices
+                    if (ws[i] != null) {              // collision
+                        int probes = 0;               // step by approx half n
+                        int step = (n <= 4) ? 2 : ((n >>> 1) & EVENMASK) + 2;
+                        while (ws[i = (i + step) & m] != null) {
+                            if (++probes >= n) {
+                                workQueues = ws = Arrays.copyOf(ws, n <<= 1);
+                                m = n - 1;
+                                probes = 0;
+                            }
                         }
                     }
+                    w.hint = s;                       // use as random seed
+                    w.config = i | mode;
+                    w.scanState = i | (s & 0x7fff0000); // random seq bits
+                    ws[i] = w;
                 }
-                w.poolIndex = (short)r;
-                w.eventCount = r; // volatile write orders
-                ws[r] = w;
+            } finally {
+                aux.unlock();
             }
-        } finally {
-            if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                releasePlock(nps);
         }
-        wt.setName(workerNamePrefix.concat(Integer.toString(w.poolIndex >>> 1)));
+        wt.setName(workerNamePrefix.concat(Integer.toString(i >>> 1)));
         return w;
     }
 
@@ -1370,383 +1605,231 @@
     final void deregisterWorker(ForkJoinWorkerThread wt, Throwable ex) {
         WorkQueue w = null;
         if (wt != null && (w = wt.workQueue) != null) {
-            int ps; long sc;
-            w.qlock = -1;                // ensure set
-            do {} while (!U.compareAndSwapLong(this, STEALCOUNT,
-                                               sc = stealCount,
-                                               sc + w.nsteals));
-            if (((ps = plock) & PL_LOCK) != 0 ||
-                !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-                ps = acquirePlock();
-            int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
-            try {
-                int idx = w.poolIndex;
-                WorkQueue[] ws = workQueues;
-                if (ws != null && idx >= 0 && idx < ws.length && ws[idx] == w)
-                    ws[idx] = null;
-            } finally {
-                if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                    releasePlock(nps);
+            AuxState aux; WorkQueue[] ws;          // remove index from array
+            int idx = w.config & SMASK;
+            int ns = w.nsteals;
+            if ((aux = auxState) != null) {
+                aux.lock();
+                try {
+                    if ((ws = workQueues) != null && ws.length > idx &&
+                        ws[idx] == w)
+                        ws[idx] = null;
+                    aux.stealCount += ns;
+                } finally {
+                    aux.unlock();
+                }
             }
         }
-
-        long c;                          // adjust ctl counts
-        do {} while (!U.compareAndSwapLong
-                     (this, CTL, c = ctl, (((c - AC_UNIT) & AC_MASK) |
-                                           ((c - TC_UNIT) & TC_MASK) |
-                                           (c & ~(AC_MASK|TC_MASK)))));
-
-        if (!tryTerminate(false, false) && w != null && w.array != null) {
-            w.cancelAll();               // cancel remaining tasks
-            WorkQueue[] ws; WorkQueue v; Thread p; int u, i, e;
-            while ((u = (int)((c = ctl) >>> 32)) < 0 && (e = (int)c) >= 0) {
-                if (e > 0) {             // activate or create replacement
-                    if ((ws = workQueues) == null ||
-                        (i = e & SMASK) >= ws.length ||
-                        (v = ws[i]) == null)
-                        break;
-                    long nc = (((long)(v.nextWait & E_MASK)) |
-                               ((long)(u + UAC_UNIT) << 32));
-                    if (v.eventCount != (e | INT_SIGN))
-                        break;
-                    if (U.compareAndSwapLong(this, CTL, c, nc)) {
-                        v.eventCount = (e + E_SEQ) & E_MASK;
-                        if ((p = v.parker) != null)
-                            U.unpark(p);
-                        break;
-                    }
-                }
-                else {
-                    if ((short)u < 0)
-                        tryAddWorker();
+        if (w == null || (w.config & UNREGISTERED) == 0) { // else pre-adjusted
+            long c;                                   // decrement counts
+            do {} while (!U.compareAndSwapLong
+                         (this, CTL, c = ctl, ((AC_MASK & (c - AC_UNIT)) |
+                                               (TC_MASK & (c - TC_UNIT)) |
+                                               (SP_MASK & c))));
+        }
+        if (w != null) {
+            w.currentSteal = null;
+            w.qlock = -1;                             // ensure set
+            w.cancelAll();                            // cancel remaining tasks
+        }
+        while (tryTerminate(false, false) >= 0) {     // possibly replace
+            WorkQueue[] ws; int wl, sp; long c;
+            if (w == null || w.array == null ||
+                (ws = workQueues) == null || (wl = ws.length) <= 0)
+                break;
+            else if ((sp = (int)(c = ctl)) != 0) {    // wake up replacement
+                if (tryRelease(c, ws[(wl - 1) & sp], AC_UNIT))
                     break;
-                }
             }
+            else if (ex != null && (c & ADD_WORKER) != 0L) {
+                tryAddWorker(c);                      // create replacement
+                break;
+            }
+            else                                      // don't need replacement
+                break;
         }
-        if (ex == null)                     // help clean refs on way out
+        if (ex == null)                               // help clean on way out
             ForkJoinTask.helpExpungeStaleExceptions();
-        else                                // rethrow
+        else                                          // rethrow
             ForkJoinTask.rethrow(ex);
     }
 
-    // Submissions
-
-    /**
-     * Per-thread records for threads that submit to pools. Currently
-     * holds only pseudo-random seed / index that is used to choose
-     * submission queues in method externalPush. In the future, this may
-     * also incorporate a means to implement different task rejection
-     * and resubmission policies.
-     *
-     * Seeds for submitters and workers/workQueues work in basically
-     * the same way but are initialized and updated using slightly
-     * different mechanics. Both are initialized using the same
-     * approach as in class ThreadLocal, where successive values are
-     * unlikely to collide with previous values. Seeds are then
-     * randomly modified upon collisions using xorshifts, which
-     * requires a non-zero seed.
-     */
-    static final class Submitter {
-        int seed;
-        Submitter(int s) { seed = s; }
-    }
-
-    /**
-     * Unless shutting down, adds the given task to a submission queue
-     * at submitter's current queue index (modulo submission
-     * range). Only the most common path is directly handled in this
-     * method. All others are relayed to fullExternalPush.
-     *
-     * @param task the task. Caller must ensure non-null.
-     */
-    final void externalPush(ForkJoinTask<?> task) {
-        Submitter z = submitters.get();
-        WorkQueue q; int r, m, s, n, am; ForkJoinTask<?>[] a;
-        int ps = plock;
-        WorkQueue[] ws = workQueues;
-        if (z != null && ps > 0 && ws != null && (m = (ws.length - 1)) >= 0 &&
-            (q = ws[m & (r = z.seed) & SQMASK]) != null && r != 0 &&
-            U.compareAndSwapInt(q, QLOCK, 0, 1)) { // lock
-            if ((a = q.array) != null &&
-                (am = a.length - 1) > (n = (s = q.top) - q.base)) {
-                int j = ((am & s) << ASHIFT) + ABASE;
-                U.putOrderedObject(a, j, task);
-                q.top = s + 1;                     // push on to deque
-                q.qlock = 0;
-                if (n <= 1)
-                    signalWork(ws, q);
-                return;
-            }
-            q.qlock = 0;
-        }
-        fullExternalPush(task);
-    }
-
-    /**
-     * Full version of externalPush. This method is called, among
-     * other times, upon the first submission of the first task to the
-     * pool, so must perform secondary initialization.  It also
-     * detects first submission by an external thread by looking up
-     * its ThreadLocal, and creates a new shared queue if the one at
-     * index if empty or contended. The plock lock body must be
-     * exception-free (so no try/finally) so we optimistically
-     * allocate new queues outside the lock and throw them away if
-     * (very rarely) not needed.
-     *
-     * Secondary initialization occurs when plock is zero, to create
-     * workQueue array and set plock to a valid value.  This lock body
-     * must also be exception-free. Because the plock seq value can
-     * eventually wrap around zero, this method harmlessly fails to
-     * reinitialize if workQueues exists, while still advancing plock.
-     */
-    private void fullExternalPush(ForkJoinTask<?> task) {
-        int r = 0; // random index seed
-        for (Submitter z = submitters.get();;) {
-            WorkQueue[] ws; WorkQueue q; int ps, m, k;
-            if (z == null) {
-                if (U.compareAndSwapInt(this, INDEXSEED, r = indexSeed,
-                                        r += SEED_INCREMENT) && r != 0)
-                    submitters.set(z = new Submitter(r));
-            }
-            else if (r == 0) {                  // move to a different index
-                r = z.seed;
-                r ^= r << 13;                   // same xorshift as WorkQueues
-                r ^= r >>> 17;
-                z.seed = r ^= (r << 5);
-            }
-            if ((ps = plock) < 0)
-                throw new RejectedExecutionException();
-            else if (ps == 0 || (ws = workQueues) == null ||
-                     (m = ws.length - 1) < 0) { // initialize workQueues
-                int p = parallelism;            // find power of two table size
-                int n = (p > 1) ? p - 1 : 1;    // ensure at least 2 slots
-                n |= n >>> 1; n |= n >>> 2;  n |= n >>> 4;
-                n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1;
-                WorkQueue[] nws = ((ws = workQueues) == null || ws.length == 0 ?
-                                   new WorkQueue[n] : null);
-                if (((ps = plock) & PL_LOCK) != 0 ||
-                    !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-                    ps = acquirePlock();
-                if (((ws = workQueues) == null || ws.length == 0) && nws != null)
-                    workQueues = nws;
-                int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
-                if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                    releasePlock(nps);
-            }
-            else if ((q = ws[k = r & m & SQMASK]) != null) {
-                if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
-                    ForkJoinTask<?>[] a = q.array;
-                    int s = q.top;
-                    boolean submitted = false;
-                    try {                      // locked version of push
-                        if ((a != null && a.length > s + 1 - q.base) ||
-                            (a = q.growArray()) != null) {   // must presize
-                            int j = (((a.length - 1) & s) << ASHIFT) + ABASE;
-                            U.putOrderedObject(a, j, task);
-                            q.top = s + 1;
-                            submitted = true;
-                        }
-                    } finally {
-                        q.qlock = 0;  // unlock
-                    }
-                    if (submitted) {
-                        signalWork(ws, q);
-                        return;
-                    }
-                }
-                r = 0; // move on failure
-            }
-            else if (((ps = plock) & PL_LOCK) == 0) { // create new queue
-                q = new WorkQueue(this, null, SHARED_QUEUE, r);
-                q.poolIndex = (short)k;
-                if (((ps = plock) & PL_LOCK) != 0 ||
-                    !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-                    ps = acquirePlock();
-                if ((ws = workQueues) != null && k < ws.length && ws[k] == null)
-                    ws[k] = q;
-                int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
-                if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                    releasePlock(nps);
-            }
-            else
-                r = 0;
-        }
-    }
-
-    // Maintaining ctl counts
-
-    /**
-     * Increments active count; mainly called upon return from blocking.
-     */
-    final void incrementActiveCount() {
-        long c;
-        do {} while (!U.compareAndSwapLong
-                     (this, CTL, c = ctl, ((c & ~AC_MASK) |
-                                           ((c & AC_MASK) + AC_UNIT))));
-    }
+    // Signalling
 
     /**
      * Tries to create or activate a worker if too few are active.
-     *
-     * @param ws the worker array to use to find signallees
-     * @param q if non-null, the queue holding tasks to be processed
      */
-    final void signalWork(WorkQueue[] ws, WorkQueue q) {
+    final void signalWork() {
         for (;;) {
-            long c; int e, u, i; WorkQueue w; Thread p;
-            if ((u = (int)((c = ctl) >>> 32)) >= 0)
+            long c; int sp, i; WorkQueue v; WorkQueue[] ws;
+            if ((c = ctl) >= 0L)                      // enough workers
                 break;
-            if ((e = (int)c) <= 0) {
-                if ((short)u < 0)
-                    tryAddWorker();
+            else if ((sp = (int)c) == 0) {            // no idle workers
+                if ((c & ADD_WORKER) != 0L)           // too few workers
+                    tryAddWorker(c);
                 break;
             }
-            if (ws == null || ws.length <= (i = e & SMASK) ||
-                (w = ws[i]) == null)
-                break;
-            long nc = (((long)(w.nextWait & E_MASK)) |
-                       ((long)(u + UAC_UNIT)) << 32);
-            int ne = (e + E_SEQ) & E_MASK;
-            if (w.eventCount == (e | INT_SIGN) &&
+            else if ((ws = workQueues) == null)
+                break;                                // unstarted/terminated
+            else if (ws.length <= (i = sp & SMASK))
+                break;                                // terminated
+            else if ((v = ws[i]) == null)
+                break;                                // terminating
+            else {
+                int ns = sp & ~UNSIGNALLED;
+                int vs = v.scanState;
+                long nc = (v.stackPred & SP_MASK) | (UC_MASK & (c + AC_UNIT));
+                if (sp == vs && U.compareAndSwapLong(this, CTL, c, nc)) {
+                    v.scanState = ns;
+                    LockSupport.unpark(v.parker);
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Signals and releases worker v if it is top of idle worker
+     * stack.  This performs a one-shot version of signalWork only if
+     * there is (apparently) at least one idle worker.
+     *
+     * @param c incoming ctl value
+     * @param v if non-null, a worker
+     * @param inc the increment to active count (zero when compensating)
+     * @return true if successful
+     */
+    private boolean tryRelease(long c, WorkQueue v, long inc) {
+        int sp = (int)c, ns = sp & ~UNSIGNALLED;
+        if (v != null) {
+            int vs = v.scanState;
+            long nc = (v.stackPred & SP_MASK) | (UC_MASK & (c + inc));
+            if (sp == vs && U.compareAndSwapLong(this, CTL, c, nc)) {
+                v.scanState = ns;
+                LockSupport.unpark(v.parker);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * With approx probability of a missed signal, tries (once) to
+     * reactivate worker w (or some other worker), failing if stale or
+     * known to be already active.
+     *
+     * @param w the worker
+     * @param ws the workQueue array to use
+     * @param r random seed
+     */
+    private void tryReactivate(WorkQueue w, WorkQueue[] ws, int r) {
+        long c; int sp, wl; WorkQueue v;
+        if ((sp = (int)(c = ctl)) != 0 && w != null &&
+            ws != null && (wl = ws.length) > 0 &&
+            ((sp ^ r) & SS_SEQ) == 0 &&
+            (v = ws[(wl - 1) & sp]) != null) {
+            long nc = (v.stackPred & SP_MASK) | (UC_MASK & (c + AC_UNIT));
+            int ns = sp & ~UNSIGNALLED;
+            if (w.scanState < 0 &&
+                v.scanState == sp &&
                 U.compareAndSwapLong(this, CTL, c, nc)) {
-                w.eventCount = ne;
-                if ((p = w.parker) != null)
-                    U.unpark(p);
-                break;
-            }
-            if (q != null && q.base >= q.top)
-                break;
-        }
-    }
-
-    // Scanning for tasks
-
-    /**
-     * Top-level runloop for workers, called by ForkJoinWorkerThread.run.
-     */
-    final void runWorker(WorkQueue w) {
-        w.growArray(); // allocate queue
-        for (int r = w.hint; scan(w, r) == 0; ) {
-            r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift
-        }
-    }
-
-    /**
-     * Scans for and, if found, runs one task, else possibly
-     * inactivates the worker. This method operates on single reads of
-     * volatile state and is designed to be re-invoked continuously,
-     * in part because it returns upon detecting inconsistencies,
-     * contention, or state changes that indicate possible success on
-     * re-invocation.
-     *
-     * The scan searches for tasks across queues starting at a random
-     * index, checking each at least twice.  The scan terminates upon
-     * either finding a non-empty queue, or completing the sweep. If
-     * the worker is not inactivated, it takes and runs a task from
-     * this queue. Otherwise, if not activated, it tries to activate
-     * itself or some other worker by signalling. On failure to find a
-     * task, returns (for retry) if pool state may have changed during
-     * an empty scan, or tries to inactivate if active, else possibly
-     * blocks or terminates via method awaitWork.
-     *
-     * @param w the worker (via its WorkQueue)
-     * @param r a random seed
-     * @return worker qlock status if would have waited, else 0
-     */
-    private final int scan(WorkQueue w, int r) {
-        WorkQueue[] ws; int m;
-        long c = ctl;                            // for consistency check
-        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 && w != null) {
-            for (int j = m + m + 1, ec = w.eventCount;;) {
-                WorkQueue q; int b, e; ForkJoinTask<?>[] a; ForkJoinTask<?> t;
-                if ((q = ws[(r - j) & m]) != null &&
-                    (b = q.base) - q.top < 0 && (a = q.array) != null) {
-                    long i = (((a.length - 1) & b) << ASHIFT) + ABASE;
-                    if ((t = ((ForkJoinTask<?>)
-                              U.getObjectVolatile(a, i))) != null) {
-                        if (ec < 0)
-                            helpRelease(c, ws, w, q, b);
-                        else if (q.base == b &&
-                                 U.compareAndSwapObject(a, i, t, null)) {
-                            U.putOrderedInt(q, QBASE, b + 1);
-                            if ((b + 1) - q.top < 0)
-                                signalWork(ws, q);
-                            w.runTask(t);
-                        }
-                    }
-                    break;
-                }
-                else if (--j < 0) {
-                    if ((ec | (e = (int)c)) < 0) // inactive or terminating
-                        return awaitWork(w, c, ec);
-                    else if (ctl == c) {         // try to inactivate and enqueue
-                        long nc = (long)ec | ((c - AC_UNIT) & (AC_MASK|TC_MASK));
-                        w.nextWait = e;
-                        w.eventCount = ec | INT_SIGN;
-                        if (!U.compareAndSwapLong(this, CTL, c, nc))
-                            w.eventCount = ec;   // back out
-                    }
-                    break;
-                }
+                v.scanState = ns;
+                LockSupport.unpark(v.parker);
             }
         }
-        return 0;
     }
 
     /**
-     * A continuation of scan(), possibly blocking or terminating
-     * worker w. Returns without blocking if pool state has apparently
-     * changed since last invocation.  Also, if inactivating w has
-     * caused the pool to become quiescent, checks for pool
-     * termination, and, so long as this is not the only worker, waits
-     * for event for up to a given duration.  On timeout, if ctl has
-     * not changed, terminates the worker, which will in turn wake up
+     * If worker w exists and is active, enqueues and sets status to inactive.
+     *
+     * @param w the worker
+     * @param ss current (non-negative) scanState
+     */
+    private void inactivate(WorkQueue w, int ss) {
+        int ns = (ss + SS_SEQ) | UNSIGNALLED;
+        long lc = ns & SP_MASK, nc, c;
+        if (w != null) {
+            w.scanState = ns;
+            do {
+                nc = lc | (UC_MASK & ((c = ctl) - AC_UNIT));
+                w.stackPred = (int)c;
+            } while (!U.compareAndSwapLong(this, CTL, c, nc));
+        }
+    }
+
+    /**
+     * Possibly blocks worker w waiting for signal, or returns
+     * negative status if the worker should terminate. May return
+     * without status change if multiple stale unparks and/or
+     * interrupts occur.
+     *
+     * @param w the calling worker
+     * @return negative if w should terminate
+     */
+    private int awaitWork(WorkQueue w) {
+        int stat = 0;
+        if (w != null && w.scanState < 0) {
+            long c = ctl;
+            if ((int)(c >> AC_SHIFT) + (config & SMASK) <= 0)
+                stat = timedAwaitWork(w, c);     // possibly quiescent
+            else if ((runState & STOP) != 0)
+                stat = w.qlock = -1;             // pool terminating
+            else if (w.scanState < 0) {
+                w.parker = Thread.currentThread();
+                if (w.scanState < 0)             // recheck after write
+                    LockSupport.park(this);
+                w.parker = null;
+                if ((runState & STOP) != 0)
+                    stat = w.qlock = -1;         // recheck
+                else if (w.scanState < 0)
+                    Thread.interrupted();        // clear status
+            }
+        }
+        return stat;
+    }
+
+    /**
+     * Possibly triggers shutdown and tries (once) to block worker
+     * when pool is (or may be) quiescent. Waits up to a duration
+     * determined by number of workers.  On timeout, if ctl has not
+     * changed, terminates the worker, which will in turn wake up
      * another worker to possibly repeat this process.
      *
      * @param w the calling worker
-     * @param c the ctl value on entry to scan
-     * @param ec the worker's eventCount on entry to scan
+     * @return negative if w should terminate
      */
-    private final int awaitWork(WorkQueue w, long c, int ec) {
-        int stat, ns; long parkTime, deadline;
-        if ((stat = w.qlock) >= 0 && w.eventCount == ec && ctl == c &&
-            !Thread.interrupted()) {
-            int e = (int)c;
-            int u = (int)(c >>> 32);
-            int d = (u >> UAC_SHIFT) + parallelism; // active count
-
-            if (e < 0 || (d <= 0 && tryTerminate(false, false)))
-                stat = w.qlock = -1;          // pool is terminating
-            else if ((ns = w.nsteals) != 0) { // collect steals and retry
-                long sc;
-                w.nsteals = 0;
-                do {} while (!U.compareAndSwapLong(this, STEALCOUNT,
-                                                   sc = stealCount, sc + ns));
-            }
-            else {
-                long pc = ((d > 0 || ec != (e | INT_SIGN)) ? 0L :
-                           ((long)(w.nextWait & E_MASK)) | // ctl to restore
-                           ((long)(u + UAC_UNIT)) << 32);
-                if (pc != 0L) {               // timed wait if last waiter
-                    int dc = -(short)(c >>> TC_SHIFT);
-                    parkTime = (dc < 0 ? FAST_IDLE_TIMEOUT:
-                                (dc + 1) * IDLE_TIMEOUT);
-                    deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP;
-                }
-                else
-                    parkTime = deadline = 0L;
-                if (w.eventCount == ec && ctl == c) {
-                    Thread wt = Thread.currentThread();
-                    U.putObject(wt, PARKBLOCKER, this);
-                    w.parker = wt;            // emulate LockSupport.park
-                    if (w.eventCount == ec && ctl == c)
-                        U.park(false, parkTime);  // must recheck before park
-                    w.parker = null;
-                    U.putObject(wt, PARKBLOCKER, null);
-                    if (parkTime != 0L && ctl == c &&
-                        deadline - System.nanoTime() <= 0L &&
-                        U.compareAndSwapLong(this, CTL, c, pc))
-                        stat = w.qlock = -1;  // shrink pool
+    private int timedAwaitWork(WorkQueue w, long c) {
+        int stat = 0;
+        int scale = 1 - (short)(c >>> TC_SHIFT);
+        long deadline = (((scale <= 0) ? 1 : scale) * IDLE_TIMEOUT_MS +
+                         System.currentTimeMillis());
+        if ((runState >= 0 || (stat = tryTerminate(false, false)) > 0) &&
+            w != null && w.scanState < 0) {
+            int ss; AuxState aux;
+            w.parker = Thread.currentThread();
+            if (w.scanState < 0)
+                LockSupport.parkUntil(this, deadline);
+            w.parker = null;
+            if ((runState & STOP) != 0)
+                stat = w.qlock = -1;         // pool terminating
+            else if ((ss = w.scanState) < 0 && !Thread.interrupted() &&
+                     (int)c == ss && (aux = auxState) != null && ctl == c &&
+                     deadline - System.currentTimeMillis() <= TIMEOUT_SLOP_MS) {
+                aux.lock();
+                try {                        // pre-deregister
+                    WorkQueue[] ws;
+                    int cfg = w.config, idx = cfg & SMASK;
+                    long nc = ((UC_MASK & (c - TC_UNIT)) |
+                               (SP_MASK & w.stackPred));
+                    if ((runState & STOP) == 0 &&
+                        (ws = workQueues) != null &&
+                        idx < ws.length && idx >= 0 && ws[idx] == w &&
+                        U.compareAndSwapLong(this, CTL, c, nc)) {
+                        ws[idx] = null;
+                        w.config = cfg | UNREGISTERED;
+                        stat = w.qlock = -1;
+                    }
+                } finally {
+                    aux.unlock();
                 }
             }
         }
@@ -1754,210 +1837,55 @@
     }
 
     /**
-     * Possibly releases (signals) a worker. Called only from scan()
-     * when a worker with apparently inactive status finds a non-empty
-     * queue. This requires revalidating all of the associated state
-     * from caller.
-     */
-    private final void helpRelease(long c, WorkQueue[] ws, WorkQueue w,
-                                   WorkQueue q, int b) {
-        WorkQueue v; int e, i; Thread p;
-        if (w != null && w.eventCount < 0 && (e = (int)c) > 0 &&
-            ws != null && ws.length > (i = e & SMASK) &&
-            (v = ws[i]) != null && ctl == c) {
-            long nc = (((long)(v.nextWait & E_MASK)) |
-                       ((long)((int)(c >>> 32) + UAC_UNIT)) << 32);
-            int ne = (e + E_SEQ) & E_MASK;
-            if (q != null && q.base == b && w.eventCount < 0 &&
-                v.eventCount == (e | INT_SIGN) &&
-                U.compareAndSwapLong(this, CTL, c, nc)) {
-                v.eventCount = ne;
-                if ((p = v.parker) != null)
-                    U.unpark(p);
-            }
-        }
-    }
-
-    /**
-     * Tries to locate and execute tasks for a stealer of the given
-     * task, or in turn one of its stealers, Traces currentSteal ->
-     * currentJoin links looking for a thread working on a descendant
-     * of the given task and with a non-empty queue to steal back and
-     * execute tasks from. The first call to this method upon a
-     * waiting join will often entail scanning/search, (which is OK
-     * because the joiner has nothing better to do), but this method
-     * leaves hints in workers to speed up subsequent calls. The
-     * implementation is very branchy to cope with potential
-     * inconsistencies or loops encountering chains that are stale,
-     * unknown, or so long that they are likely cyclic.
+     * If the given worker is a spare with no queued tasks, and there
+     * are enough existing workers, drops it from ctl counts and sets
+     * its state to terminated.
      *
-     * @param joiner the joining worker
-     * @param task the task to join
-     * @return 0 if no progress can be made, negative if task
-     * known complete, else positive
+     * @param w the calling worker -- must be a spare
+     * @return true if dropped (in which case it must not process more tasks)
      */
-    private int tryHelpStealer(WorkQueue joiner, ForkJoinTask<?> task) {
-        int stat = 0, steps = 0;                    // bound to avoid cycles
-        if (task != null && joiner != null &&
-            joiner.base - joiner.top >= 0) {        // hoist checks
-            restart: for (;;) {
-                ForkJoinTask<?> subtask = task;     // current target
-                for (WorkQueue j = joiner, v;;) {   // v is stealer of subtask
-                    WorkQueue[] ws; int m, s, h;
-                    if ((s = task.status) < 0) {
-                        stat = s;
-                        break restart;
-                    }
-                    if ((ws = workQueues) == null || (m = ws.length - 1) <= 0)
-                        break restart;              // shutting down
-                    if ((v = ws[h = (j.hint | 1) & m]) == null ||
-                        v.currentSteal != subtask) {
-                        for (int origin = h;;) {    // find stealer
-                            if (((h = (h + 2) & m) & 15) == 1 &&
-                                (subtask.status < 0 || j.currentJoin != subtask))
-                                continue restart;   // occasional staleness check
-                            if ((v = ws[h]) != null &&
-                                v.currentSteal == subtask) {
-                                j.hint = h;        // save hint
-                                break;
-                            }
-                            if (h == origin)
-                                break restart;      // cannot find stealer
-                        }
-                    }
-                    for (;;) { // help stealer or descend to its stealer
-                        ForkJoinTask[] a; int b;
-                        if (subtask.status < 0)     // surround probes with
-                            continue restart;       //   consistency checks
-                        if ((b = v.base) - v.top < 0 && (a = v.array) != null) {
-                            int i = (((a.length - 1) & b) << ASHIFT) + ABASE;
-                            ForkJoinTask<?> t =
-                                (ForkJoinTask<?>)U.getObjectVolatile(a, i);
-                            if (subtask.status < 0 || j.currentJoin != subtask ||
-                                v.currentSteal != subtask)
-                                continue restart;   // stale
-                            stat = 1;               // apparent progress
-                            if (v.base == b) {
-                                if (t == null)
-                                    break restart;
-                                if (U.compareAndSwapObject(a, i, t, null)) {
-                                    U.putOrderedInt(v, QBASE, b + 1);
-                                    ForkJoinTask<?> ps = joiner.currentSteal;
-                                    int jt = joiner.top;
-                                    do {
-                                        joiner.currentSteal = t;
-                                        t.doExec(); // clear local tasks too
-                                    } while (task.status >= 0 &&
-                                             joiner.top != jt &&
-                                             (t = joiner.pop()) != null);
-                                    joiner.currentSteal = ps;
-                                    break restart;
-                                }
-                            }
-                        }
-                        else {                      // empty -- try to descend
-                            ForkJoinTask<?> next = v.currentJoin;
-                            if (subtask.status < 0 || j.currentJoin != subtask ||
-                                v.currentSteal != subtask)
-                                continue restart;   // stale
-                            else if (next == null || ++steps == MAX_HELP)
-                                break restart;      // dead-end or maybe cyclic
-                            else {
-                                subtask = next;
-                                j = v;
-                                break;
-                            }
-                        }
-                    }
+    private boolean tryDropSpare(WorkQueue w) {
+        if (w != null && w.isEmpty()) {           // no local tasks
+            long c; int sp, wl; WorkQueue[] ws; WorkQueue v;
+            while ((short)((c = ctl) >> TC_SHIFT) > 0 &&
+                   ((sp = (int)c) != 0 || (int)(c >> AC_SHIFT) > 0) &&
+                   (ws = workQueues) != null && (wl = ws.length) > 0) {
+                boolean dropped, canDrop;
+                if (sp == 0) {                    // no queued workers
+                    long nc = ((AC_MASK & (c - AC_UNIT)) |
+                               (TC_MASK & (c - TC_UNIT)) | (SP_MASK & c));
+                    dropped = U.compareAndSwapLong(this, CTL, c, nc);
                 }
-            }
-        }
-        return stat;
-    }
-
-    /**
-     * Analog of tryHelpStealer for CountedCompleters. Tries to steal
-     * and run tasks within the target's computation.
-     *
-     * @param task the task to join
-     */
-    private int helpComplete(WorkQueue joiner, CountedCompleter<?> task) {
-        WorkQueue[] ws; int m;
-        int s = 0;
-        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
-            joiner != null && task != null) {
-            int j = joiner.poolIndex;
-            int scans = m + m + 1;
-            long c = 0L;              // for stability check
-            for (int k = scans; ; j += 2) {
-                WorkQueue q;
-                if ((s = task.status) < 0)
-                    break;
-                else if (joiner.internalPopAndExecCC(task))
-                    k = scans;
-                else if ((s = task.status) < 0)
-                    break;
-                else if ((q = ws[j & m]) != null && q.pollAndExecCC(task))
-                    k = scans;
-                else if (--k < 0) {
-                    if (c == (c = ctl))
-                        break;
-                    k = scans;
-                }
-            }
-        }
-        return s;
-    }
-
-    /**
-     * Tries to decrement active count (sometimes implicitly) and
-     * possibly release or create a compensating worker in preparation
-     * for blocking. Fails on contention or termination. Otherwise,
-     * adds a new thread if no idle workers are available and pool
-     * may become starved.
-     *
-     * @param c the assumed ctl value
-     */
-    final boolean tryCompensate(long c) {
-        WorkQueue[] ws = workQueues;
-        int pc = parallelism, e = (int)c, m, tc;
-        if (ws != null && (m = ws.length - 1) >= 0 && e >= 0 && ctl == c) {
-            WorkQueue w = ws[e & m];
-            if (e != 0 && w != null) {
-                Thread p;
-                long nc = ((long)(w.nextWait & E_MASK) |
-                           (c & (AC_MASK|TC_MASK)));
-                int ne = (e + E_SEQ) & E_MASK;
-                if (w.eventCount == (e | INT_SIGN) &&
-                    U.compareAndSwapLong(this, CTL, c, nc)) {
-                    w.eventCount = ne;
-                    if ((p = w.parker) != null)
-                        U.unpark(p);
-                    return true;   // replace with idle worker
-                }
-            }
-            else if ((tc = (short)(c >>> TC_SHIFT)) >= 0 &&
-                     (int)(c >> AC_SHIFT) + pc > 1) {
-                long nc = ((c - AC_UNIT) & AC_MASK) | (c & ~AC_MASK);
-                if (U.compareAndSwapLong(this, CTL, c, nc))
-                    return true;   // no compensation
-            }
-            else if (tc + pc < MAX_CAP) {
-                long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK);
-                if (U.compareAndSwapLong(this, CTL, c, nc)) {
-                    ForkJoinWorkerThreadFactory fac;
-                    Throwable ex = null;
-                    ForkJoinWorkerThread wt = null;
-                    try {
-                        if ((fac = factory) != null &&
-                            (wt = fac.newThread(this)) != null) {
-                            wt.start();
-                            return true;
-                        }
-                    } catch (Throwable rex) {
-                        ex = rex;
+                else if (
+                    (v = ws[(wl - 1) & sp]) == null || v.scanState != sp)
+                    dropped = false;              // stale; retry
+                else {
+                    long nc = v.stackPred & SP_MASK;
+                    if (w == v || w.scanState >= 0) {
+                        canDrop = true;           // w unqueued or topmost
+                        nc |= ((AC_MASK & c) |    // ensure replacement
+                               (TC_MASK & (c - TC_UNIT)));
                     }
-                    deregisterWorker(wt, ex); // clean up and return false
+                    else {                        // w may be queued
+                        canDrop = false;          // help uncover
+                        nc |= ((AC_MASK & (c + AC_UNIT)) |
+                               (TC_MASK & c));
+                    }
+                    if (U.compareAndSwapLong(this, CTL, c, nc)) {
+                        v.scanState = sp & ~UNSIGNALLED;
+                        LockSupport.unpark(v.parker);
+                        dropped = canDrop;
+                    }
+                    else
+                        dropped = false;
+                }
+                if (dropped) {                    // pre-deregister
+                    int cfg = w.config, idx = cfg & SMASK;
+                    if (idx >= 0 && idx < ws.length && ws[idx] == w)
+                        ws[idx] = null;
+                    w.config = cfg | UNREGISTERED;
+                    w.qlock = -1;
+                    return true;
                 }
             }
         }
@@ -1965,97 +1893,366 @@
     }
 
     /**
-     * Helps and/or blocks until the given task is done.
+     * Top-level runloop for workers, called by ForkJoinWorkerThread.run.
+     */
+    final void runWorker(WorkQueue w) {
+        w.growArray();                                  // allocate queue
+        int bound = (w.config & SPARE_WORKER) != 0 ? 0 : POLL_LIMIT;
+        long seed = w.hint * 0xdaba0b6eb09322e3L;       // initial random seed
+        if ((runState & STOP) == 0) {
+            for (long r = (seed == 0L) ? 1L : seed;;) { // ensure nonzero
+                if (bound == 0 && tryDropSpare(w))
+                    break;
+                // high bits of prev seed for step; current low bits for idx
+                int step = (int)(r >>> 48) | 1;
+                r ^= r >>> 12; r ^= r << 25; r ^= r >>> 27; // xorshift
+                if (scan(w, bound, step, (int)r) < 0 && awaitWork(w) < 0)
+                    break;
+            }
+        }
+    }
+
+    // Scanning for tasks
+
+    /**
+     * Repeatedly scans for and tries to steal and execute (via
+     * workQueue.runTask) a queued task. Each scan traverses queues in
+     * pseudorandom permutation. Upon finding a non-empty queue, makes
+     * at most the given bound attempts to re-poll (fewer if
+     * contended) on the same queue before returning (impossible
+     * scanState value) 0 to restart scan. Else returns after at least
+     * 1 and at most 32 full scans.
      *
-     * @param joiner the joining worker
-     * @param task the task
+     * @param w the worker (via its WorkQueue)
+     * @param bound repoll bound as bitmask (0 if spare)
+     * @param step (circular) index increment per iteration (must be odd)
+     * @param r a random seed for origin index
+     * @return negative if should await signal
+     */
+    private int scan(WorkQueue w, int bound, int step, int r) {
+        int stat = 0, wl; WorkQueue[] ws;
+        if ((ws = workQueues) != null && w != null && (wl = ws.length) > 0) {
+            for (int m = wl - 1,
+                     origin = m & r, idx = origin,
+                     npolls = 0,
+                     ss = w.scanState;;) {         // negative if inactive
+                WorkQueue q; ForkJoinTask<?>[] a; int b, al;
+                if ((q = ws[idx]) != null && (b = q.base) - q.top < 0 &&
+                    (a = q.array) != null && (al = a.length) > 0) {
+                    int index = (al - 1) & b;
+                    long offset = ((long)index << ASHIFT) + ABASE;
+                    ForkJoinTask<?> t = (ForkJoinTask<?>)
+                        U.getObjectVolatile(a, offset);
+                    if (t == null)
+                        break;                     // empty or busy
+                    else if (b++ != q.base)
+                        break;                     // busy
+                    else if (ss < 0) {
+                        tryReactivate(w, ws, r);
+                        break;                     // retry upon rescan
+                    }
+                    else if (!U.compareAndSwapObject(a, offset, t, null))
+                        break;                     // contended
+                    else {
+                        q.base = b;
+                        w.currentSteal = t;
+                        if (b != q.top)            // propagate signal
+                            signalWork();
+                        w.runTask(t);
+                        if (++npolls > bound)
+                            break;
+                    }
+                }
+                else if (npolls != 0)              // rescan
+                    break;
+                else if ((idx = (idx + step) & m) == origin) {
+                    if (ss < 0) {                  // await signal
+                        stat = ss;
+                        break;
+                    }
+                    else if (r >= 0) {
+                        inactivate(w, ss);
+                        break;
+                    }
+                    else
+                        r <<= 1;                   // at most 31 rescans
+                }
+            }
+        }
+        return stat;
+    }
+
+    // Joining tasks
+
+    /**
+     * Tries to steal and run tasks within the target's computation.
+     * Uses a variant of the top-level algorithm, restricted to tasks
+     * with the given task as ancestor: It prefers taking and running
+     * eligible tasks popped from the worker's own queue (via
+     * popCC). Otherwise it scans others, randomly moving on
+     * contention or execution, deciding to give up based on a
+     * checksum (via return codes from pollAndExecCC). The maxTasks
+     * argument supports external usages; internal calls use zero,
+     * allowing unbounded steps (external calls trap non-positive
+     * values).
+     *
+     * @param w caller
+     * @param maxTasks if non-zero, the maximum number of other tasks to run
      * @return task status on exit
      */
-    final int awaitJoin(WorkQueue joiner, ForkJoinTask<?> task) {
-        int s = 0;
-        if (task != null && (s = task.status) >= 0 && joiner != null) {
-            ForkJoinTask<?> prevJoin = joiner.currentJoin;
-            joiner.currentJoin = task;
-            do {} while (joiner.tryRemoveAndExec(task) && // process local tasks
-                         (s = task.status) >= 0);
-            if (s >= 0 && (task instanceof CountedCompleter))
-                s = helpComplete(joiner, (CountedCompleter<?>)task);
-            long cc = 0;        // for stability checks
-            while (s >= 0 && (s = task.status) >= 0) {
-                if ((s = tryHelpStealer(joiner, task)) == 0 &&
-                    (s = task.status) >= 0) {
-                    if (!tryCompensate(cc))
-                        cc = ctl;
-                    else {
-                        if (task.trySetSignal() && (s = task.status) >= 0) {
-                            synchronized (task) {
-                                if (task.status >= 0) {
-                                    try {                // see ForkJoinTask
-                                        task.wait();     //  for explanation
-                                    } catch (InterruptedException ie) {
-                                    }
-                                }
-                                else
-                                    task.notifyAll();
-                            }
-                        }
-                        long c; // reactivate
-                        do {} while (!U.compareAndSwapLong
-                                     (this, CTL, c = ctl,
-                                      ((c & ~AC_MASK) |
-                                       ((c & AC_MASK) + AC_UNIT))));
+    final int helpComplete(WorkQueue w, CountedCompleter<?> task,
+                           int maxTasks) {
+        WorkQueue[] ws; int s = 0, wl;
+        if ((ws = workQueues) != null && (wl = ws.length) > 1 &&
+            task != null && w != null) {
+            for (int m = wl - 1,
+                     mode = w.config,
+                     r = ~mode,                  // scanning seed
+                     origin = r & m, k = origin, // first queue to scan
+                     step = 3,                   // first scan step
+                     h = 1,                      // 1:ran, >1:contended, <0:hash
+                     oldSum = 0, checkSum = 0;;) {
+                CountedCompleter<?> p; WorkQueue q; int i;
+                if ((s = task.status) < 0)
+                    break;
+                if (h == 1 && (p = w.popCC(task, mode)) != null) {
+                    p.doExec();                  // run local task
+                    if (maxTasks != 0 && --maxTasks == 0)
+                        break;
+                    origin = k;                  // reset
+                    oldSum = checkSum = 0;
+                }
+                else {                           // poll other worker queues
+                    if ((i = k | 1) < 0 || i > m || (q = ws[i]) == null)
+                        h = 0;
+                    else if ((h = q.pollAndExecCC(task)) < 0)
+                        checkSum += h;
+                    if (h > 0) {
+                        if (h == 1 && maxTasks != 0 && --maxTasks == 0)
+                            break;
+                        step = (r >>> 16) | 3;
+                        r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift
+                        k = origin = r & m;      // move and restart
+                        oldSum = checkSum = 0;
+                    }
+                    else if ((k = (k + step) & m) == origin) {
+                        if (oldSum == (oldSum = checkSum))
+                            break;
+                        checkSum = 0;
                     }
                 }
             }
-            joiner.currentJoin = prevJoin;
         }
         return s;
     }
 
     /**
-     * Stripped-down variant of awaitJoin used by timed joins. Tries
-     * to help join only while there is continuous progress. (Caller
-     * will then enter a timed wait.)
+     * Tries to locate and execute tasks for a stealer of the given
+     * task, or in turn one of its stealers. Traces currentSteal ->
+     * currentJoin links looking for a thread working on a descendant
+     * of the given task and with a non-empty queue to steal back and
+     * execute tasks from. The first call to this method upon a
+     * waiting join will often entail scanning/search, (which is OK
+     * because the joiner has nothing better to do), but this method
+     * leaves hints in workers to speed up subsequent calls.
      *
-     * @param joiner the joining worker
-     * @param task the task
+     * @param w caller
+     * @param task the task to join
      */
-    final void helpJoinOnce(WorkQueue joiner, ForkJoinTask<?> task) {
-        int s;
-        if (joiner != null && task != null && (s = task.status) >= 0) {
-            ForkJoinTask<?> prevJoin = joiner.currentJoin;
-            joiner.currentJoin = task;
-            do {} while (joiner.tryRemoveAndExec(task) && // process local tasks
-                         (s = task.status) >= 0);
-            if (s >= 0) {
-                if (task instanceof CountedCompleter)
-                    helpComplete(joiner, (CountedCompleter<?>)task);
-                do {} while (task.status >= 0 &&
-                             tryHelpStealer(joiner, task) > 0);
+    private void helpStealer(WorkQueue w, ForkJoinTask<?> task) {
+        if (task != null && w != null) {
+            ForkJoinTask<?> ps = w.currentSteal;
+            WorkQueue[] ws; int wl, oldSum = 0;
+            outer: while (w.tryRemoveAndExec(task) && task.status >= 0 &&
+                          (ws = workQueues) != null && (wl = ws.length) > 0) {
+                ForkJoinTask<?> subtask;
+                int m = wl - 1, checkSum = 0;          // for stability check
+                WorkQueue j = w, v;                    // v is subtask stealer
+                descent: for (subtask = task; subtask.status >= 0; ) {
+                    for (int h = j.hint | 1, k = 0, i;;) {
+                        if ((v = ws[i = (h + (k << 1)) & m]) != null) {
+                            if (v.currentSteal == subtask) {
+                                j.hint = i;
+                                break;
+                            }
+                            checkSum += v.base;
+                        }
+                        if (++k > m)                   // can't find stealer
+                            break outer;
+                    }
+
+                    for (;;) {                         // help v or descend
+                        ForkJoinTask<?>[] a; int b, al;
+                        if (subtask.status < 0)        // too late to help
+                            break descent;
+                        checkSum += (b = v.base);
+                        ForkJoinTask<?> next = v.currentJoin;
+                        ForkJoinTask<?> t = null;
+                        if ((a = v.array) != null && (al = a.length) > 0) {
+                            int index = (al - 1) & b;
+                            long offset = ((long)index << ASHIFT) + ABASE;
+                            t = (ForkJoinTask<?>)
+                                U.getObjectVolatile(a, offset);
+                            if (t != null && b++ == v.base) {
+                                if (j.currentJoin != subtask ||
+                                    v.currentSteal != subtask ||
+                                    subtask.status < 0)
+                                    break descent;     // stale
+                                if (U.compareAndSwapObject(a, offset, t, null)) {
+                                    v.base = b;
+                                    w.currentSteal = t;
+                                    for (int top = w.top;;) {
+                                        t.doExec();    // help
+                                        w.currentSteal = ps;
+                                        if (task.status < 0)
+                                            break outer;
+                                        if (w.top == top)
+                                            break;     // run local tasks
+                                        if ((t = w.pop()) == null)
+                                            break descent;
+                                        w.currentSteal = t;
+                                    }
+                                }
+                            }
+                        }
+                        if (t == null && b == v.base && b - v.top >= 0) {
+                            if ((subtask = next) == null) {  // try to descend
+                                if (next == v.currentJoin &&
+                                    oldSum == (oldSum = checkSum))
+                                    break outer;
+                                break descent;
+                            }
+                            j = v;
+                            break;
+                        }
+                    }
+                }
             }
-            joiner.currentJoin = prevJoin;
         }
     }
 
     /**
+     * Tries to decrement active count (sometimes implicitly) and
+     * possibly release or create a compensating worker in preparation
+     * for blocking. Returns false (retryable by caller), on
+     * contention, detected staleness, instability, or termination.
+     *
+     * @param w caller
+     */
+    private boolean tryCompensate(WorkQueue w) {
+        boolean canBlock; int wl;
+        long c = ctl;
+        WorkQueue[] ws = workQueues;
+        int pc = config & SMASK;
+        int ac = pc + (int)(c >> AC_SHIFT);
+        int tc = pc + (short)(c >> TC_SHIFT);
+        if (w == null || w.qlock < 0 || pc == 0 ||  // terminating or disabled
+            ws == null || (wl = ws.length) <= 0)
+            canBlock = false;
+        else {
+            int m = wl - 1, sp;
+            boolean busy = true;                    // validate ac
+            for (int i = 0; i <= m; ++i) {
+                int k; WorkQueue v;
+                if ((k = (i << 1) | 1) <= m && k >= 0 && (v = ws[k]) != null &&
+                    v.scanState >= 0 && v.currentSteal == null) {
+                    busy = false;
+                    break;
+                }
+            }
+            if (!busy || ctl != c)
+                canBlock = false;                   // unstable or stale
+            else if ((sp = (int)c) != 0)            // release idle worker
+                canBlock = tryRelease(c, ws[m & sp], 0L);
+            else if (tc >= pc && ac > 1 && w.isEmpty()) {
+                long nc = ((AC_MASK & (c - AC_UNIT)) |
+                           (~AC_MASK & c));         // uncompensated
+                canBlock = U.compareAndSwapLong(this, CTL, c, nc);
+            }
+            else if (tc >= MAX_CAP ||
+                     (this == common && tc >= pc + COMMON_MAX_SPARES))
+                throw new RejectedExecutionException(
+                    "Thread limit exceeded replacing blocked worker");
+            else {                                  // similar to tryAddWorker
+                boolean isSpare = (tc >= pc);
+                long nc = (AC_MASK & c) | (TC_MASK & (c + TC_UNIT));
+                canBlock = (U.compareAndSwapLong(this, CTL, c, nc) &&
+                            createWorker(isSpare)); // throws on exception
+            }
+        }
+        return canBlock;
+    }
+
+    /**
+     * Helps and/or blocks until the given task is done or timeout.
+     *
+     * @param w caller
+     * @param task the task
+     * @param deadline for timed waits, if nonzero
+     * @return task status on exit
+     */
+    final int awaitJoin(WorkQueue w, ForkJoinTask<?> task, long deadline) {
+        int s = 0;
+        if (w != null) {
+            ForkJoinTask<?> prevJoin = w.currentJoin;
+            if (task != null && (s = task.status) >= 0) {
+                w.currentJoin = task;
+                CountedCompleter<?> cc = (task instanceof CountedCompleter) ?
+                    (CountedCompleter<?>)task : null;
+                for (;;) {
+                    if (cc != null)
+                        helpComplete(w, cc, 0);
+                    else
+                        helpStealer(w, task);
+                    if ((s = task.status) < 0)
+                        break;
+                    long ms, ns;
+                    if (deadline == 0L)
+                        ms = 0L;
+                    else if ((ns = deadline - System.nanoTime()) <= 0L)
+                        break;
+                    else if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) <= 0L)
+                        ms = 1L;
+                    if (tryCompensate(w)) {
+                        task.internalWait(ms);
+                        U.getAndAddLong(this, CTL, AC_UNIT);
+                    }
+                    if ((s = task.status) < 0)
+                        break;
+                }
+                w.currentJoin = prevJoin;
+            }
+        }
+        return s;
+    }
+
+    // Specialized scanning
+
+    /**
      * Returns a (probably) non-empty steal queue, if one is found
      * during a scan, else null.  This method must be retried by
      * caller if, by the time it tries to use the queue, it is empty.
      */
     private WorkQueue findNonEmptyStealQueue() {
-        int r = ThreadLocalRandom.current().nextInt();
-        for (;;) {
-            int ps = plock, m; WorkQueue[] ws; WorkQueue q;
-            if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) {
-                for (int j = (m + 1) << 2; j >= 0; --j) {
-                    if ((q = ws[(((r - j) << 1) | 1) & m]) != null &&
-                        q.base - q.top < 0)
+        WorkQueue[] ws; int wl;  // one-shot version of scan loop
+        int r = ThreadLocalRandom.nextSecondarySeed();
+        if ((ws = workQueues) != null && (wl = ws.length) > 0) {
+            int m = wl - 1, origin = r & m;
+            for (int k = origin, oldSum = 0, checkSum = 0;;) {
+                WorkQueue q; int b;
+                if ((q = ws[k]) != null) {
+                    if ((b = q.base) - q.top < 0)
                         return q;
+                    checkSum += b;
+                }
+                if ((k = (k + 1) & m) == origin) {
+                    if (oldSum == (oldSum = checkSum))
+                        break;
+                    checkSum = 0;
                 }
             }
-            if (plock == ps)
-                return null;
         }
+        return null;
     }
 
     /**
@@ -2065,35 +2262,33 @@
      * find tasks either.
      */
     final void helpQuiescePool(WorkQueue w) {
-        ForkJoinTask<?> ps = w.currentSteal;
+        ForkJoinTask<?> ps = w.currentSteal; // save context
+        int wc = w.config;
         for (boolean active = true;;) {
-            long c; WorkQueue q; ForkJoinTask<?> t; int b;
-            while ((t = w.nextLocalTask()) != null)
-                t.doExec();
-            if ((q = findNonEmptyStealQueue()) != null) {
+            long c; WorkQueue q; ForkJoinTask<?> t;
+            if (wc >= 0 && (t = w.pop()) != null) { // run locals if LIFO
+                (w.currentSteal = t).doExec();
+                w.currentSteal = ps;
+            }
+            else if ((q = findNonEmptyStealQueue()) != null) {
                 if (!active) {      // re-establish active count
                     active = true;
-                    do {} while (!U.compareAndSwapLong
-                                 (this, CTL, c = ctl,
-                                  ((c & ~AC_MASK) |
-                                   ((c & AC_MASK) + AC_UNIT))));
+                    U.getAndAddLong(this, CTL, AC_UNIT);
                 }
-                if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) {
+                if ((t = q.pollAt(q.base)) != null) {
                     (w.currentSteal = t).doExec();
                     w.currentSteal = ps;
+                    if (++w.nsteals < 0)
+                        w.transferStealCount(this);
                 }
             }
             else if (active) {      // decrement active count without queuing
-                long nc = ((c = ctl) & ~AC_MASK) | ((c & AC_MASK) - AC_UNIT);
-                if ((int)(nc >> AC_SHIFT) + parallelism == 0)
-                    break;          // bypass decrement-then-increment
+                long nc = (AC_MASK & ((c = ctl) - AC_UNIT)) | (~AC_MASK & c);
                 if (U.compareAndSwapLong(this, CTL, c, nc))
                     active = false;
             }
-            else if ((int)((c = ctl) >> AC_SHIFT) + parallelism <= 0 &&
-                     U.compareAndSwapLong
-                     (this, CTL, c, ((c & ~AC_MASK) |
-                                     ((c & AC_MASK) + AC_UNIT))))
+            else if ((int)((c = ctl) >> AC_SHIFT) + (config & SMASK) <= 0 &&
+                     U.compareAndSwapLong(this, CTL, c, c + AC_UNIT))
                 break;
         }
     }
@@ -2105,12 +2300,12 @@
      */
     final ForkJoinTask<?> nextTaskFor(WorkQueue w) {
         for (ForkJoinTask<?> t;;) {
-            WorkQueue q; int b;
+            WorkQueue q;
             if ((t = w.nextLocalTask()) != null)
                 return t;
             if ((q = findNonEmptyStealQueue()) == null)
                 return null;
-            if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null)
+            if ((t = q.pollAt(q.base)) != null)
                 return t;
         }
     }
@@ -2118,7 +2313,7 @@
     /**
      * Returns a cheap heuristic guide for task partitioning when
      * programmers, frameworks, tools, or languages have little or no
-     * idea about task granularity.  In essence by offering this
+     * idea about task granularity.  In essence, by offering this
      * method, we ask users only about tradeoffs in overhead vs
      * expected throughput and its variance, rather than how finely to
      * partition tasks.
@@ -2156,15 +2351,11 @@
      * many of these by further considering the number of "idle"
      * threads, that are known to have zero queued tasks, so
      * compensate by a factor of (#idle/#active) threads.
-     *
-     * Note: The approximation of #busy workers as #active workers is
-     * not very good under current signalling scheme, and should be
-     * improved.
      */
     static int getSurplusQueuedTaskCount() {
         Thread t; ForkJoinWorkerThread wt; ForkJoinPool pool; WorkQueue q;
-        if (((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)) {
-            int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).parallelism;
+        if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) {
+            int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).config & SMASK;
             int n = (q = wt.workQueue).top - q.base;
             int a = (int)(pool.ctl >> AC_SHIFT) + p;
             return n - (a > (p >>>= 1) ? 0 :
@@ -2179,170 +2370,203 @@
     //  Termination
 
     /**
-     * Possibly initiates and/or completes termination.  The caller
-     * triggering termination runs three passes through workQueues:
-     * (0) Setting termination status, followed by wakeups of queued
-     * workers; (1) cancelling all tasks; (2) interrupting lagging
-     * threads (likely in external tasks, but possibly also blocked in
-     * joins).  Each pass repeats previous steps because of potential
-     * lagging thread creation.
+     * Possibly initiates and/or completes termination.
      *
      * @param now if true, unconditionally terminate, else only
      * if no work and no active workers
-     * @param enable if true, enable shutdown when next possible
-     * @return true if now terminating or terminated
+     * @param enable if true, terminate when next possible
+     * @return -1: terminating/terminated, 0: retry if internal caller, else 1
      */
-    private boolean tryTerminate(boolean now, boolean enable) {
-        int ps;
-        if (this == common)                        // cannot shut down
-            return false;
-        if ((ps = plock) >= 0) {                   // enable by setting plock
-            if (!enable)
-                return false;
-            if ((ps & PL_LOCK) != 0 ||
-                !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-                ps = acquirePlock();
-            int nps = ((ps + PL_LOCK) & ~SHUTDOWN) | SHUTDOWN;
-            if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                releasePlock(nps);
+    private int tryTerminate(boolean now, boolean enable) {
+        int rs; // 3 phases: try to set SHUTDOWN, then STOP, then TERMINATED
+
+        while ((rs = runState) >= 0) {
+            if (!enable || this == common)        // cannot shutdown
+                return 1;
+            else if (rs == 0)
+                tryInitialize(false);             // ensure initialized
+            else
+                U.compareAndSwapInt(this, RUNSTATE, rs, rs | SHUTDOWN);
         }
-        for (long c;;) {
-            if (((c = ctl) & STOP_BIT) != 0) {     // already terminating
-                if ((short)(c >>> TC_SHIFT) + parallelism <= 0) {
-                    synchronized (this) {
-                        notifyAll();               // signal when 0 workers
-                    }
-                }
-                return true;
-            }
-            if (!now) {                            // check if idle & no tasks
-                WorkQueue[] ws; WorkQueue w;
-                if ((int)(c >> AC_SHIFT) + parallelism > 0)
-                    return false;
-                if ((ws = workQueues) != null) {
-                    for (int i = 0; i < ws.length; ++i) {
-                        if ((w = ws[i]) != null &&
-                            (!w.isEmpty() ||
-                             ((i & 1) != 0 && w.eventCount >= 0))) {
-                            signalWork(ws, w);
-                            return false;
+
+        if ((rs & STOP) == 0) {                   // try to initiate termination
+            if (!now) {                           // check quiescence
+                for (long oldSum = 0L;;) {        // repeat until stable
+                    WorkQueue[] ws; WorkQueue w; int b;
+                    long checkSum = ctl;
+                    if ((int)(checkSum >> AC_SHIFT) + (config & SMASK) > 0)
+                        return 0;                 // still active workers
+                    if ((ws = workQueues) != null) {
+                        for (int i = 0; i < ws.length; ++i) {
+                            if ((w = ws[i]) != null) {
+                                checkSum += (b = w.base);
+                                if (w.currentSteal != null || b != w.top)
+                                    return 0;     // retry if internal caller
+                            }
                         }
                     }
+                    if (oldSum == (oldSum = checkSum))
+                        break;
                 }
             }
-            if (U.compareAndSwapLong(this, CTL, c, c | STOP_BIT)) {
-                for (int pass = 0; pass < 3; ++pass) {
-                    WorkQueue[] ws; WorkQueue w; Thread wt;
-                    if ((ws = workQueues) != null) {
-                        int n = ws.length;
-                        for (int i = 0; i < n; ++i) {
-                            if ((w = ws[i]) != null) {
-                                w.qlock = -1;
-                                if (pass > 0) {
-                                    w.cancelAll();
-                                    if (pass > 1 && (wt = w.owner) != null) {
-                                        if (!wt.isInterrupted()) {
-                                            try {
-                                                wt.interrupt();
-                                            } catch (Throwable ignore) {
-                                            }
-                                        }
-                                        U.unpark(wt);
-                                    }
+            do {} while (!U.compareAndSwapInt(this, RUNSTATE,
+                                              rs = runState, rs | STOP));
+        }
+
+        for (long oldSum = 0L;;) {                // repeat until stable
+            WorkQueue[] ws; WorkQueue w; ForkJoinWorkerThread wt;
+            long checkSum = ctl;
+            if ((ws = workQueues) != null) {      // help terminate others
+                for (int i = 0; i < ws.length; ++i) {
+                    if ((w = ws[i]) != null) {
+                        w.cancelAll();            // clear queues
+                        checkSum += w.base;
+                        if (w.qlock >= 0) {
+                            w.qlock = -1;         // racy set OK
+                            if ((wt = w.owner) != null) {
+                                try {             // unblock join or park
+                                    wt.interrupt();
+                                } catch (Throwable ignore) {
                                 }
                             }
                         }
-                        // Wake up workers parked on event queue
-                        int i, e; long cc; Thread p;
-                        while ((e = (int)(cc = ctl) & E_MASK) != 0 &&
-                               (i = e & SMASK) < n && i >= 0 &&
-                               (w = ws[i]) != null) {
-                            long nc = ((long)(w.nextWait & E_MASK) |
-                                       ((cc + AC_UNIT) & AC_MASK) |
-                                       (cc & (TC_MASK|STOP_BIT)));
-                            if (w.eventCount == (e | INT_SIGN) &&
-                                U.compareAndSwapLong(this, CTL, cc, nc)) {
-                                w.eventCount = (e + E_SEQ) & E_MASK;
-                                w.qlock = -1;
-                                if ((p = w.parker) != null)
-                                    U.unpark(p);
-                            }
-                        }
                     }
                 }
             }
+            if (oldSum == (oldSum = checkSum))
+                break;
+        }
+
+        if ((short)(ctl >>> TC_SHIFT) + (config & SMASK) <= 0) {
+            runState = (STARTED | SHUTDOWN | STOP | TERMINATED); // final write
+            synchronized (this) {
+                notifyAll();                      // for awaitTermination
+            }
+        }
+
+        return -1;
+    }
+
+    // External operations
+
+    /**
+     * Constructs and tries to install a new external queue,
+     * failing if the workQueues array already has a queue at
+     * the given index.
+     *
+     * @param index the index of the new queue
+     */
+    private void tryCreateExternalQueue(int index) {
+        AuxState aux;
+        if ((aux = auxState) != null && index >= 0) {
+            WorkQueue q = new WorkQueue(this, null);
+            q.config = index;
+            q.scanState = ~UNSIGNALLED;
+            q.qlock = 1;                   // lock queue
+            boolean installed = false;
+            aux.lock();
+            try {                          // lock pool to install
+                WorkQueue[] ws;
+                if ((ws = workQueues) != null && index < ws.length &&
+                    ws[index] == null) {
+                    ws[index] = q;         // else throw away
+                    installed = true;
+                }
+            } finally {
+                aux.unlock();
+            }
+            if (installed) {
+                try {
+                    q.growArray();
+                } finally {
+                    q.qlock = 0;
+                }
+            }
         }
     }
 
-    // external operations on common pool
+    /**
+     * Adds the given task to a submission queue at submitter's
+     * current queue. Also performs secondary initialization upon the
+     * first submission of the first task to the pool, and detects
+     * first submission by an external thread and creates a new shared
+     * queue if the one at index if empty or contended.
+     *
+     * @param task the task. Caller must ensure non-null.
+     */
+    final void externalPush(ForkJoinTask<?> task) {
+        int r;                            // initialize caller's probe
+        if ((r = ThreadLocalRandom.getProbe()) == 0) {
+            ThreadLocalRandom.localInit();
+            r = ThreadLocalRandom.getProbe();
+        }
+        for (;;) {
+            WorkQueue q; int wl, k, stat;
+            int rs = runState;
+            WorkQueue[] ws = workQueues;
+            if (rs <= 0 || ws == null || (wl = ws.length) <= 0)
+                tryInitialize(true);
+            else if ((q = ws[k = (wl - 1) & r & SQMASK]) == null)
+                tryCreateExternalQueue(k);
+            else if ((stat = q.sharedPush(task)) < 0)
+                break;
+            else if (stat == 0) {
+                signalWork();
+                break;
+            }
+            else                          // move if busy
+                r = ThreadLocalRandom.advanceProbe(r);
+        }
+    }
 
     /**
-     * Returns common pool queue for a thread that has submitted at
-     * least one task.
+     * Pushes a possibly-external submission.
+     */
+    private <T> ForkJoinTask<T> externalSubmit(ForkJoinTask<T> task) {
+        Thread t; ForkJoinWorkerThread w; WorkQueue q;
+        if (task == null)
+            throw new NullPointerException();
+        if (((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) &&
+            (w = (ForkJoinWorkerThread)t).pool == this &&
+            (q = w.workQueue) != null)
+            q.push(task);
+        else
+            externalPush(task);
+        return task;
+    }
+
+    /**
+     * Returns common pool queue for an external thread.
      */
     static WorkQueue commonSubmitterQueue() {
-        Submitter z; ForkJoinPool p; WorkQueue[] ws; int m, r;
-        return ((z = submitters.get()) != null &&
-                (p = common) != null &&
-                (ws = p.workQueues) != null &&
-                (m = ws.length - 1) >= 0) ?
-            ws[m & z.seed & SQMASK] : null;
+        ForkJoinPool p = common;
+        int r = ThreadLocalRandom.getProbe();
+        WorkQueue[] ws; int wl;
+        return (p != null && (ws = p.workQueues) != null &&
+                (wl = ws.length) > 0) ?
+            ws[(wl - 1) & r & SQMASK] : null;
     }
 
     /**
-     * Tries to pop the given task from submitter's queue in common pool.
+     * Performs tryUnpush for an external submitter.
      */
     final boolean tryExternalUnpush(ForkJoinTask<?> task) {
-        WorkQueue joiner; ForkJoinTask<?>[] a; int m, s;
-        Submitter z = submitters.get();
-        WorkQueue[] ws = workQueues;
-        boolean popped = false;
-        if (z != null && ws != null && (m = ws.length - 1) >= 0 &&
-            (joiner = ws[z.seed & m & SQMASK]) != null &&
-            joiner.base != (s = joiner.top) &&
-            (a = joiner.array) != null) {
-            long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
-            if (U.getObject(a, j) == task &&
-                U.compareAndSwapInt(joiner, QLOCK, 0, 1)) {
-                if (joiner.top == s && joiner.array == a &&
-                    U.compareAndSwapObject(a, j, task, null)) {
-                    joiner.top = s - 1;
-                    popped = true;
-                }
-                joiner.qlock = 0;
-            }
-        }
-        return popped;
+        int r = ThreadLocalRandom.getProbe();
+        WorkQueue[] ws; WorkQueue w; int wl;
+        return ((ws = workQueues) != null &&
+                (wl = ws.length) > 0 &&
+                (w = ws[(wl - 1) & r & SQMASK]) != null &&
+                w.trySharedUnpush(task));
     }
 
-    final int externalHelpComplete(CountedCompleter<?> task) {
-        WorkQueue joiner; int m, j;
-        Submitter z = submitters.get();
-        WorkQueue[] ws = workQueues;
-        int s = 0;
-        if (z != null && ws != null && (m = ws.length - 1) >= 0 &&
-            (joiner = ws[(j = z.seed) & m & SQMASK]) != null && task != null) {
-            int scans = m + m + 1;
-            long c = 0L;             // for stability check
-            j |= 1;                  // poll odd queues
-            for (int k = scans; ; j += 2) {
-                WorkQueue q;
-                if ((s = task.status) < 0)
-                    break;
-                else if (joiner.externalPopAndExecCC(task))
-                    k = scans;
-                else if ((s = task.status) < 0)
-                    break;
-                else if ((q = ws[j & m]) != null && q.pollAndExecCC(task))
-                    k = scans;
-                else if (--k < 0) {
-                    if (c == (c = ctl))
-                        break;
-                    k = scans;
-                }
-            }
-        }
-        return s;
+    /**
+     * Performs helpComplete for an external submitter.
+     */
+    final int externalHelpComplete(CountedCompleter<?> task, int maxTasks) {
+        WorkQueue[] ws; int wl;
+        int r = ThreadLocalRandom.getProbe();
+        return ((ws = workQueues) != null && (wl = ws.length) > 0) ?
+            helpComplete(ws[(wl - 1) & r & SQMASK], task, maxTasks) : 0;
     }
 
     // Exported methods
@@ -2354,6 +2578,11 @@
      * java.lang.Runtime#availableProcessors}, using the {@linkplain
      * #defaultForkJoinWorkerThreadFactory default thread factory},
      * no UncaughtExceptionHandler, and non-async LIFO processing mode.
+     *
+     * @throws SecurityException if a security manager exists and
+     *         the caller is not permitted to modify threads
+     *         because it does not hold {@link
+     *         java.lang.RuntimePermission}{@code ("modifyThread")}
      */
     public ForkJoinPool() {
         this(Math.min(MAX_CAP, Runtime.getRuntime().availableProcessors()),
@@ -2369,6 +2598,10 @@
      * @param parallelism the parallelism level
      * @throws IllegalArgumentException if parallelism less than or
      *         equal to zero, or greater than implementation limit
+     * @throws SecurityException if a security manager exists and
+     *         the caller is not permitted to modify threads
+     *         because it does not hold {@link
+     *         java.lang.RuntimePermission}{@code ("modifyThread")}
      */
     public ForkJoinPool(int parallelism) {
         this(parallelism, defaultForkJoinWorkerThreadFactory, null, false);
@@ -2393,6 +2626,10 @@
      * @throws IllegalArgumentException if parallelism less than or
      *         equal to zero, or greater than implementation limit
      * @throws NullPointerException if the factory is null
+     * @throws SecurityException if a security manager exists and
+     *         the caller is not permitted to modify threads
+     *         because it does not hold {@link
+     *         java.lang.RuntimePermission}{@code ("modifyThread")}
      */
     public ForkJoinPool(int parallelism,
                         ForkJoinWorkerThreadFactory factory,
@@ -2401,7 +2638,7 @@
         this(checkParallelism(parallelism),
              checkFactory(factory),
              handler,
-             (asyncMode ? FIFO_QUEUE : LIFO_QUEUE),
+             asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
              "ForkJoinPool-" + nextPoolId() + "-worker-");
         checkPermission();
     }
@@ -2432,8 +2669,7 @@
         this.workerNamePrefix = workerNamePrefix;
         this.factory = factory;
         this.ueh = handler;
-        this.mode = (short)mode;
-        this.parallelism = (short)parallelism;
+        this.config = (parallelism & SMASK) | mode;
         long np = (long)(-parallelism); // offset ctl counts
         this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
     }
@@ -2450,7 +2686,6 @@
      *
      * @return the common pool instance
      * @since 1.8
-     * @hide
      */
     public static ForkJoinPool commonPool() {
         // assert common != null : "static init error";
@@ -2479,7 +2714,7 @@
     public <T> T invoke(ForkJoinTask<T> task) {
         if (task == null)
             throw new NullPointerException();
-        externalPush(task);
+        externalSubmit(task);
         return task.join();
     }
 
@@ -2492,9 +2727,7 @@
      *         scheduled for execution
      */
     public void execute(ForkJoinTask<?> task) {
-        if (task == null)
-            throw new NullPointerException();
-        externalPush(task);
+        externalSubmit(task);
     }
 
     // AbstractExecutorService methods
@@ -2512,7 +2745,7 @@
             job = (ForkJoinTask<?>) task;
         else
             job = new ForkJoinTask.RunnableExecuteAction(task);
-        externalPush(job);
+        externalSubmit(job);
     }
 
     /**
@@ -2526,10 +2759,7 @@
      *         scheduled for execution
      */
     public <T> ForkJoinTask<T> submit(ForkJoinTask<T> task) {
-        if (task == null)
-            throw new NullPointerException();
-        externalPush(task);
-        return task;
+        return externalSubmit(task);
     }
 
     /**
@@ -2538,9 +2768,7 @@
      *         scheduled for execution
      */
     public <T> ForkJoinTask<T> submit(Callable<T> task) {
-        ForkJoinTask<T> job = new ForkJoinTask.AdaptedCallable<T>(task);
-        externalPush(job);
-        return job;
+        return externalSubmit(new ForkJoinTask.AdaptedCallable<T>(task));
     }
 
     /**
@@ -2549,9 +2777,7 @@
      *         scheduled for execution
      */
     public <T> ForkJoinTask<T> submit(Runnable task, T result) {
-        ForkJoinTask<T> job = new ForkJoinTask.AdaptedRunnable<T>(task, result);
-        externalPush(job);
-        return job;
+        return externalSubmit(new ForkJoinTask.AdaptedRunnable<T>(task, result));
     }
 
     /**
@@ -2567,8 +2793,7 @@
             job = (ForkJoinTask<?>) task;
         else
             job = new ForkJoinTask.AdaptedRunnableAction(task);
-        externalPush(job);
-        return job;
+        return externalSubmit(job);
     }
 
     /**
@@ -2579,23 +2804,21 @@
         // In previous versions of this class, this method constructed
         // a task to run ForkJoinTask.invokeAll, but now external
         // invocation of multiple tasks is at least as efficient.
-        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
+        ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
 
-        boolean done = false;
         try {
             for (Callable<T> t : tasks) {
                 ForkJoinTask<T> f = new ForkJoinTask.AdaptedCallable<T>(t);
                 futures.add(f);
-                externalPush(f);
+                externalSubmit(f);
             }
             for (int i = 0, size = futures.size(); i < size; i++)
                 ((ForkJoinTask<?>)futures.get(i)).quietlyJoin();
-            done = true;
             return futures;
-        } finally {
-            if (!done)
-                for (int i = 0, size = futures.size(); i < size; i++)
-                    futures.get(i).cancel(false);
+        } catch (Throwable t) {
+            for (int i = 0, size = futures.size(); i < size; i++)
+                futures.get(i).cancel(false);
+            throw t;
         }
     }
 
@@ -2625,7 +2848,7 @@
      */
     public int getParallelism() {
         int par;
-        return ((par = parallelism) > 0) ? par : 1;
+        return ((par = config & SMASK) > 0) ? par : 1;
     }
 
     /**
@@ -2633,10 +2856,9 @@
      *
      * @return the targeted parallelism level of the common pool
      * @since 1.8
-     * @hide
      */
     public static int getCommonPoolParallelism() {
-        return commonParallelism;
+        return COMMON_PARALLELISM;
     }
 
     /**
@@ -2648,7 +2870,7 @@
      * @return the number of worker threads
      */
     public int getPoolSize() {
-        return parallelism + (short)(ctl >>> TC_SHIFT);
+        return (config & SMASK) + (short)(ctl >>> TC_SHIFT);
     }
 
     /**
@@ -2658,7 +2880,7 @@
      * @return {@code true} if this pool uses async mode
      */
     public boolean getAsyncMode() {
-        return mode == FIFO_QUEUE;
+        return (config & FIFO_QUEUE) != 0;
     }
 
     /**
@@ -2689,7 +2911,7 @@
      * @return the number of active threads
      */
     public int getActiveThreadCount() {
-        int r = parallelism + (int)(ctl >> AC_SHIFT);
+        int r = (config & SMASK) + (int)(ctl >> AC_SHIFT);
         return (r <= 0) ? 0 : r; // suppress momentarily negative values
     }
 
@@ -2705,7 +2927,7 @@
      * @return {@code true} if all threads are currently idle
      */
     public boolean isQuiescent() {
-        return parallelism + (int)(ctl >> AC_SHIFT) <= 0;
+        return (config & SMASK) + (int)(ctl >> AC_SHIFT) <= 0;
     }
 
     /**
@@ -2720,7 +2942,8 @@
      * @return the number of steals
      */
     public long getStealCount() {
-        long count = stealCount;
+        AuxState sc = auxState;
+        long count = (sc == null) ? 0L : sc.stealCount;
         WorkQueue[] ws; WorkQueue w;
         if ((ws = workQueues) != null) {
             for (int i = 1; i < ws.length; i += 2) {
@@ -2797,10 +3020,11 @@
      * @return the next submission, or {@code null} if none
      */
     protected ForkJoinTask<?> pollSubmission() {
-        WorkQueue[] ws; WorkQueue w; ForkJoinTask<?> t;
-        if ((ws = workQueues) != null) {
-            for (int i = 0; i < ws.length; i += 2) {
-                if ((w = ws[i]) != null && (t = w.poll()) != null)
+        WorkQueue[] ws; int wl; WorkQueue w; ForkJoinTask<?> t;
+        int r = ThreadLocalRandom.nextSecondarySeed();
+        if ((ws = workQueues) != null && (wl = ws.length) > 0) {
+            for (int m = wl - 1, i = 0; i < wl; ++i) {
+                if ((w = ws[(i << 1) & m]) != null && (t = w.poll()) != null)
                     return t;
             }
         }
@@ -2850,7 +3074,8 @@
     public String toString() {
         // Use a single pass through workQueues to collect counts
         long qt = 0L, qs = 0L; int rc = 0;
-        long st = stealCount;
+        AuxState sc = auxState;
+        long st = (sc == null) ? 0L : sc.stealCount;
         long c = ctl;
         WorkQueue[] ws; WorkQueue w;
         if ((ws = workQueues) != null) {
@@ -2868,16 +3093,16 @@
                 }
             }
         }
-        int pc = parallelism;
+        int pc = (config & SMASK);
         int tc = pc + (short)(c >>> TC_SHIFT);
         int ac = pc + (int)(c >> AC_SHIFT);
         if (ac < 0) // ignore transient negative
             ac = 0;
-        String level;
-        if ((c & STOP_BIT) != 0)
-            level = (tc == 0) ? "Terminated" : "Terminating";
-        else
-            level = plock < 0 ? "Shutting down" : "Running";
+        int rs = runState;
+        String level = ((rs & TERMINATED) != 0 ? "Terminated" :
+                        (rs & STOP)       != 0 ? "Terminating" :
+                        (rs & SHUTDOWN)   != 0 ? "Shutting down" :
+                        "Running");
         return super.toString() +
             "[" + level +
             ", parallelism = " + pc +
@@ -2894,10 +3119,15 @@
      * Possibly initiates an orderly shutdown in which previously
      * submitted tasks are executed, but no new tasks will be
      * accepted. Invocation has no effect on execution state if this
-     * is the {@code commonPool()}, and no additional effect if
+     * is the {@link #commonPool()}, and no additional effect if
      * already shut down.  Tasks that are in the process of being
      * submitted concurrently during the course of this method may or
      * may not be rejected.
+     *
+     * @throws SecurityException if a security manager exists and
+     *         the caller is not permitted to modify threads
+     *         because it does not hold {@link
+     *         java.lang.RuntimePermission}{@code ("modifyThread")}
      */
     public void shutdown() {
         checkPermission();
@@ -2907,7 +3137,7 @@
     /**
      * Possibly attempts to cancel and/or stop all tasks, and reject
      * all subsequently submitted tasks.  Invocation has no effect on
-     * execution state if this is the {@code commonPool()}, and no
+     * execution state if this is the {@link #commonPool()}, and no
      * additional effect if already shut down. Otherwise, tasks that
      * are in the process of being submitted or executed concurrently
      * during the course of this method may or may not be
@@ -2917,6 +3147,10 @@
      * (unlike the case for some other Executors).
      *
      * @return an empty list
+     * @throws SecurityException if a security manager exists and
+     *         the caller is not permitted to modify threads
+     *         because it does not hold {@link
+     *         java.lang.RuntimePermission}{@code ("modifyThread")}
      */
     public List<Runnable> shutdownNow() {
         checkPermission();
@@ -2930,9 +3164,7 @@
      * @return {@code true} if all tasks have completed following shut down
      */
     public boolean isTerminated() {
-        long c = ctl;
-        return ((c & STOP_BIT) != 0L &&
-                (short)(c >>> TC_SHIFT) + parallelism <= 0);
+        return (runState & TERMINATED) != 0;
     }
 
     /**
@@ -2949,9 +3181,8 @@
      * @return {@code true} if terminating but not yet terminated
      */
     public boolean isTerminating() {
-        long c = ctl;
-        return ((c & STOP_BIT) != 0L &&
-                (short)(c >>> TC_SHIFT) + parallelism > 0);
+        int rs = runState;
+        return (rs & STOP) != 0 && (rs & TERMINATED) == 0;
     }
 
     /**
@@ -2960,14 +3191,14 @@
      * @return {@code true} if this pool has been shut down
      */
     public boolean isShutdown() {
-        return plock < 0;
+        return (runState & SHUTDOWN) != 0;
     }
 
     /**
      * Blocks until all tasks have completed execution after a
      * shutdown request, or the timeout occurs, or the current thread
-     * is interrupted, whichever happens first. Because the {@code
-     * commonPool()} never terminates until program shutdown, when
+     * is interrupted, whichever happens first. Because the {@link
+     * #commonPool()} never terminates until program shutdown, when
      * applied to the common pool, this method is equivalent to {@link
      * #awaitQuiescence(long, TimeUnit)} but always returns {@code false}.
      *
@@ -3026,19 +3257,20 @@
         }
         long startTime = System.nanoTime();
         WorkQueue[] ws;
-        int r = 0, m;
+        int r = 0, wl;
         boolean found = true;
         while (!isQuiescent() && (ws = workQueues) != null &&
-               (m = ws.length - 1) >= 0) {
+               (wl = ws.length) > 0) {
             if (!found) {
                 if ((System.nanoTime() - startTime) > nanos)
                     return false;
                 Thread.yield(); // cannot block
             }
             found = false;
-            for (int j = (m + 1) << 2; j >= 0; --j) {
-                ForkJoinTask<?> t; WorkQueue q; int b;
-                if ((q = ws[r++ & m]) != null && (b = q.base) - q.top < 0) {
+            for (int m = wl - 1, j = (m + 1) << 2; j >= 0; --j) {
+                ForkJoinTask<?> t; WorkQueue q; int b, k;
+                if ((k = r++ & m) <= m && k >= 0 && (q = ws[k]) != null &&
+                    (b = q.base) - q.top < 0) {
                     found = true;
                     if ((t = q.pollAt(b)) != null)
                         t.doExec();
@@ -3051,7 +3283,7 @@
 
     /**
      * Waits and/or attempts to assist performing tasks indefinitely
-     * until the {@code commonPool()} {@link #isQuiescent}.
+     * until the {@link #commonPool()} {@link #isQuiescent}.
      */
     static void quiesceCommonPool() {
         common.awaitQuiescence(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
@@ -3062,8 +3294,8 @@
      * in {@link ForkJoinPool}s.
      *
      * <p>A {@code ManagedBlocker} provides two methods.  Method
-     * {@code isReleasable} must return {@code true} if blocking is
-     * not necessary. Method {@code block} blocks the current thread
+     * {@link #isReleasable} must return {@code true} if blocking is
+     * not necessary. Method {@link #block} blocks the current thread
      * if necessary (perhaps internally invoking {@code isReleasable}
      * before actually blocking). These actions are performed by any
      * thread invoking {@link ForkJoinPool#managedBlock(ManagedBlocker)}.
@@ -3077,7 +3309,7 @@
      *
      * <p>For example, here is a ManagedBlocker based on a
      * ReentrantLock:
-     *  <pre> {@code
+     * <pre> {@code
      * class ManagedLocker implements ManagedBlocker {
      *   final ReentrantLock lock;
      *   boolean hasLock = false;
@@ -3094,7 +3326,7 @@
      *
      * <p>Here is a class that possibly blocks waiting for an
      * item on a given queue:
-     *  <pre> {@code
+     * <pre> {@code
      * class QueueTaker<E> implements ManagedBlocker {
      *   final BlockingQueue<E> queue;
      *   volatile E item = null;
@@ -3132,37 +3364,46 @@
     }
 
     /**
-     * Blocks in accord with the given blocker.  If the current thread
-     * is a {@link ForkJoinWorkerThread}, this method possibly
-     * arranges for a spare thread to be activated if necessary to
-     * ensure sufficient parallelism while the current thread is blocked.
+     * Runs the given possibly blocking task.  When {@linkplain
+     * ForkJoinTask#inForkJoinPool() running in a ForkJoinPool}, this
+     * method possibly arranges for a spare thread to be activated if
+     * necessary to ensure sufficient parallelism while the current
+     * thread is blocked in {@link ManagedBlocker#block blocker.block()}.
      *
-     * <p>If the caller is not a {@link ForkJoinTask}, this method is
+     * <p>This method repeatedly calls {@code blocker.isReleasable()} and
+     * {@code blocker.block()} until either method returns {@code true}.
+     * Every call to {@code blocker.block()} is preceded by a call to
+     * {@code blocker.isReleasable()} that returned {@code false}.
+     *
+     * <p>If not running in a ForkJoinPool, this method is
      * behaviorally equivalent to
-     *  <pre> {@code
+     * <pre> {@code
      * while (!blocker.isReleasable())
      *   if (blocker.block())
-     *     return;
-     * }</pre>
+     *     break;}</pre>
      *
-     * If the caller is a {@code ForkJoinTask}, then the pool may
-     * first be expanded to ensure parallelism, and later adjusted.
+     * If running in a ForkJoinPool, the pool may first be expanded to
+     * ensure sufficient parallelism available during the call to
+     * {@code blocker.block()}.
      *
-     * @param blocker the blocker
-     * @throws InterruptedException if blocker.block did so
+     * @param blocker the blocker task
+     * @throws InterruptedException if {@code blocker.block()} did so
      */
     public static void managedBlock(ManagedBlocker blocker)
         throws InterruptedException {
+        ForkJoinPool p;
+        ForkJoinWorkerThread wt;
         Thread t = Thread.currentThread();
-        if (t instanceof ForkJoinWorkerThread) {
-            ForkJoinPool p = ((ForkJoinWorkerThread)t).pool;
+        if ((t instanceof ForkJoinWorkerThread) &&
+            (p = (wt = (ForkJoinWorkerThread)t).pool) != null) {
+            WorkQueue w = wt.workQueue;
             while (!blocker.isReleasable()) {
-                if (p.tryCompensate(p.ctl)) {
+                if (p.tryCompensate(w)) {
                     try {
                         do {} while (!blocker.isReleasable() &&
                                      !blocker.block());
                     } finally {
-                        p.incrementActiveCount();
+                        U.getAndAddLong(p, CTL, AC_UNIT);
                     }
                     break;
                 }
@@ -3187,49 +3428,40 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
     private static final long CTL;
-    private static final long PARKBLOCKER;
+    private static final long RUNSTATE;
     private static final int ABASE;
     private static final int ASHIFT;
-    private static final long STEALCOUNT;
-    private static final long PLOCK;
-    private static final long INDEXSEED;
-    private static final long QBASE;
-    private static final long QLOCK;
 
     static {
-        // initialize field offsets for CAS etc
         try {
-            U = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = ForkJoinPool.class;
             CTL = U.objectFieldOffset
-                (k.getDeclaredField("ctl"));
-            STEALCOUNT = U.objectFieldOffset
-                (k.getDeclaredField("stealCount"));
-            PLOCK = U.objectFieldOffset
-                (k.getDeclaredField("plock"));
-            INDEXSEED = U.objectFieldOffset
-                (k.getDeclaredField("indexSeed"));
-            Class<?> tk = Thread.class;
-            PARKBLOCKER = U.objectFieldOffset
-                (tk.getDeclaredField("parkBlocker"));
-            Class<?> wk = WorkQueue.class;
-            QBASE = U.objectFieldOffset
-                (wk.getDeclaredField("base"));
-            QLOCK = U.objectFieldOffset
-                (wk.getDeclaredField("qlock"));
-            Class<?> ak = ForkJoinTask[].class;
-            ABASE = U.arrayBaseOffset(ak);
-            int scale = U.arrayIndexScale(ak);
+                (ForkJoinPool.class.getDeclaredField("ctl"));
+            RUNSTATE = U.objectFieldOffset
+                (ForkJoinPool.class.getDeclaredField("runState"));
+            ABASE = U.arrayBaseOffset(ForkJoinTask[].class);
+            int scale = U.arrayIndexScale(ForkJoinTask[].class);
             if ((scale & (scale - 1)) != 0)
-                throw new Error("data type scale not a power of two");
+                throw new Error("array index scale not a power of two");
             ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
-        } catch (Exception e) {
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
 
-        submitters = new ThreadLocal<Submitter>();
+        // Reduce the risk of rare disastrous classloading in first call to
+        // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
+        Class<?> ensureLoaded = LockSupport.class;
+
+        int commonMaxSpares = DEFAULT_COMMON_MAX_SPARES;
+        try {
+            String p = System.getProperty
+                ("java.util.concurrent.ForkJoinPool.common.maximumSpares");
+            if (p != null)
+                commonMaxSpares = Integer.parseInt(p);
+        } catch (Exception ignore) {}
+        COMMON_MAX_SPARES = commonMaxSpares;
+
         defaultForkJoinWorkerThreadFactory =
             new DefaultForkJoinWorkerThreadFactory();
         modifyThreadPermission = new RuntimePermission("modifyThread");
@@ -3237,18 +3469,18 @@
         common = java.security.AccessController.doPrivileged
             (new java.security.PrivilegedAction<ForkJoinPool>() {
                 public ForkJoinPool run() { return makeCommonPool(); }});
-        int par = common.parallelism; // report 1 even if threads disabled
-        commonParallelism = par > 0 ? par : 1;
+
+        // report 1 even if threads disabled
+        COMMON_PARALLELISM = Math.max(common.config & SMASK, 1);
     }
 
     /**
      * Creates and returns the common pool, respecting user settings
      * specified via system properties.
      */
-    private static ForkJoinPool makeCommonPool() {
+    static ForkJoinPool makeCommonPool() {
         int parallelism = -1;
-        ForkJoinWorkerThreadFactory factory
-            = defaultForkJoinWorkerThreadFactory;
+        ForkJoinWorkerThreadFactory factory = null;
         UncaughtExceptionHandler handler = null;
         try {  // ignore exceptions in accessing/parsing properties
             String pp = System.getProperty
@@ -3267,14 +3499,52 @@
                            getSystemClassLoader().loadClass(hp).newInstance());
         } catch (Exception ignore) {
         }
-
+        if (factory == null) {
+            if (System.getSecurityManager() == null)
+                factory = defaultForkJoinWorkerThreadFactory;
+            else // use security-managed default
+                factory = new InnocuousForkJoinWorkerThreadFactory();
+        }
         if (parallelism < 0 && // default 1 less than #cores
-            (parallelism = Runtime.getRuntime().availableProcessors() - 1) < 0)
-            parallelism = 0;
+            (parallelism = Runtime.getRuntime().availableProcessors() - 1) <= 0)
+            parallelism = 1;
         if (parallelism > MAX_CAP)
             parallelism = MAX_CAP;
         return new ForkJoinPool(parallelism, factory, handler, LIFO_QUEUE,
                                 "ForkJoinPool.commonPool-worker-");
     }
 
+    /**
+     * Factory for innocuous worker threads.
+     */
+    private static final class InnocuousForkJoinWorkerThreadFactory
+        implements ForkJoinWorkerThreadFactory {
+
+        /**
+         * An ACC to restrict permissions for the factory itself.
+         * The constructed workers have no permissions set.
+         */
+        private static final AccessControlContext innocuousAcc;
+        static {
+            Permissions innocuousPerms = new Permissions();
+            innocuousPerms.add(modifyThreadPermission);
+            innocuousPerms.add(new RuntimePermission(
+                                   "enableContextClassLoaderOverride"));
+            innocuousPerms.add(new RuntimePermission(
+                                   "modifyThreadGroup"));
+            innocuousAcc = new AccessControlContext(new ProtectionDomain[] {
+                    new ProtectionDomain(null, innocuousPerms)
+                });
+        }
+
+        public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
+            return java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<ForkJoinWorkerThread>() {
+                    public ForkJoinWorkerThread run() {
+                        return new ForkJoinWorkerThread.
+                            InnocuousForkJoinWorkerThread(pool);
+                    }}, innocuousAcc);
+        }
+    }
+
 }
diff --git a/luni/src/main/java/java/util/concurrent/ForkJoinTask.java b/luni/src/main/java/java/util/concurrent/ForkJoinTask.java
index 3a1a381..a8d97db 100644
--- a/luni/src/main/java/java/util/concurrent/ForkJoinTask.java
+++ b/luni/src/main/java/java/util/concurrent/ForkJoinTask.java
@@ -7,13 +7,17 @@
 package java.util.concurrent;
 
 import java.io.Serializable;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
 import java.util.Collection;
 import java.util.List;
 import java.util.RandomAccess;
-import java.lang.ref.WeakReference;
-import java.lang.ref.ReferenceQueue;
 import java.util.concurrent.locks.ReentrantLock;
-import java.lang.reflect.Constructor;
+
+// BEGIN android-note
+// removed java 9 code
+// END android-note
 
 /**
  * Abstract base class for tasks that run within a {@link ForkJoinPool}.
@@ -24,8 +28,8 @@
  *
  * <p>A "main" {@code ForkJoinTask} begins execution when it is
  * explicitly submitted to a {@link ForkJoinPool}, or, if not already
- * engaged in a ForkJoin computation, commenced in the {@code
- * ForkJoinPool.commonPool()} via {@link #fork}, {@link #invoke}, or
+ * engaged in a ForkJoin computation, commenced in the {@link
+ * ForkJoinPool#commonPool()} via {@link #fork}, {@link #invoke}, or
  * related methods.  Once started, it will usually in turn start other
  * subtasks.  As indicated by the name of this class, many programs
  * using {@code ForkJoinTask} employ only methods {@link #fork} and
@@ -66,9 +70,10 @@
  * but doing do requires three further considerations: (1) Completion
  * of few if any <em>other</em> tasks should be dependent on a task
  * that blocks on external synchronization or I/O. Event-style async
- * tasks that are never joined often fall into this category.
- * (2) To minimize resource impact, tasks should be small; ideally
- * performing only the (possibly) blocking action. (3) Unless the {@link
+ * tasks that are never joined (for example, those subclassing {@link
+ * CountedCompleter}) often fall into this category.  (2) To minimize
+ * resource impact, tasks should be small; ideally performing only the
+ * (possibly) blocking action. (3) Unless the {@link
  * ForkJoinPool.ManagedBlocker} API is used, or the number of possibly
  * blocked tasks is known to be less than the pool's {@link
  * ForkJoinPool#getParallelism} level, the pool cannot guarantee that
@@ -111,11 +116,13 @@
  * <p>The ForkJoinTask class is not usually directly subclassed.
  * Instead, you subclass one of the abstract classes that support a
  * particular style of fork/join processing, typically {@link
- * RecursiveAction} for most computations that do not return results
- * and {@link RecursiveTask} for those that do. Normally, a concrete
- * ForkJoinTask subclass declares fields comprising its parameters,
- * established in a constructor, and then defines a {@code compute}
- * method that somehow uses the control methods supplied by this base class.
+ * RecursiveAction} for most computations that do not return results,
+ * {@link RecursiveTask} for those that do, and {@link
+ * CountedCompleter} for those in which completed actions trigger
+ * other actions.  Normally, a concrete ForkJoinTask subclass declares
+ * fields comprising its parameters, established in a constructor, and
+ * then defines a {@code compute} method that somehow uses the control
+ * methods supplied by this base class.
  *
  * <p>Method {@link #join} and its variants are appropriate for use
  * only when completion dependencies are acyclic; that is, the
@@ -127,9 +134,9 @@
  * may be of use in constructing custom subclasses for problems that
  * are not statically structured as DAGs. To support such usages, a
  * ForkJoinTask may be atomically <em>tagged</em> with a {@code short}
- * value using {@code setForkJoinTaskTag} or {@code
- * compareAndSetForkJoinTaskTag} and checked using {@code
- * getForkJoinTaskTag}. The ForkJoinTask implementation does not use
+ * value using {@link #setForkJoinTaskTag} or {@link
+ * #compareAndSetForkJoinTaskTag} and checked using {@link
+ * #getForkJoinTaskTag}. The ForkJoinTask implementation does not use
  * these {@code protected} methods or tags for any purpose, but they
  * may be of use in the construction of specialized subclasses.  For
  * example, parallel graph traversals can use the supplied methods to
@@ -169,8 +176,6 @@
  * @since 1.7
  * @author Doug Lea
  */
-// android-note: Removed references to hidden apis commonPool, CountedCompleter
-// etc.
 public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
 
     /*
@@ -259,15 +264,22 @@
     }
 
     /**
-     * Tries to set SIGNAL status unless already completed. Used by
-     * ForkJoinPool. Other variants are directly incorporated into
-     * externalAwaitDone etc.
+     * If not done, sets SIGNAL status and performs Object.wait(timeout).
+     * This task may or may not be done on exit. Ignores interrupts.
      *
-     * @return true if successful
+     * @param timeout using Object.wait conventions.
      */
-    final boolean trySetSignal() {
-        int s = status;
-        return s >= 0 && U.compareAndSwapInt(this, STATUS, s, s | SIGNAL);
+    final void internalWait(long timeout) {
+        int s;
+        if ((s = status) >= 0 && // force completer to issue notify
+            U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+            synchronized (this) {
+                if (status >= 0)
+                    try { wait(timeout); } catch (InterruptedException ie) { }
+                else
+                    notifyAll();
+            }
+        }
     }
 
     /**
@@ -275,35 +287,29 @@
      * @return status upon completion
      */
     private int externalAwaitDone() {
-        int s;
-        ForkJoinPool cp = ForkJoinPool.common;
-        if ((s = status) >= 0) {
-            if (cp != null) {
-                if (this instanceof CountedCompleter)
-                    s = cp.externalHelpComplete((CountedCompleter<?>)this);
-                else if (cp.tryExternalUnpush(this))
-                    s = doExec();
-            }
-            if (s >= 0 && (s = status) >= 0) {
-                boolean interrupted = false;
-                do {
-                    if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
-                        synchronized (this) {
-                            if (status >= 0) {
-                                try {
-                                    wait();
-                                } catch (InterruptedException ie) {
-                                    interrupted = true;
-                                }
+        int s = ((this instanceof CountedCompleter) ? // try helping
+                 ForkJoinPool.common.externalHelpComplete(
+                     (CountedCompleter<?>)this, 0) :
+                 ForkJoinPool.common.tryExternalUnpush(this) ? doExec() : 0);
+        if (s >= 0 && (s = status) >= 0) {
+            boolean interrupted = false;
+            do {
+                if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+                    synchronized (this) {
+                        if (status >= 0) {
+                            try {
+                                wait(0L);
+                            } catch (InterruptedException ie) {
+                                interrupted = true;
                             }
-                            else
-                                notifyAll();
                         }
+                        else
+                            notifyAll();
                     }
-                } while ((s = status) >= 0);
-                if (interrupted)
-                    Thread.currentThread().interrupt();
-            }
+                }
+            } while ((s = status) >= 0);
+            if (interrupted)
+                Thread.currentThread().interrupt();
         }
         return s;
     }
@@ -313,22 +319,22 @@
      */
     private int externalInterruptibleAwaitDone() throws InterruptedException {
         int s;
-        ForkJoinPool cp = ForkJoinPool.common;
         if (Thread.interrupted())
             throw new InterruptedException();
-        if ((s = status) >= 0 && cp != null) {
-            if (this instanceof CountedCompleter)
-                cp.externalHelpComplete((CountedCompleter<?>)this);
-            else if (cp.tryExternalUnpush(this))
-                doExec();
-        }
-        while ((s = status) >= 0) {
-            if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
-                synchronized (this) {
-                    if (status >= 0)
-                        wait();
-                    else
-                        notifyAll();
+        if ((s = status) >= 0 &&
+            (s = ((this instanceof CountedCompleter) ?
+                  ForkJoinPool.common.externalHelpComplete(
+                      (CountedCompleter<?>)this, 0) :
+                  ForkJoinPool.common.tryExternalUnpush(this) ? doExec() :
+                  0)) >= 0) {
+            while ((s = status) >= 0) {
+                if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+                    synchronized (this) {
+                        if (status >= 0)
+                            wait(0L);
+                        else
+                            notifyAll();
+                    }
                 }
             }
         }
@@ -348,7 +354,7 @@
             ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
             (w = (wt = (ForkJoinWorkerThread)t).workQueue).
             tryUnpush(this) && (s = doExec()) < 0 ? s :
-            wt.pool.awaitJoin(w, this) :
+            wt.pool.awaitJoin(w, this, 0L) :
             externalAwaitDone();
     }
 
@@ -361,7 +367,8 @@
         int s; Thread t; ForkJoinWorkerThread wt;
         return (s = doExec()) < 0 ? s :
             ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
-            (wt = (ForkJoinWorkerThread)t).pool.awaitJoin(wt.workQueue, this) :
+            (wt = (ForkJoinWorkerThread)t).pool.
+            awaitJoin(wt.workQueue, this, 0L) :
             externalAwaitDone();
     }
 
@@ -402,7 +409,8 @@
         ExceptionNode next;
         final long thrower;  // use id not ref to avoid weak cycles
         final int hashCode;  // store task hashCode before weak ref disappears
-        ExceptionNode(ForkJoinTask<?> task, Throwable ex, ExceptionNode next) {
+        ExceptionNode(ForkJoinTask<?> task, Throwable ex, ExceptionNode next,
+                      ReferenceQueue<Object> exceptionTableRefQueue) {
             super(task, exceptionTableRefQueue);
             this.ex = ex;
             this.next = next;
@@ -428,7 +436,8 @@
                 int i = h & (t.length - 1);
                 for (ExceptionNode e = t[i]; ; e = e.next) {
                     if (e == null) {
-                        t[i] = new ExceptionNode(this, ex, t[i]);
+                        t[i] = new ExceptionNode(this, ex, t[i],
+                                                 exceptionTableRefQueue);
                         break;
                     }
                     if (e.get() == this) // already present
@@ -507,22 +516,20 @@
     }
 
     /**
-     * Returns a rethrowable exception for the given task, if
-     * available. To provide accurate stack traces, if the exception
-     * was not thrown by the current thread, we try to create a new
-     * exception of the same type as the one thrown, but with the
-     * recorded exception as its cause. If there is no such
-     * constructor, we instead try to use a no-arg constructor,
-     * followed by initCause, to the same effect. If none of these
-     * apply, or any fail due to other exceptions, we return the
-     * recorded exception, which is still correct, although it may
-     * contain a misleading stack trace.
+     * Returns a rethrowable exception for this task, if available.
+     * To provide accurate stack traces, if the exception was not
+     * thrown by the current thread, we try to create a new exception
+     * of the same type as the one thrown, but with the recorded
+     * exception as its cause. If there is no such constructor, we
+     * instead try to use a no-arg constructor, followed by initCause,
+     * to the same effect. If none of these apply, or any fail due to
+     * other exceptions, we return the recorded exception, which is
+     * still correct, although it may contain a misleading stack
+     * trace.
      *
      * @return the exception, or null if none
      */
     private Throwable getThrowableException() {
-        if ((status & DONE_MASK) != EXCEPTIONAL)
-            return null;
         int h = System.identityHashCode(this);
         ExceptionNode e;
         final ReentrantLock lock = exceptionTableLock;
@@ -539,21 +546,19 @@
         Throwable ex;
         if (e == null || (ex = e.ex) == null)
             return null;
-        if (false && e.thrower != Thread.currentThread().getId()) {
-            Class<? extends Throwable> ec = ex.getClass();
+        if (e.thrower != Thread.currentThread().getId()) {
             try {
                 Constructor<?> noArgCtor = null;
-                Constructor<?>[] cs = ec.getConstructors();// public ctors only
-                for (int i = 0; i < cs.length; ++i) {
-                    Constructor<?> c = cs[i];
+                // public ctors only
+                for (Constructor<?> c : ex.getClass().getConstructors()) {
                     Class<?>[] ps = c.getParameterTypes();
                     if (ps.length == 0)
                         noArgCtor = c;
                     else if (ps.length == 1 && ps[0] == Throwable.class)
-                        return (Throwable)(c.newInstance(ex));
+                        return (Throwable)c.newInstance(ex);
                 }
                 if (noArgCtor != null) {
-                    Throwable wx = (Throwable)(noArgCtor.newInstance());
+                    Throwable wx = (Throwable)noArgCtor.newInstance();
                     wx.initCause(ex);
                     return wx;
                 }
@@ -564,7 +569,7 @@
     }
 
     /**
-     * Poll stale refs and remove them. Call only while holding lock.
+     * Polls stale refs and removes them. Call only while holding lock.
      */
     private static void expungeStaleExceptions() {
         for (Object x; (x = exceptionTableRefQueue.poll()) != null;) {
@@ -591,7 +596,7 @@
     }
 
     /**
-     * If lock is available, poll stale refs and remove them.
+     * If lock is available, polls stale refs and removes them.
      * Called from ForkJoinPool when pools become quiescent.
      */
     static final void helpExpungeStaleExceptions() {
@@ -606,21 +611,23 @@
     }
 
     /**
-     * A version of "sneaky throw" to relay exceptions
+     * A version of "sneaky throw" to relay exceptions.
      */
     static void rethrow(Throwable ex) {
-        if (ex != null)
-            ForkJoinTask.<RuntimeException>uncheckedThrow(ex);
+        ForkJoinTask.<RuntimeException>uncheckedThrow(ex);
     }
 
     /**
      * The sneaky part of sneaky throw, relying on generics
      * limitations to evade compiler complaints about rethrowing
-     * unchecked exceptions
+     * unchecked exceptions.
      */
     @SuppressWarnings("unchecked") static <T extends Throwable>
-        void uncheckedThrow(Throwable t) throws T {
-        throw (T)t; // rely on vacuous cast
+    void uncheckedThrow(Throwable t) throws T {
+        if (t != null)
+            throw (T)t; // rely on vacuous cast
+        else
+            throw new Error("Unknown Exception");
     }
 
     /**
@@ -637,8 +644,8 @@
 
     /**
      * Arranges to asynchronously execute this task in the pool the
-     * current task is running in, if applicable, or using the {@code
-     * ForkJoinPool.commonPool()} if not {@link #inForkJoinPool}.  While
+     * current task is running in, if applicable, or using the {@link
+     * ForkJoinPool#commonPool()} if not {@link #inForkJoinPool}.  While
      * it is not necessarily enforced, it is a usage error to fork a
      * task more than once unless it has completed and been
      * reinitialized.  Subsequent modifications to the state of this
@@ -936,7 +943,6 @@
      * invocations of {@code join} and related operations.
      *
      * @since 1.8
-     * @hide
      */
     public final void quietlyComplete() {
         setCompletion(NORMAL);
@@ -956,11 +962,10 @@
     public final V get() throws InterruptedException, ExecutionException {
         int s = (Thread.currentThread() instanceof ForkJoinWorkerThread) ?
             doJoin() : externalInterruptibleAwaitDone();
-        Throwable ex;
         if ((s &= DONE_MASK) == CANCELLED)
             throw new CancellationException();
-        if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
-            throw new ExecutionException(ex);
+        if (s == EXCEPTIONAL)
+            throw new ExecutionException(getThrowableException());
         return getRawResult();
     }
 
@@ -980,75 +985,46 @@
      */
     public final V get(long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException {
+        int s;
+        long nanos = unit.toNanos(timeout);
         if (Thread.interrupted())
             throw new InterruptedException();
-        // Messy in part because we measure in nanosecs, but wait in millisecs
-        int s; long ms;
-        long ns = unit.toNanos(timeout);
-        ForkJoinPool cp;
-        if ((s = status) >= 0 && ns > 0L) {
-            long deadline = System.nanoTime() + ns;
-            ForkJoinPool p = null;
-            ForkJoinPool.WorkQueue w = null;
+        if ((s = status) >= 0 && nanos > 0L) {
+            long d = System.nanoTime() + nanos;
+            long deadline = (d == 0L) ? 1L : d; // avoid 0
             Thread t = Thread.currentThread();
             if (t instanceof ForkJoinWorkerThread) {
                 ForkJoinWorkerThread wt = (ForkJoinWorkerThread)t;
-                p = wt.pool;
-                w = wt.workQueue;
-                p.helpJoinOnce(w, this); // no retries on failure
+                s = wt.pool.awaitJoin(wt.workQueue, this, deadline);
             }
-            else if ((cp = ForkJoinPool.common) != null) {
-                if (this instanceof CountedCompleter)
-                    cp.externalHelpComplete((CountedCompleter<?>)this);
-                else if (cp.tryExternalUnpush(this))
-                    doExec();
-            }
-            boolean canBlock = false;
-            boolean interrupted = false;
-            try {
-                while ((s = status) >= 0) {
-                    if (w != null && w.qlock < 0)
-                        cancelIgnoringExceptions(this);
-                    else if (!canBlock) {
-                        if (p == null || p.tryCompensate(p.ctl))
-                            canBlock = true;
-                    }
-                    else {
-                        if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) > 0L &&
-                            U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
-                            synchronized (this) {
-                                if (status >= 0) {
-                                    try {
-                                        wait(ms);
-                                    } catch (InterruptedException ie) {
-                                        if (p == null)
-                                            interrupted = true;
-                                    }
-                                }
-                                else
-                                    notifyAll();
-                            }
+            else if ((s = ((this instanceof CountedCompleter) ?
+                           ForkJoinPool.common.externalHelpComplete(
+                               (CountedCompleter<?>)this, 0) :
+                           ForkJoinPool.common.tryExternalUnpush(this) ?
+                           doExec() : 0)) >= 0) {
+                long ns, ms; // measure in nanosecs, but wait in millisecs
+                while ((s = status) >= 0 &&
+                       (ns = deadline - System.nanoTime()) > 0L) {
+                    if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) > 0L &&
+                        U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+                        synchronized (this) {
+                            if (status >= 0)
+                                wait(ms); // OK to throw InterruptedException
+                            else
+                                notifyAll();
                         }
-                        if ((s = status) < 0 || interrupted ||
-                            (ns = deadline - System.nanoTime()) <= 0L)
-                            break;
                     }
                 }
-            } finally {
-                if (p != null && canBlock)
-                    p.incrementActiveCount();
             }
-            if (interrupted)
-                throw new InterruptedException();
         }
+        if (s >= 0)
+            s = status;
         if ((s &= DONE_MASK) != NORMAL) {
-            Throwable ex;
             if (s == CANCELLED)
                 throw new CancellationException();
             if (s != EXCEPTIONAL)
                 throw new TimeoutException();
-            if ((ex = getThrowableException()) != null)
-                throw new ExecutionException(ex);
+            throw new ExecutionException(getThrowableException());
         }
         return getRawResult();
     }
@@ -1074,10 +1050,10 @@
 
     /**
      * Possibly executes tasks until the pool hosting the current task
-     * {@link ForkJoinPool#isQuiescent is quiescent}. This method may
-     * be of use in designs in which many tasks are forked, but none
-     * are explicitly joined, instead executing them until all are
-     * processed.
+     * {@linkplain ForkJoinPool#isQuiescent is quiescent}.  This
+     * method may be of use in designs in which many tasks are forked,
+     * but none are explicitly joined, instead executing them until
+     * all are processed.
      */
     public static void helpQuiesce() {
         Thread t;
@@ -1113,10 +1089,12 @@
     }
 
     /**
-     * Returns the pool hosting the current task execution, or null
-     * if this task is executing outside of any ForkJoinPool.
+     * Returns the pool hosting the current thread, or {@code null}
+     * if the current thread is executing outside of any ForkJoinPool.
      *
-     * @see #inForkJoinPool
+     * <p>This method returns {@code null} if and only if {@link
+     * #inForkJoinPool} returns {@code false}.
+     *
      * @return the pool, or {@code null} if none
      */
     public static ForkJoinPool getPool() {
@@ -1283,6 +1261,25 @@
             null;
     }
 
+    /**
+     * If the current thread is operating in a ForkJoinPool,
+     * unschedules and returns, without executing, a task externally
+     * submitted to the pool, if one is available. Availability may be
+     * transient, so a {@code null} result does not necessarily imply
+     * quiescence of the pool.  This method is designed primarily to
+     * support extensions, and is unlikely to be useful otherwise.
+     *
+     * @return a task, or {@code null} if none are available
+     * @since 9
+     * @hide
+     */
+    // android-changed - hidden
+    protected static ForkJoinTask<?> pollSubmission() {
+        Thread t;
+        return ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
+            ((ForkJoinWorkerThread)t).pool.pollSubmission() : null;
+    }
+
     // tag operations
 
     /**
@@ -1290,24 +1287,22 @@
      *
      * @return the tag for this task
      * @since 1.8
-     * @hide
      */
     public final short getForkJoinTaskTag() {
         return (short)status;
     }
 
     /**
-     * Atomically sets the tag value for this task.
+     * Atomically sets the tag value for this task and returns the old value.
      *
-     * @param tag the tag value
+     * @param newValue the new tag value
      * @return the previous value of the tag
      * @since 1.8
-     * @hide
      */
-    public final short setForkJoinTaskTag(short tag) {
+    public final short setForkJoinTaskTag(short newValue) {
         for (int s;;) {
             if (U.compareAndSwapInt(this, STATUS, s = status,
-                                    (s & ~SMASK) | (tag & SMASK)))
+                                    (s & ~SMASK) | (newValue & SMASK)))
                 return (short)s;
         }
     }
@@ -1320,25 +1315,24 @@
      * before processing, otherwise exiting because the node has
      * already been visited.
      *
-     * @param e the expected tag value
-     * @param tag the new tag value
+     * @param expect the expected tag value
+     * @param update the new tag value
      * @return {@code true} if successful; i.e., the current value was
-     * equal to e and is now tag.
+     * equal to {@code expect} and was changed to {@code update}.
      * @since 1.8
-     * @hide
      */
-    public final boolean compareAndSetForkJoinTaskTag(short e, short tag) {
+    public final boolean compareAndSetForkJoinTaskTag(short expect, short update) {
         for (int s;;) {
-            if ((short)(s = status) != e)
+            if ((short)(s = status) != expect)
                 return false;
             if (U.compareAndSwapInt(this, STATUS, s,
-                                    (s & ~SMASK) | (tag & SMASK)))
+                                    (s & ~SMASK) | (update & SMASK)))
                 return true;
         }
     }
 
     /**
-     * Adaptor for Runnables. This implements RunnableFuture
+     * Adapter for Runnables. This implements RunnableFuture
      * to be compliant with AbstractExecutorService constraints
      * when used in ForkJoinPool.
      */
@@ -1359,7 +1353,7 @@
     }
 
     /**
-     * Adaptor for Runnables without results
+     * Adapter for Runnables without results.
      */
     static final class AdaptedRunnableAction extends ForkJoinTask<Void>
         implements RunnableFuture<Void> {
@@ -1376,7 +1370,7 @@
     }
 
     /**
-     * Adaptor for Runnables in which failure forces worker exception
+     * Adapter for Runnables in which failure forces worker exception.
      */
     static final class RunnableExecuteAction extends ForkJoinTask<Void> {
         final Runnable runnable;
@@ -1394,7 +1388,7 @@
     }
 
     /**
-     * Adaptor for Callables
+     * Adapter for Callables.
      */
     static final class AdaptedCallable<T> extends ForkJoinTask<T>
         implements RunnableFuture<T> {
@@ -1467,6 +1461,8 @@
     /**
      * Saves this task to a stream (that is, serializes it).
      *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData the current run status and the exception thrown
      * during execution, or {@code null} if none
      */
@@ -1478,6 +1474,10 @@
 
     /**
      * Reconstitutes this task from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
@@ -1488,7 +1488,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
     private static final long STATUS;
 
     static {
@@ -1496,12 +1496,11 @@
         exceptionTableRefQueue = new ReferenceQueue<Object>();
         exceptionTable = new ExceptionNode[EXCEPTION_MAP_CAPACITY];
         try {
-            U = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = ForkJoinTask.class;
             STATUS = U.objectFieldOffset
-                (k.getDeclaredField("status"));
-        } catch (Exception e) {
+                (ForkJoinTask.class.getDeclaredField("status"));
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
     }
+
 }
diff --git a/luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java b/luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java
index ae28700..664d56e 100644
--- a/luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java
+++ b/luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java
@@ -6,6 +6,9 @@
 
 package java.util.concurrent;
 
+import java.security.AccessControlContext;
+import java.security.ProtectionDomain;
+
 /**
  * A thread managed by a {@link ForkJoinPool}, which executes
  * {@link ForkJoinTask}s.
@@ -32,6 +35,10 @@
      * completes. This leads to a visibility race, that is tolerated
      * by requiring that the workQueue field is only accessed by the
      * owning thread.
+     *
+     * Support for (non-public) subclass InnocuousForkJoinWorkerThread
+     * requires that we break quite a lot of encapsulation (via Unsafe)
+     * both here and in the subclass to access and set Thread fields.
      */
 
     final ForkJoinPool pool;                // the pool this thread works in
@@ -51,6 +58,18 @@
     }
 
     /**
+     * Version for InnocuousForkJoinWorkerThread.
+     */
+    ForkJoinWorkerThread(ForkJoinPool pool, ThreadGroup threadGroup,
+                         AccessControlContext acc) {
+        super(threadGroup, null, "aForkJoinWorkerThread");
+        U.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, acc);
+        eraseThreadLocals(); // clear before registering
+        this.pool = pool;
+        this.workQueue = pool.registerWorker(this);
+    }
+
+    /**
      * Returns the pool hosting this thread.
      *
      * @return the pool
@@ -70,7 +89,7 @@
      * @return the index number
      */
     public int getPoolIndex() {
-        return workQueue.poolIndex >>> 1; // ignore odd/even tag bit
+        return workQueue.getPoolIndex();
     }
 
     /**
@@ -102,21 +121,124 @@
      * {@link ForkJoinTask}s.
      */
     public void run() {
-        Throwable exception = null;
-        try {
-            onStart();
-            pool.runWorker(workQueue);
-        } catch (Throwable ex) {
-            exception = ex;
-        } finally {
+        if (workQueue.array == null) { // only run once
+            Throwable exception = null;
             try {
-                onTermination(exception);
+                onStart();
+                pool.runWorker(workQueue);
             } catch (Throwable ex) {
-                if (exception == null)
-                    exception = ex;
+                exception = ex;
             } finally {
-                pool.deregisterWorker(this, exception);
+                try {
+                    onTermination(exception);
+                } catch (Throwable ex) {
+                    if (exception == null)
+                        exception = ex;
+                } finally {
+                    pool.deregisterWorker(this, exception);
+                }
             }
         }
     }
+
+    /**
+     * Erases ThreadLocals by nulling out Thread maps.
+     */
+    final void eraseThreadLocals() {
+        U.putObject(this, THREADLOCALS, null);
+        U.putObject(this, INHERITABLETHREADLOCALS, null);
+    }
+
+    /**
+     * Non-public hook method for InnocuousForkJoinWorkerThread.
+     */
+    void afterTopLevelExec() {
+    }
+
+    // Set up to allow setting thread fields in constructor
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long THREADLOCALS;
+    private static final long INHERITABLETHREADLOCALS;
+    private static final long INHERITEDACCESSCONTROLCONTEXT;
+    static {
+        try {
+            THREADLOCALS = U.objectFieldOffset
+                (Thread.class.getDeclaredField("threadLocals"));
+            INHERITABLETHREADLOCALS = U.objectFieldOffset
+                (Thread.class.getDeclaredField("inheritableThreadLocals"));
+            INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset
+                (Thread.class.getDeclaredField("inheritedAccessControlContext"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+
+    /**
+     * A worker thread that has no permissions, is not a member of any
+     * user-defined ThreadGroup, and erases all ThreadLocals after
+     * running each top-level task.
+     */
+    static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread {
+        /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */
+        private static final ThreadGroup innocuousThreadGroup =
+            createThreadGroup();
+
+        /** An AccessControlContext supporting no privileges */
+        private static final AccessControlContext INNOCUOUS_ACC =
+            new AccessControlContext(
+                new ProtectionDomain[] {
+                    new ProtectionDomain(null, null)
+                });
+
+        InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
+            super(pool, innocuousThreadGroup, INNOCUOUS_ACC);
+        }
+
+        @Override // to erase ThreadLocals
+        void afterTopLevelExec() {
+            eraseThreadLocals();
+        }
+
+        @Override // to always report system loader
+        public ClassLoader getContextClassLoader() {
+            return ClassLoader.getSystemClassLoader();
+        }
+
+        @Override // to silently fail
+        public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
+
+        @Override // paranoically
+        public void setContextClassLoader(ClassLoader cl) {
+            throw new SecurityException("setContextClassLoader");
+        }
+
+        /**
+         * Returns a new group with the system ThreadGroup (the
+         * topmost, parent-less group) as parent.  Uses Unsafe to
+         * traverse Thread.group and ThreadGroup.parent fields.
+         */
+        private static ThreadGroup createThreadGroup() {
+            try {
+                sun.misc.Unsafe u = sun.misc.Unsafe.getUnsafe();
+                long tg = u.objectFieldOffset
+                    (Thread.class.getDeclaredField("group"));
+                long gp = u.objectFieldOffset
+                    (ThreadGroup.class.getDeclaredField("parent"));
+                ThreadGroup group = (ThreadGroup)
+                    u.getObject(Thread.currentThread(), tg);
+                while (group != null) {
+                    ThreadGroup parent = (ThreadGroup)u.getObject(group, gp);
+                    if (parent == null)
+                        return new ThreadGroup(group,
+                                               "InnocuousForkJoinWorkerThreadGroup");
+                    group = parent;
+                }
+            } catch (ReflectiveOperationException e) {
+                throw new Error(e);
+            }
+            // fall through if null as cannot-happen safeguard
+            throw new Error("Cannot create ThreadGroup");
+        }
+    }
+
 }
diff --git a/luni/src/main/java/java/util/concurrent/Future.java b/luni/src/main/java/java/util/concurrent/Future.java
index 32e8145..28d2de5 100644
--- a/luni/src/main/java/java/util/concurrent/Future.java
+++ b/luni/src/main/java/java/util/concurrent/Future.java
@@ -23,8 +23,9 @@
  *
  * <p>
  * <b>Sample Usage</b> (Note that the following classes are all
- * made-up.) <p>
- *  <pre> {@code
+ * made-up.)
+ *
+ * <pre> {@code
  * interface ArchiveSearcher { String search(String target); }
  * class App {
  *   ExecutorService executor = ...
@@ -46,9 +47,9 @@
  * The {@link FutureTask} class is an implementation of {@code Future} that
  * implements {@code Runnable}, and so may be executed by an {@code Executor}.
  * For example, the above construction with {@code submit} could be replaced by:
- *  <pre> {@code
+ * <pre> {@code
  * FutureTask<String> future =
- *   new FutureTask<String>(new Callable<String>() {
+ *   new FutureTask<>(new Callable<String>() {
  *     public String call() {
  *       return searcher.search(target);
  *   }});
diff --git a/luni/src/main/java/java/util/concurrent/FutureTask.java b/luni/src/main/java/java/util/concurrent/FutureTask.java
index 5e24fc8..ed42817 100644
--- a/luni/src/main/java/java/util/concurrent/FutureTask.java
+++ b/luni/src/main/java/java/util/concurrent/FutureTask.java
@@ -367,7 +367,7 @@
         throws InterruptedException {
         // The code below is very delicate, to achieve these goals:
         // - call nanoTime exactly once for each call to park
-        // - if nanos <= 0, return promptly without allocation or nanoTime
+        // - if nanos <= 0L, return promptly without allocation or nanoTime
         // - if nanos == Long.MIN_VALUE, don't underflow
         // - if nanos == Long.MAX_VALUE, and nanoTime is non-monotonic
         //   and we suffer a spurious wakeup, we will do no worse than
@@ -467,7 +467,7 @@
                 (FutureTask.class.getDeclaredField("runner"));
             WAITERS = U.objectFieldOffset
                 (FutureTask.class.getDeclaredField("waiters"));
-        } catch (Exception e) {
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
 
diff --git a/luni/src/main/java/java/util/concurrent/Helpers.java b/luni/src/main/java/java/util/concurrent/Helpers.java
new file mode 100644
index 0000000..9051e2f
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/Helpers.java
@@ -0,0 +1,89 @@
+/*
+ * Written by Martin Buchholz 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.Collection;
+
+/** Shared implementation code for java.util.concurrent. */
+class Helpers {
+    private Helpers() {}                // non-instantiable
+
+    /**
+     * An implementation of Collection.toString() suitable for classes
+     * with locks.  Instead of holding a lock for the entire duration of
+     * toString(), or acquiring a lock for each call to Iterator.next(),
+     * we hold the lock only during the call to toArray() (less
+     * disruptive to other threads accessing the collection) and follows
+     * the maxim "Never call foreign code while holding a lock".
+     */
+    static String collectionToString(Collection<?> c) {
+        final Object[] a = c.toArray();
+        final int size = a.length;
+        if (size == 0)
+            return "[]";
+        int charLength = 0;
+
+        // Replace every array element with its string representation
+        for (int i = 0; i < size; i++) {
+            Object e = a[i];
+            // Extreme compatibility with AbstractCollection.toString()
+            String s = (e == c) ? "(this Collection)" : objectToString(e);
+            a[i] = s;
+            charLength += s.length();
+        }
+
+        return toString(a, size, charLength);
+    }
+
+    /**
+     * Like Arrays.toString(), but caller guarantees that size > 0,
+     * each element with index 0 <= i < size is a non-null String,
+     * and charLength is the sum of the lengths of the input Strings.
+     */
+    static String toString(Object[] a, int size, int charLength) {
+        // assert a != null;
+        // assert size > 0;
+
+        // Copy each string into a perfectly sized char[]
+        // Length of [ , , , ] == 2 * size
+        final char[] chars = new char[charLength + 2 * size];
+        chars[0] = '[';
+        int j = 1;
+        for (int i = 0; i < size; i++) {
+            if (i > 0) {
+                chars[j++] = ',';
+                chars[j++] = ' ';
+            }
+            String s = (String) a[i];
+            int len = s.length();
+            s.getChars(0, len, chars, j);
+            j += len;
+        }
+        chars[j] = ']';
+        // assert j == chars.length - 1;
+        return new String(chars);
+    }
+
+    /** Optimized form of: key + "=" + val */
+    static String mapEntryToString(Object key, Object val) {
+        final String k, v;
+        final int klen, vlen;
+        final char[] chars =
+            new char[(klen = (k = objectToString(key)).length()) +
+                     (vlen = (v = objectToString(val)).length()) + 1];
+        k.getChars(0, klen, chars, 0);
+        chars[klen] = '=';
+        v.getChars(0, vlen, chars, klen + 1);
+        return new String(chars);
+    }
+
+    private static String objectToString(Object x) {
+        // Extreme compatibility with StringBuilder.append(null)
+        String s;
+        return (x == null || (s = x.toString()) == null) ? "null" : s;
+    }
+}
diff --git a/luni/src/main/java/java/util/concurrent/LinkedBlockingDeque.java b/luni/src/main/java/java/util/concurrent/LinkedBlockingDeque.java
index 64b0bf1..b1d196d 100644
--- a/luni/src/main/java/java/util/concurrent/LinkedBlockingDeque.java
+++ b/luni/src/main/java/java/util/concurrent/LinkedBlockingDeque.java
@@ -10,8 +10,11 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.Spliterators;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -40,7 +43,7 @@
  *
  * @since 1.6
  * @author  Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this deque
  */
 public class LinkedBlockingDeque<E>
     extends AbstractQueue<E>
@@ -286,8 +289,8 @@
     // BlockingDeque methods
 
     /**
-     * @throws IllegalStateException {@inheritDoc}
-     * @throws NullPointerException  {@inheritDoc}
+     * @throws IllegalStateException if this deque is full
+     * @throws NullPointerException {@inheritDoc}
      */
     public void addFirst(E e) {
         if (!offerFirst(e))
@@ -295,7 +298,7 @@
     }
 
     /**
-     * @throws IllegalStateException {@inheritDoc}
+     * @throws IllegalStateException if this deque is full
      * @throws NullPointerException  {@inheritDoc}
      */
     public void addLast(E e) {
@@ -380,7 +383,7 @@
         lock.lockInterruptibly();
         try {
             while (!linkFirst(node)) {
-                if (nanos <= 0)
+                if (nanos <= 0L)
                     return false;
                 nanos = notFull.awaitNanos(nanos);
             }
@@ -403,7 +406,7 @@
         lock.lockInterruptibly();
         try {
             while (!linkLast(node)) {
-                if (nanos <= 0)
+                if (nanos <= 0L)
                     return false;
                 nanos = notFull.awaitNanos(nanos);
             }
@@ -485,7 +488,7 @@
         try {
             E x;
             while ( (x = unlinkFirst()) == null) {
-                if (nanos <= 0)
+                if (nanos <= 0L)
                     return null;
                 nanos = notEmpty.awaitNanos(nanos);
             }
@@ -503,7 +506,7 @@
         try {
             E x;
             while ( (x = unlinkLast()) == null) {
-                if (nanos <= 0)
+                if (nanos <= 0L)
                     return null;
                 nanos = notEmpty.awaitNanos(nanos);
             }
@@ -594,8 +597,7 @@
      *
      * <p>This method is equivalent to {@link #addLast}.
      *
-     * @throws IllegalStateException if the element cannot be added at this
-     *         time due to capacity restrictions
+     * @throws IllegalStateException if this deque is full
      * @throws NullPointerException if the specified element is null
      */
     public boolean add(E e) {
@@ -732,8 +734,8 @@
     // Stack methods
 
     /**
-     * @throws IllegalStateException {@inheritDoc}
-     * @throws NullPointerException  {@inheritDoc}
+     * @throws IllegalStateException if this deque is full
+     * @throws NullPointerException {@inheritDoc}
      */
     public void push(E e) {
         addFirst(e);
@@ -823,7 +825,7 @@
 //      * @throws ClassCastException            {@inheritDoc}
 //      * @throws NullPointerException          {@inheritDoc}
 //      * @throws IllegalArgumentException      {@inheritDoc}
-//      * @throws IllegalStateException         {@inheritDoc}
+//      * @throws IllegalStateException if this deque is full
 //      * @see #add(Object)
 //      */
 //     public boolean addAll(Collection<? extends E> c) {
@@ -893,7 +895,7 @@
      * The following code can be used to dump the deque into a newly
      * allocated array of {@code String}:
      *
-     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -928,26 +930,7 @@
     }
 
     public String toString() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            Node<E> p = first;
-            if (p == null)
-                return "[]";
-
-            StringBuilder sb = new StringBuilder();
-            sb.append('[');
-            for (;;) {
-                E e = p.item;
-                sb.append(e == this ? "(this Collection)" : e);
-                p = p.next;
-                if (p == null)
-                    return sb.append(']').toString();
-                sb.append(',').append(' ');
-            }
-        } finally {
-            lock.unlock();
-        }
+        return Helpers.collectionToString(this);
     }
 
     /**
@@ -977,12 +960,8 @@
      * Returns an iterator over the elements in this deque in proper sequence.
      * The elements will be returned in order from first (head) to last (tail).
      *
-     * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException}, and guarantees to traverse
-     * elements as they existed upon construction of the iterator, and
-     * may (but is not guaranteed to) reflect any modifications
-     * subsequent to construction.
+     * <p>The returned iterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return an iterator over the elements in this deque in proper sequence
      */
@@ -995,12 +974,8 @@
      * sequential order.  The elements will be returned in order from
      * last (tail) to first (head).
      *
-     * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException}, and guarantees to traverse
-     * elements as they existed upon construction of the iterator, and
-     * may (but is not guaranteed to) reflect any modifications
-     * subsequent to construction.
+     * <p>The returned iterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return an iterator over the elements in this deque in reverse order
      */
@@ -1009,11 +984,11 @@
     }
 
     /**
-     * Base class for Iterators for LinkedBlockingDeque
+     * Base class for LinkedBlockingDeque iterators.
      */
     private abstract class AbstractItr implements Iterator<E> {
         /**
-         * The next node to return in next()
+         * The next node to return in next().
          */
         Node<E> next;
 
@@ -1122,9 +1097,149 @@
         Node<E> nextNode(Node<E> n) { return n.prev; }
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class LBDSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final LinkedBlockingDeque<E> queue;
+        Node<E> current;    // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        long est;           // size estimate
+        LBDSpliterator(LinkedBlockingDeque<E> queue) {
+            this.queue = queue;
+            this.est = queue.size();
+        }
+
+        public long estimateSize() { return est; }
+
+        public Spliterator<E> trySplit() {
+            Node<E> h;
+            final LinkedBlockingDeque<E> q = this.queue;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((h = current) != null || (h = q.first) != null) &&
+                h.next != null) {
+                Object[] a = new Object[n];
+                final ReentrantLock lock = q.lock;
+                int i = 0;
+                Node<E> p = current;
+                lock.lock();
+                try {
+                    if (p != null || (p = q.first) != null) {
+                        do {
+                            if ((a[i] = p.item) != null)
+                                ++i;
+                        } while ((p = p.next) != null && i < n);
+                    }
+                } finally {
+                    lock.unlock();
+                }
+                if ((current = p) == null) {
+                    est = 0L;
+                    exhausted = true;
+                }
+                else if ((est -= i) < 0L)
+                    est = 0L;
+                if (i > 0) {
+                    batch = i;
+                    return Spliterators.spliterator
+                        (a, 0, i, (Spliterator.ORDERED |
+                                   Spliterator.NONNULL |
+                                   Spliterator.CONCURRENT));
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            if (action == null) throw new NullPointerException();
+            final LinkedBlockingDeque<E> q = this.queue;
+            final ReentrantLock lock = q.lock;
+            if (!exhausted) {
+                exhausted = true;
+                Node<E> p = current;
+                do {
+                    E e = null;
+                    lock.lock();
+                    try {
+                        if (p == null)
+                            p = q.first;
+                        while (p != null) {
+                            e = p.item;
+                            p = p.next;
+                            if (e != null)
+                                break;
+                        }
+                    } finally {
+                        lock.unlock();
+                    }
+                    if (e != null)
+                        action.accept(e);
+                } while (p != null);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null) throw new NullPointerException();
+            final LinkedBlockingDeque<E> q = this.queue;
+            final ReentrantLock lock = q.lock;
+            if (!exhausted) {
+                E e = null;
+                lock.lock();
+                try {
+                    if (current == null)
+                        current = q.first;
+                    while (current != null) {
+                        e = current.item;
+                        current = current.next;
+                        if (e != null)
+                            break;
+                    }
+                } finally {
+                    lock.unlock();
+                }
+                if (current == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept(e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
+    /**
+     * Returns a {@link Spliterator} over the elements in this deque.
+     *
+     * <p>The returned spliterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+     *
+     * @implNote
+     * The {@code Spliterator} implements {@code trySplit} to permit limited
+     * parallelism.
+     *
+     * @return a {@code Spliterator} over the elements in this deque
+     * @since 1.8
+     */
+    public Spliterator<E> spliterator() {
+        return new LBDSpliterator<E>(this);
+    }
+
     /**
      * Saves this deque to a stream (that is, serializes it).
      *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData The capacity (int), followed by elements (each an
      * {@code Object}) in the proper order, followed by a null
      */
@@ -1147,6 +1262,10 @@
 
     /**
      * Reconstitutes this deque from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
diff --git a/luni/src/main/java/java/util/concurrent/LinkedBlockingQueue.java b/luni/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
index 0719828..86ed04a 100644
--- a/luni/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
+++ b/luni/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
@@ -6,13 +6,16 @@
 
 package java.util.concurrent;
 
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.ReentrantLock;
 import java.util.AbstractQueue;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -43,7 +46,7 @@
  *
  * @since 1.5
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public class LinkedBlockingQueue<E> extends AbstractQueue<E>
         implements BlockingQueue<E>, java.io.Serializable {
@@ -85,7 +88,7 @@
      */
 
     /**
-     * Linked list node class
+     * Linked list node class.
      */
     static class Node<E> {
         E item;
@@ -348,7 +351,7 @@
         putLock.lockInterruptibly();
         try {
             while (count.get() == capacity) {
-                if (nanos <= 0)
+                if (nanos <= 0L)
                     return false;
                 nanos = notFull.awaitNanos(nanos);
             }
@@ -430,7 +433,7 @@
         takeLock.lockInterruptibly();
         try {
             while (count.get() == 0) {
-                if (nanos <= 0)
+                if (nanos <= 0L)
                     return null;
                 nanos = notEmpty.awaitNanos(nanos);
             }
@@ -475,11 +478,7 @@
         final ReentrantLock takeLock = this.takeLock;
         takeLock.lock();
         try {
-            Node<E> first = head.next;
-            if (first == null)
-                return null;
-            else
-                return first.item;
+            return (count.get() > 0) ? head.next.item : null;
         } finally {
             takeLock.unlock();
         }
@@ -598,7 +597,7 @@
      * The following code can be used to dump the queue into a newly
      * allocated array of {@code String}:
      *
-     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -633,25 +632,7 @@
     }
 
     public String toString() {
-        fullyLock();
-        try {
-            Node<E> p = head.next;
-            if (p == null)
-                return "[]";
-
-            StringBuilder sb = new StringBuilder();
-            sb.append('[');
-            for (;;) {
-                E e = p.item;
-                sb.append(e == this ? "(this Collection)" : e);
-                p = p.next;
-                if (p == null)
-                    return sb.append(']').toString();
-                sb.append(',').append(' ');
-            }
-        } finally {
-            fullyUnlock();
-        }
+        return Helpers.collectionToString(this);
     }
 
     /**
@@ -734,12 +715,8 @@
      * Returns an iterator over the elements in this queue in proper sequence.
      * The elements will be returned in order from first (head) to last (tail).
      *
-     * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException}, and guarantees to traverse
-     * elements as they existed upon construction of the iterator, and
-     * may (but is not guaranteed to) reflect any modifications
-     * subsequent to construction.
+     * <p>The returned iterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return an iterator over the elements in this queue in proper sequence
      */
@@ -773,34 +750,26 @@
             return current != null;
         }
 
-        /**
-         * Returns the next live successor of p, or null if no such.
-         *
-         * Unlike other traversal methods, iterators need to handle both:
-         * - dequeued nodes (p.next == p)
-         * - (possibly multiple) interior removed nodes (p.item == null)
-         */
-        private Node<E> nextNode(Node<E> p) {
-            for (;;) {
-                Node<E> s = p.next;
-                if (s == p)
-                    return head.next;
-                if (s == null || s.item != null)
-                    return s;
-                p = s;
-            }
-        }
-
         public E next() {
             fullyLock();
             try {
                 if (current == null)
                     throw new NoSuchElementException();
-                E x = currentElement;
                 lastRet = current;
-                current = nextNode(current);
-                currentElement = (current == null) ? null : current.item;
-                return x;
+                E item = null;
+                // Unlike other traversal methods, iterators must handle both:
+                // - dequeued nodes (p.next == p)
+                // - (possibly multiple) interior removed nodes (p.item == null)
+                for (Node<E> p = current, q;; p = q) {
+                    if ((q = p.next) == p)
+                        q = head.next;
+                    if (q == null || (item = q.item) != null) {
+                        current = q;
+                        E x = currentElement;
+                        currentElement = item;
+                        return x;
+                    }
+                }
             } finally {
                 fullyUnlock();
             }
@@ -827,9 +796,146 @@
         }
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class LBQSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final LinkedBlockingQueue<E> queue;
+        Node<E> current;    // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        long est;           // size estimate
+        LBQSpliterator(LinkedBlockingQueue<E> queue) {
+            this.queue = queue;
+            this.est = queue.size();
+        }
+
+        public long estimateSize() { return est; }
+
+        public Spliterator<E> trySplit() {
+            Node<E> h;
+            final LinkedBlockingQueue<E> q = this.queue;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((h = current) != null || (h = q.head.next) != null) &&
+                h.next != null) {
+                Object[] a = new Object[n];
+                int i = 0;
+                Node<E> p = current;
+                q.fullyLock();
+                try {
+                    if (p != null || (p = q.head.next) != null) {
+                        do {
+                            if ((a[i] = p.item) != null)
+                                ++i;
+                        } while ((p = p.next) != null && i < n);
+                    }
+                } finally {
+                    q.fullyUnlock();
+                }
+                if ((current = p) == null) {
+                    est = 0L;
+                    exhausted = true;
+                }
+                else if ((est -= i) < 0L)
+                    est = 0L;
+                if (i > 0) {
+                    batch = i;
+                    return Spliterators.spliterator
+                        (a, 0, i, (Spliterator.ORDERED |
+                                   Spliterator.NONNULL |
+                                   Spliterator.CONCURRENT));
+                }
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            if (action == null) throw new NullPointerException();
+            final LinkedBlockingQueue<E> q = this.queue;
+            if (!exhausted) {
+                exhausted = true;
+                Node<E> p = current;
+                do {
+                    E e = null;
+                    q.fullyLock();
+                    try {
+                        if (p == null)
+                            p = q.head.next;
+                        while (p != null) {
+                            e = p.item;
+                            p = p.next;
+                            if (e != null)
+                                break;
+                        }
+                    } finally {
+                        q.fullyUnlock();
+                    }
+                    if (e != null)
+                        action.accept(e);
+                } while (p != null);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null) throw new NullPointerException();
+            final LinkedBlockingQueue<E> q = this.queue;
+            if (!exhausted) {
+                E e = null;
+                q.fullyLock();
+                try {
+                    if (current == null)
+                        current = q.head.next;
+                    while (current != null) {
+                        e = current.item;
+                        current = current.next;
+                        if (e != null)
+                            break;
+                    }
+                } finally {
+                    q.fullyUnlock();
+                }
+                if (current == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept(e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
+    /**
+     * Returns a {@link Spliterator} over the elements in this queue.
+     *
+     * <p>The returned spliterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+     *
+     * @implNote
+     * The {@code Spliterator} implements {@code trySplit} to permit limited
+     * parallelism.
+     *
+     * @return a {@code Spliterator} over the elements in this queue
+     * @since 1.8
+     */
+    public Spliterator<E> spliterator() {
+        return new LBQSpliterator<E>(this);
+    }
+
     /**
      * Saves this queue to a stream (that is, serializes it).
      *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData The capacity is emitted (int), followed by all of
      * its elements (each an {@code Object}) in the proper order,
      * followed by a null
@@ -855,6 +961,10 @@
 
     /**
      * Reconstitutes this queue from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
diff --git a/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java b/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java
index db48420..185ebfd 100644
--- a/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java
+++ b/luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java
@@ -7,11 +7,15 @@
 package java.util.concurrent;
 
 import java.util.AbstractQueue;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 import java.util.Queue;
+import java.util.Spliterator;
+import java.util.Spliterators;
 import java.util.concurrent.locks.LockSupport;
+import java.util.function.Consumer;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -50,7 +54,7 @@
  *
  * @since 1.7
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public class LinkedTransferQueue<E> extends AbstractQueue<E>
     implements TransferQueue<E>, java.io.Serializable {
@@ -182,7 +186,7 @@
      * of costly-to-reclaim garbage caused by the sequential "next"
      * links of nodes starting at old forgotten head nodes: As first
      * described in detail by Boehm
-     * (http://portal.acm.org/citation.cfm?doid=503272.503282) if a GC
+     * (http://portal.acm.org/citation.cfm?doid=503272.503282), if a GC
      * delays noticing that any arbitrarily old node has become
      * garbage, all newer dead nodes will also be unreclaimed.
      * (Similar issues arise in non-GC environments.)  To cope with
@@ -423,12 +427,12 @@
 
         // CAS methods for fields
         final boolean casNext(Node cmp, Node val) {
-            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
+            return U.compareAndSwapObject(this, NEXT, cmp, val);
         }
 
         final boolean casItem(Object cmp, Object val) {
             // assert cmp == null || cmp.getClass() != Node.class;
-            return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
+            return U.compareAndSwapObject(this, ITEM, cmp, val);
         }
 
         /**
@@ -436,7 +440,7 @@
          * only be seen after publication via casNext.
          */
         Node(Object item, boolean isData) {
-            UNSAFE.putObject(this, itemOffset, item); // relaxed write
+            U.putObject(this, ITEM, item); // relaxed write
             this.isData = isData;
         }
 
@@ -445,7 +449,7 @@
          * only after CASing head field, so uses relaxed write.
          */
         final void forgetNext() {
-            UNSAFE.putObject(this, nextOffset, this);
+            U.putObject(this, NEXT, this);
         }
 
         /**
@@ -458,8 +462,8 @@
          * else we don't care).
          */
         final void forgetContents() {
-            UNSAFE.putObject(this, itemOffset, this);
-            UNSAFE.putObject(this, waiterOffset, null);
+            U.putObject(this, ITEM, this);
+            U.putObject(this, WAITER, null);
         }
 
         /**
@@ -505,21 +509,19 @@
         private static final long serialVersionUID = -3375979862319811754L;
 
         // Unsafe mechanics
-        private static final sun.misc.Unsafe UNSAFE;
-        private static final long itemOffset;
-        private static final long nextOffset;
-        private static final long waiterOffset;
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final long ITEM;
+        private static final long NEXT;
+        private static final long WAITER;
         static {
             try {
-                UNSAFE = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = Node.class;
-                itemOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("item"));
-                nextOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("next"));
-                waiterOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("waiter"));
-            } catch (Exception e) {
+                ITEM = U.objectFieldOffset
+                    (Node.class.getDeclaredField("item"));
+                NEXT = U.objectFieldOffset
+                    (Node.class.getDeclaredField("next"));
+                WAITER = U.objectFieldOffset
+                    (Node.class.getDeclaredField("waiter"));
+            } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
         }
@@ -536,15 +538,15 @@
 
     // CAS methods for fields
     private boolean casTail(Node cmp, Node val) {
-        return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
+        return U.compareAndSwapObject(this, TAIL, cmp, val);
     }
 
     private boolean casHead(Node cmp, Node val) {
-        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
+        return U.compareAndSwapObject(this, HEAD, cmp, val);
     }
 
     private boolean casSweepVotes(int cmp, int val) {
-        return UNSAFE.compareAndSwapInt(this, sweepVotesOffset, cmp, val);
+        return U.compareAndSwapInt(this, SWEEPVOTES, cmp, val);
     }
 
     /*
@@ -555,12 +557,6 @@
     private static final int SYNC  = 2; // for transfer, take
     private static final int TIMED = 3; // for timed poll, tryTransfer
 
-    @SuppressWarnings("unchecked")
-    static <E> E cast(Object item) {
-        // assert item == null || item.getClass() != Node.class;
-        return (E) item;
-    }
-
     /**
      * Implements all queuing methods. See above for explanation.
      *
@@ -597,7 +593,8 @@
                                 break;        // unless slack < 2
                         }
                         LockSupport.unpark(p.waiter);
-                        return LinkedTransferQueue.<E>cast(item);
+                        @SuppressWarnings("unchecked") E itemE = (E) item;
+                        return itemE;
                     }
                 }
                 Node n = p.next;
@@ -675,15 +672,15 @@
             if (item != e) {                  // matched
                 // assert item != s;
                 s.forgetContents();           // avoid garbage
-                return LinkedTransferQueue.<E>cast(item);
+                @SuppressWarnings("unchecked") E itemE = (E) item;
+                return itemE;
             }
-            if ((w.isInterrupted() || (timed && nanos <= 0)) &&
-                    s.casItem(e, s)) {        // cancel
-                unsplice(pred, s);
-                return e;
+            else if (w.isInterrupted() || (timed && nanos <= 0L)) {
+                unsplice(pred, s);           // try to unlink and cancel
+                if (s.casItem(e, s))         // return normally if lost CAS
+                    return e;
             }
-
-            if (spins < 0) {                  // establish spins at/near front
+            else if (spins < 0) {            // establish spins at/near front
                 if ((spins = spinsFor(pred, s.isData)) > 0)
                     randomYields = ThreadLocalRandom.current();
             }
@@ -735,32 +732,25 @@
     }
 
     /**
-     * Returns the first unmatched node of the given mode, or null if
-     * none.  Used by methods isEmpty, hasWaitingConsumer.
+     * Returns the first unmatched data node, or null if none.
+     * Callers must recheck if the returned node's item field is null
+     * or self-linked before using.
      */
-    private Node firstOfMode(boolean isData) {
-        for (Node p = head; p != null; p = succ(p)) {
-            if (!p.isMatched())
-                return (p.isData == isData) ? p : null;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the item in the first unmatched node with isData; or
-     * null if none.  Used by peek.
-     */
-    private E firstDataItem() {
-        for (Node p = head; p != null; p = succ(p)) {
-            Object item = p.item;
-            if (p.isData) {
-                if (item != null && item != p)
-                    return LinkedTransferQueue.<E>cast(item);
+    final Node firstDataNode() {
+        restartFromHead: for (;;) {
+            for (Node p = head; p != null;) {
+                Object item = p.item;
+                if (p.isData) {
+                    if (item != null && item != p)
+                        return p;
+                }
+                else if (item == null)
+                    break;
+                if (p == (p = p.next))
+                    continue restartFromHead;
             }
-            else if (item == null)
-                return null;
+            return null;
         }
-        return null;
     }
 
     /**
@@ -768,23 +758,140 @@
      * Used by methods size and getWaitingConsumerCount.
      */
     private int countOfMode(boolean data) {
-        int count = 0;
-        for (Node p = head; p != null; ) {
-            if (!p.isMatched()) {
-                if (p.isData != data)
-                    return 0;
-                if (++count == Integer.MAX_VALUE) // saturated
-                    break;
+        restartFromHead: for (;;) {
+            int count = 0;
+            for (Node p = head; p != null;) {
+                if (!p.isMatched()) {
+                    if (p.isData != data)
+                        return 0;
+                    if (++count == Integer.MAX_VALUE)
+                        break;  // @see Collection.size()
+                }
+                if (p == (p = p.next))
+                    continue restartFromHead;
             }
-            Node n = p.next;
-            if (n != p)
-                p = n;
-            else {
-                count = 0;
-                p = head;
-            }
+            return count;
         }
-        return count;
+    }
+
+    public String toString() {
+        String[] a = null;
+        restartFromHead: for (;;) {
+            int charLength = 0;
+            int size = 0;
+            for (Node p = head; p != null;) {
+                Object item = p.item;
+                if (p.isData) {
+                    if (item != null && item != p) {
+                        if (a == null)
+                            a = new String[4];
+                        else if (size == a.length)
+                            a = Arrays.copyOf(a, 2 * size);
+                        String s = item.toString();
+                        a[size++] = s;
+                        charLength += s.length();
+                    }
+                } else if (item == null)
+                    break;
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+
+            if (size == 0)
+                return "[]";
+
+            return Helpers.toString(a, size, charLength);
+        }
+    }
+
+    private Object[] toArrayInternal(Object[] a) {
+        Object[] x = a;
+        restartFromHead: for (;;) {
+            int size = 0;
+            for (Node p = head; p != null;) {
+                Object item = p.item;
+                if (p.isData) {
+                    if (item != null && item != p) {
+                        if (x == null)
+                            x = new Object[4];
+                        else if (size == x.length)
+                            x = Arrays.copyOf(x, 2 * (size + 4));
+                        x[size++] = item;
+                    }
+                } else if (item == null)
+                    break;
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+            if (x == null)
+                return new Object[0];
+            else if (a != null && size <= a.length) {
+                if (a != x)
+                    System.arraycopy(x, 0, a, 0, size);
+                if (size < a.length)
+                    a[size] = null;
+                return a;
+            }
+            return (size == x.length) ? x : Arrays.copyOf(x, size);
+        }
+    }
+
+    /**
+     * Returns an array containing all of the elements in this queue, in
+     * proper sequence.
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this queue.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this queue
+     */
+    public Object[] toArray() {
+        return toArrayInternal(null);
+    }
+
+    /**
+     * Returns an array containing all of the elements in this queue, in
+     * proper sequence; the runtime type of the returned array is that of
+     * the specified array.  If the queue fits in the specified array, it
+     * is returned therein.  Otherwise, a new array is allocated with the
+     * runtime type of the specified array and the size of this queue.
+     *
+     * <p>If this queue fits in the specified array with room to spare
+     * (i.e., the array has more elements than this queue), the element in
+     * the array immediately following the end of the queue is set to
+     * {@code null}.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose {@code x} is a queue known to contain only strings.
+     * The following code can be used to dump the queue into a newly
+     * allocated array of {@code String}:
+     *
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     *
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
+     *
+     * @param a the array into which the elements of the queue are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose
+     * @return an array containing all of the elements in this queue
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this queue
+     * @throws NullPointerException if the specified array is null
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T[] toArray(T[] a) {
+        if (a == null) throw new NullPointerException();
+        return (T[]) toArrayInternal(a);
     }
 
     final class Itr implements Iterator<E> {
@@ -833,7 +940,8 @@
                 Object item = s.item;
                 if (s.isData) {
                     if (item != null && item != s) {
-                        nextItem = LinkedTransferQueue.<E>cast(item);
+                        @SuppressWarnings("unchecked") E itemE = (E) item;
+                        nextItem = itemE;
                         nextNode = s;
                         return;
                     }
@@ -880,6 +988,111 @@
         }
     }
 
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    final class LTQSpliterator<E> implements Spliterator<E> {
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        Node current;       // current node; null until initialized
+        int batch;          // batch size for splits
+        boolean exhausted;  // true when no more nodes
+        LTQSpliterator() {}
+
+        public Spliterator<E> trySplit() {
+            Node p;
+            int b = batch;
+            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
+            if (!exhausted &&
+                ((p = current) != null || (p = firstDataNode()) != null) &&
+                p.next != null) {
+                Object[] a = new Object[n];
+                int i = 0;
+                do {
+                    Object e = p.item;
+                    if (e != p && (a[i] = e) != null)
+                        ++i;
+                    if (p == (p = p.next))
+                        p = firstDataNode();
+                } while (p != null && i < n && p.isData);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (i > 0) {
+                    batch = i;
+                    return Spliterators.spliterator
+                        (a, 0, i, (Spliterator.ORDERED |
+                                   Spliterator.NONNULL |
+                                   Spliterator.CONCURRENT));
+                }
+            }
+            return null;
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super E> action) {
+            Node p;
+            if (action == null) throw new NullPointerException();
+            if (!exhausted &&
+                ((p = current) != null || (p = firstDataNode()) != null)) {
+                exhausted = true;
+                do {
+                    Object e = p.item;
+                    if (e != null && e != p)
+                        action.accept((E)e);
+                    if (p == (p = p.next))
+                        p = firstDataNode();
+                } while (p != null && p.isData);
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        public boolean tryAdvance(Consumer<? super E> action) {
+            Node p;
+            if (action == null) throw new NullPointerException();
+            if (!exhausted &&
+                ((p = current) != null || (p = firstDataNode()) != null)) {
+                Object e;
+                do {
+                    if ((e = p.item) == p)
+                        e = null;
+                    if (p == (p = p.next))
+                        p = firstDataNode();
+                } while (e == null && p != null && p.isData);
+                if ((current = p) == null)
+                    exhausted = true;
+                if (e != null) {
+                    action.accept((E)e);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public long estimateSize() { return Long.MAX_VALUE; }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.NONNULL |
+                Spliterator.CONCURRENT;
+        }
+    }
+
+    /**
+     * Returns a {@link Spliterator} over the elements in this queue.
+     *
+     * <p>The returned spliterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
+     * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
+     *
+     * @implNote
+     * The {@code Spliterator} implements {@code trySplit} to permit limited
+     * parallelism.
+     *
+     * @return a {@code Spliterator} over the elements in this queue
+     * @since 1.8
+     */
+    public Spliterator<E> spliterator() {
+        return new LTQSpliterator<E>();
+    }
+
     /* -------------- Removal methods -------------- */
 
     /**
@@ -891,7 +1104,7 @@
      * @param s the node to be unspliced
      */
     final void unsplice(Node pred, Node s) {
-        s.forgetContents(); // forget unneeded fields
+        s.waiter = null; // disable signals
         /*
          * See above for rationale. Briefly: if pred still points to
          * s, try to unlink s.  If s cannot be unlinked, because it is
@@ -1159,12 +1372,8 @@
      * Returns an iterator over the elements in this queue in proper sequence.
      * The elements will be returned in order from first (head) to last (tail).
      *
-     * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException}, and guarantees to traverse
-     * elements as they existed upon construction of the iterator, and
-     * may (but is not guaranteed to) reflect any modifications
-     * subsequent to construction.
+     * <p>The returned iterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return an iterator over the elements in this queue in proper sequence
      */
@@ -1173,7 +1382,22 @@
     }
 
     public E peek() {
-        return firstDataItem();
+        restartFromHead: for (;;) {
+            for (Node p = head; p != null;) {
+                Object item = p.item;
+                if (p.isData) {
+                    if (item != null && item != p) {
+                        @SuppressWarnings("unchecked") E e = (E) item;
+                        return e;
+                    }
+                }
+                else if (item == null)
+                    break;
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+            return null;
+        }
     }
 
     /**
@@ -1182,15 +1406,24 @@
      * @return {@code true} if this queue contains no elements
      */
     public boolean isEmpty() {
-        for (Node p = head; p != null; p = succ(p)) {
-            if (!p.isMatched())
-                return !p.isData;
-        }
-        return true;
+        return firstDataNode() == null;
     }
 
     public boolean hasWaitingConsumer() {
-        return firstOfMode(false) != null;
+        restartFromHead: for (;;) {
+            for (Node p = head; p != null;) {
+                Object item = p.item;
+                if (p.isData) {
+                    if (item != null && item != p)
+                        break;
+                }
+                else if (item == null)
+                    return true;
+                if (p == (p = p.next))
+                    continue restartFromHead;
+            }
+            return false;
+        }
     }
 
     /**
@@ -1237,15 +1470,16 @@
      * @return {@code true} if this queue contains the specified element
      */
     public boolean contains(Object o) {
-        if (o == null) return false;
-        for (Node p = head; p != null; p = succ(p)) {
-            Object item = p.item;
-            if (p.isData) {
-                if (item != null && item != p && o.equals(item))
-                    return true;
+        if (o != null) {
+            for (Node p = head; p != null; p = succ(p)) {
+                Object item = p.item;
+                if (p.isData) {
+                    if (item != null && item != p && o.equals(item))
+                        return true;
+                }
+                else if (item == null)
+                    break;
             }
-            else if (item == null)
-                break;
         }
         return false;
     }
@@ -1265,6 +1499,8 @@
     /**
      * Saves this queue to a stream (that is, serializes it).
      *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData All of the elements (each an {@code E}) in
      * the proper order, followed by a null
      */
@@ -1279,6 +1515,10 @@
 
     /**
      * Reconstitutes this queue from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
@@ -1295,21 +1535,19 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe UNSAFE;
-    private static final long headOffset;
-    private static final long tailOffset;
-    private static final long sweepVotesOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long HEAD;
+    private static final long TAIL;
+    private static final long SWEEPVOTES;
     static {
         try {
-            UNSAFE = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = LinkedTransferQueue.class;
-            headOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("head"));
-            tailOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("tail"));
-            sweepVotesOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("sweepVotes"));
-        } catch (Exception e) {
+            HEAD = U.objectFieldOffset
+                (LinkedTransferQueue.class.getDeclaredField("head"));
+            TAIL = U.objectFieldOffset
+                (LinkedTransferQueue.class.getDeclaredField("tail"));
+            SWEEPVOTES = U.objectFieldOffset
+                (LinkedTransferQueue.class.getDeclaredField("sweepVotes"));
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
 
diff --git a/luni/src/main/java/java/util/concurrent/Phaser.java b/luni/src/main/java/java/util/concurrent/Phaser.java
index c5faf16..9b2a7a1 100644
--- a/luni/src/main/java/java/util/concurrent/Phaser.java
+++ b/luni/src/main/java/java/util/concurrent/Phaser.java
@@ -42,7 +42,7 @@
  *
  * <ul>
  *
- *   <li> <b>Arrival.</b> Methods {@link #arrive} and
+ *   <li><b>Arrival.</b> Methods {@link #arrive} and
  *       {@link #arriveAndDeregister} record arrival.  These methods
  *       do not block, but return an associated <em>arrival phase
  *       number</em>; that is, the phase number of the phaser to which
@@ -55,7 +55,7 @@
  *       flexible than, providing a barrier action to a {@code
  *       CyclicBarrier}.
  *
- *   <li> <b>Waiting.</b> Method {@link #awaitAdvance} requires an
+ *   <li><b>Waiting.</b> Method {@link #awaitAdvance} requires an
  *       argument indicating an arrival phase number, and returns when
  *       the phaser advances to (or is already at) a different phase.
  *       Unlike similar constructions using {@code CyclicBarrier},
@@ -66,9 +66,10 @@
  *       state of the phaser. If necessary, you can perform any
  *       associated recovery within handlers of those exceptions,
  *       often after invoking {@code forceTermination}.  Phasers may
- *       also be used by tasks executing in a {@link ForkJoinPool},
- *       which will ensure sufficient parallelism to execute tasks
- *       when others are blocked waiting for a phase to advance.
+ *       also be used by tasks executing in a {@link ForkJoinPool}.
+ *       Progress is ensured if the pool's parallelismLevel can
+ *       accommodate the maximum number of simultaneously blocked
+ *       parties.
  *
  * </ul>
  *
@@ -124,7 +125,7 @@
  * The typical idiom is for the method setting this up to first
  * register, then start the actions, then deregister, as in:
  *
- *  <pre> {@code
+ * <pre> {@code
  * void runTasks(List<Runnable> tasks) {
  *   final Phaser phaser = new Phaser(1); // "1" to register self
  *   // create and start threads
@@ -145,7 +146,7 @@
  * <p>One way to cause a set of threads to repeatedly perform actions
  * for a given number of iterations is to override {@code onAdvance}:
  *
- *  <pre> {@code
+ * <pre> {@code
  * void startTasks(List<Runnable> tasks, final int iterations) {
  *   final Phaser phaser = new Phaser() {
  *     protected boolean onAdvance(int phase, int registeredParties) {
@@ -169,7 +170,7 @@
  *
  * If the main task must later await termination, it
  * may re-register and then execute a similar loop:
- *  <pre> {@code
+ * <pre> {@code
  *   // ...
  *   phaser.register();
  *   while (!phaser.isTerminated())
@@ -179,7 +180,7 @@
  * in contexts where you are sure that the phase will never wrap around
  * {@code Integer.MAX_VALUE}. For example:
  *
- *  <pre> {@code
+ * <pre> {@code
  * void awaitPhase(Phaser phaser, int phase) {
  *   int p = phaser.register(); // assumes caller not already registered
  *   while (p < phase) {
@@ -199,7 +200,7 @@
  * new Phaser())}, these tasks could then be started, for example by
  * submitting to a pool:
  *
- *  <pre> {@code
+ * <pre> {@code
  * void build(Task[] tasks, int lo, int hi, Phaser ph) {
  *   if (hi - lo > TASKS_PER_PHASER) {
  *     for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
@@ -300,7 +301,7 @@
     }
 
     /**
-     * The parent of this phaser, or null if none
+     * The parent of this phaser, or null if none.
      */
     private final Phaser parent;
 
@@ -358,7 +359,7 @@
             int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);
             if (unarrived <= 0)
                 throw new IllegalStateException(badArrive(s));
-            if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adjust)) {
+            if (U.compareAndSwapLong(this, STATE, s, s-=adjust)) {
                 if (unarrived == 1) {
                     long n = s & PARTIES_MASK;  // base of next state
                     int nextUnarrived = (int)n >>> PARTIES_SHIFT;
@@ -371,13 +372,12 @@
                             n |= nextUnarrived;
                         int nextPhase = (phase + 1) & MAX_PHASE;
                         n |= (long)nextPhase << PHASE_SHIFT;
-                        UNSAFE.compareAndSwapLong(this, stateOffset, s, n);
+                        U.compareAndSwapLong(this, STATE, s, n);
                         releaseWaiters(phase);
                     }
                     else if (nextUnarrived == 0) { // propagate deregistration
                         phase = parent.doArrive(ONE_DEREGISTER);
-                        UNSAFE.compareAndSwapLong(this, stateOffset,
-                                                  s, s | EMPTY);
+                        U.compareAndSwapLong(this, STATE, s, s | EMPTY);
                     }
                     else
                         phase = parent.doArrive(ONE_ARRIVAL);
@@ -388,7 +388,7 @@
     }
 
     /**
-     * Implementation of register, bulkRegister
+     * Implementation of register, bulkRegister.
      *
      * @param registrations number to add to both parties and
      * unarrived fields. Must be greater than zero.
@@ -412,14 +412,13 @@
                 if (parent == null || reconcileState() == s) {
                     if (unarrived == 0)             // wait out advance
                         root.internalAwaitAdvance(phase, null);
-                    else if (UNSAFE.compareAndSwapLong(this, stateOffset,
-                                                       s, s + adjust))
+                    else if (U.compareAndSwapLong(this, STATE, s, s + adjust))
                         break;
                 }
             }
             else if (parent == null) {              // 1st root registration
                 long next = ((long)phase << PHASE_SHIFT) | adjust;
-                if (UNSAFE.compareAndSwapLong(this, stateOffset, s, next))
+                if (U.compareAndSwapLong(this, STATE, s, next))
                     break;
             }
             else {
@@ -431,8 +430,8 @@
                         // finish registration whenever parent registration
                         // succeeded, even when racing with termination,
                         // since these are part of the same "transaction".
-                        while (!UNSAFE.compareAndSwapLong
-                               (this, stateOffset, s,
+                        while (!U.compareAndSwapLong
+                               (this, STATE, s,
                                 ((long)phase << PHASE_SHIFT) | adjust)) {
                             s = state;
                             phase = (int)(root.state >>> PHASE_SHIFT);
@@ -463,8 +462,8 @@
             // CAS to root phase with current parties, tripping unarrived
             while ((phase = (int)(root.state >>> PHASE_SHIFT)) !=
                    (int)(s >>> PHASE_SHIFT) &&
-                   !UNSAFE.compareAndSwapLong
-                   (this, stateOffset, s,
+                   !U.compareAndSwapLong
+                   (this, STATE, s,
                     s = (((long)phase << PHASE_SHIFT) |
                          ((phase < 0) ? (s & COUNTS_MASK) :
                           (((p = (int)s >>> PARTIES_SHIFT) == 0) ? EMPTY :
@@ -653,8 +652,7 @@
             int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);
             if (unarrived <= 0)
                 throw new IllegalStateException(badArrive(s));
-            if (UNSAFE.compareAndSwapLong(this, stateOffset, s,
-                                          s -= ONE_ARRIVAL)) {
+            if (U.compareAndSwapLong(this, STATE, s, s -= ONE_ARRIVAL)) {
                 if (unarrived > 1)
                     return root.internalAwaitAdvance(phase, null);
                 if (root != this)
@@ -669,7 +667,7 @@
                     n |= nextUnarrived;
                 int nextPhase = (phase + 1) & MAX_PHASE;
                 n |= (long)nextPhase << PHASE_SHIFT;
-                if (!UNSAFE.compareAndSwapLong(this, stateOffset, s, n))
+                if (!U.compareAndSwapLong(this, STATE, s, n))
                     return (int)(state >>> PHASE_SHIFT); // terminated
                 releaseWaiters(phase);
                 return nextPhase;
@@ -785,8 +783,7 @@
         final Phaser root = this.root;
         long s;
         while ((s = root.state) >= 0) {
-            if (UNSAFE.compareAndSwapLong(root, stateOffset,
-                                          s, s | TERMINATION_BIT)) {
+            if (U.compareAndSwapLong(root, STATE, s, s | TERMINATION_BIT)) {
                 // signal all threads
                 releaseWaiters(0); // Waiters on evenQ
                 releaseWaiters(1); // Waiters on oddQ
@@ -925,7 +922,7 @@
     }
 
     /**
-     * Implementation of toString and string-based error messages
+     * Implementation of toString and string-based error messages.
      */
     private String stateToString(long s) {
         return super.toString() +
@@ -1034,7 +1031,7 @@
             else {
                 try {
                     ForkJoinPool.managedBlock(node);
-                } catch (InterruptedException ie) {
+                } catch (InterruptedException cantHappen) {
                     node.wasInterrupted = true;
                 }
             }
@@ -1053,7 +1050,7 @@
     }
 
     /**
-     * Wait nodes for Treiber stack representing wait queue
+     * Wait nodes for Treiber stack representing wait queue.
      */
     static final class QNode implements ForkJoinPool.ManagedBlocker {
         final Phaser phaser;
@@ -1090,40 +1087,34 @@
                 thread = null;
                 return true;
             }
-            if (timed) {
-                if (nanos > 0L) {
-                    nanos = deadline - System.nanoTime();
-                }
-                if (nanos <= 0L) {
-                    thread = null;
-                    return true;
-                }
+            if (timed &&
+                (nanos <= 0L || (nanos = deadline - System.nanoTime()) <= 0L)) {
+                thread = null;
+                return true;
             }
             return false;
         }
 
         public boolean block() {
-            if (isReleasable())
-                return true;
-            else if (!timed)
-                LockSupport.park(this);
-            else if (nanos > 0L)
-                LockSupport.parkNanos(this, nanos);
-            return isReleasable();
+            while (!isReleasable()) {
+                if (timed)
+                    LockSupport.parkNanos(this, nanos);
+                else
+                    LockSupport.park(this);
+            }
+            return true;
         }
     }
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe UNSAFE;
-    private static final long stateOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long STATE;
     static {
         try {
-            UNSAFE = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = Phaser.class;
-            stateOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("state"));
-        } catch (Exception e) {
+            STATE = U.objectFieldOffset
+                (Phaser.class.getDeclaredField("state"));
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
 
diff --git a/luni/src/main/java/java/util/concurrent/PriorityBlockingQueue.java b/luni/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
index 40b3510..2044406 100644
--- a/luni/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
+++ b/luni/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
@@ -6,9 +6,19 @@
 
 package java.util.concurrent;
 
+import java.util.AbstractQueue;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.PriorityQueue;
+import java.util.Queue;
+import java.util.SortedSet;
+import java.util.Spliterator;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.*;
+import java.util.function.Consumer;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -43,7 +53,7 @@
  * tie-breaking to comparable elements. To use it, you would insert a
  * {@code new FIFOEntry(anEntry)} instead of a plain entry object.
  *
- *  <pre> {@code
+ * <pre> {@code
  * class FIFOEntry<E extends Comparable<? super E>>
  *     implements Comparable<FIFOEntry<E>> {
  *   static final AtomicLong seq = new AtomicLong(0);
@@ -64,7 +74,7 @@
  *
  * @since 1.5
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 @SuppressWarnings("unchecked")
 public class PriorityBlockingQueue<E> extends AbstractQueue<E>
@@ -122,12 +132,12 @@
     private transient Comparator<? super E> comparator;
 
     /**
-     * Lock used for all public operations
+     * Lock used for all public operations.
      */
     private final ReentrantLock lock;
 
     /**
-     * Condition for blocking when empty
+     * Condition for blocking when empty.
      */
     private final Condition notEmpty;
 
@@ -250,8 +260,7 @@
         lock.unlock(); // must release and then re-acquire main lock
         Object[] newArray = null;
         if (allocationSpinLock == 0 &&
-            UNSAFE.compareAndSwapInt(this, allocationSpinLockOffset,
-                                     0, 1)) {
+            U.compareAndSwapInt(this, ALLOCATIONSPINLOCK, 0, 1)) {
             try {
                 int newCap = oldCap + ((oldCap < 64) ?
                                        (oldCap + 2) : // grow faster if small
@@ -633,7 +642,7 @@
     }
 
     /**
-     * Identity-based version for use in Itr.remove
+     * Identity-based version for use in Itr.remove.
      */
     void removeEQ(Object o) {
         final ReentrantLock lock = this.lock;
@@ -669,48 +678,8 @@
         }
     }
 
-    /**
-     * Returns an array containing all of the elements in this queue.
-     * The returned array elements are in no particular order.
-     *
-     * <p>The returned array will be "safe" in that no references to it are
-     * maintained by this queue.  (In other words, this method must allocate
-     * a new array).  The caller is thus free to modify the returned array.
-     *
-     * <p>This method acts as bridge between array-based and collection-based
-     * APIs.
-     *
-     * @return an array containing all of the elements in this queue
-     */
-    public Object[] toArray() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            return Arrays.copyOf(queue, size);
-        } finally {
-            lock.unlock();
-        }
-    }
-
     public String toString() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            int n = size;
-            if (n == 0)
-                return "[]";
-            StringBuilder sb = new StringBuilder();
-            sb.append('[');
-            for (int i = 0; i < n; ++i) {
-                Object e = queue[i];
-                sb.append(e == this ? "(this Collection)" : e);
-                if (i != n - 1)
-                    sb.append(',').append(' ');
-            }
-            return sb.append(']').toString();
-        } finally {
-            lock.unlock();
-        }
+        return Helpers.collectionToString(this);
     }
 
     /**
@@ -769,6 +738,29 @@
     }
 
     /**
+     * Returns an array containing all of the elements in this queue.
+     * The returned array elements are in no particular order.
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this queue.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this queue
+     */
+    public Object[] toArray() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return Arrays.copyOf(queue, size);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
      * Returns an array containing all of the elements in this queue; the
      * runtime type of the returned array is that of the specified array.
      * The returned array elements are in no particular order.
@@ -790,7 +782,7 @@
      * The following code can be used to dump the queue into a newly
      * allocated array of {@code String}:
      *
-     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -825,12 +817,8 @@
      * Returns an iterator over the elements in this queue. The
      * iterator does not return the elements in any particular order.
      *
-     * <p>The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException
-     * ConcurrentModificationException}, and guarantees to traverse
-     * elements as they existed upon construction of the iterator, and
-     * may (but is not guaranteed to) reflect any modifications
-     * subsequent to construction.
+     * <p>The returned iterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
      *
      * @return an iterator over the elements in this queue
      */
@@ -876,6 +864,9 @@
      * For compatibility with previous version of this class, elements
      * are first copied to a java.util.PriorityQueue, which is then
      * serialized.
+     *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void writeObject(java.io.ObjectOutputStream s)
         throws java.io.IOException {
@@ -893,6 +884,10 @@
 
     /**
      * Reconstitutes this queue from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
@@ -906,16 +901,93 @@
         }
     }
 
+    // Similar to Collections.ArraySnapshotSpliterator but avoids
+    // commitment to toArray until needed
+    static final class PBQSpliterator<E> implements Spliterator<E> {
+        final PriorityBlockingQueue<E> queue;
+        Object[] array;
+        int index;
+        int fence;
+
+        PBQSpliterator(PriorityBlockingQueue<E> queue, Object[] array,
+                       int index, int fence) {
+            this.queue = queue;
+            this.array = array;
+            this.index = index;
+            this.fence = fence;
+        }
+
+        final int getFence() {
+            int hi;
+            if ((hi = fence) < 0)
+                hi = fence = (array = queue.toArray()).length;
+            return hi;
+        }
+
+        public PBQSpliterator<E> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid) ? null :
+                new PBQSpliterator<E>(queue, array, lo, index = mid);
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super E> action) {
+            Object[] a; int i, hi; // hoist accesses and checks from loop
+            if (action == null)
+                throw new NullPointerException();
+            if ((a = array) == null)
+                fence = (a = queue.toArray()).length;
+            if ((hi = fence) <= a.length &&
+                (i = index) >= 0 && i < (index = hi)) {
+                do { action.accept((E)a[i]); } while (++i < hi);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null)
+                throw new NullPointerException();
+            if (getFence() > index && index >= 0) {
+                @SuppressWarnings("unchecked") E e = (E) array[index++];
+                action.accept(e);
+                return true;
+            }
+            return false;
+        }
+
+        public long estimateSize() { return (long)(getFence() - index); }
+
+        public int characteristics() {
+            return Spliterator.NONNULL | Spliterator.SIZED | Spliterator.SUBSIZED;
+        }
+    }
+
+    /**
+     * Returns a {@link Spliterator} over the elements in this queue.
+     *
+     * <p>The returned spliterator is
+     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
+     *
+     * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
+     * {@link Spliterator#NONNULL}.
+     *
+     * @implNote
+     * The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}.
+     *
+     * @return a {@code Spliterator} over the elements in this queue
+     * @since 1.8
+     */
+    public Spliterator<E> spliterator() {
+        return new PBQSpliterator<E>(this, null, 0, -1);
+    }
+
     // Unsafe mechanics
-    private static final sun.misc.Unsafe UNSAFE;
-    private static final long allocationSpinLockOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long ALLOCATIONSPINLOCK;
     static {
         try {
-            UNSAFE = sun.misc.Unsafe.getUnsafe();
-            Class<?> k = PriorityBlockingQueue.class;
-            allocationSpinLockOffset = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("allocationSpinLock"));
-        } catch (Exception e) {
+            ALLOCATIONSPINLOCK = U.objectFieldOffset
+                (PriorityBlockingQueue.class.getDeclaredField("allocationSpinLock"));
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
     }
diff --git a/luni/src/main/java/java/util/concurrent/RecursiveAction.java b/luni/src/main/java/java/util/concurrent/RecursiveAction.java
index e3a6340..8631a89 100644
--- a/luni/src/main/java/java/util/concurrent/RecursiveAction.java
+++ b/luni/src/main/java/java/util/concurrent/RecursiveAction.java
@@ -16,7 +16,7 @@
  * <p><b>Sample Usages.</b> Here is a simple but complete ForkJoin
  * sort that sorts a given {@code long[]} array:
  *
- *  <pre> {@code
+ * <pre> {@code
  * static class SortTask extends RecursiveAction {
  *   final long[] array; final int lo, hi;
  *   SortTask(long[] array, int lo, int hi) {
@@ -50,7 +50,7 @@
  * SortTask(anArray)} and invoking it in a ForkJoinPool.  As a more
  * concrete simple example, the following task increments each element
  * of an array:
- *  <pre> {@code
+ * <pre> {@code
  * class IncrementTask extends RecursiveAction {
  *   final long[] array; final int lo, hi;
  *   IncrementTask(long[] array, int lo, int hi) {
@@ -81,7 +81,7 @@
  * performing leaf actions on unstolen tasks rather than further
  * subdividing.
  *
- *  <pre> {@code
+ * <pre> {@code
  * double sumOfSquares(ForkJoinPool pool, double[] array) {
  *   int n = array.length;
  *   Applyer a = new Applyer(array, 0, n, null);
diff --git a/luni/src/main/java/java/util/concurrent/RecursiveTask.java b/luni/src/main/java/java/util/concurrent/RecursiveTask.java
index d201bd6..5cba1da 100644
--- a/luni/src/main/java/java/util/concurrent/RecursiveTask.java
+++ b/luni/src/main/java/java/util/concurrent/RecursiveTask.java
@@ -11,11 +11,11 @@
  *
  * <p>For a classic example, here is a task computing Fibonacci numbers:
  *
- *  <pre> {@code
+ * <pre> {@code
  * class Fibonacci extends RecursiveTask<Integer> {
  *   final int n;
  *   Fibonacci(int n) { this.n = n; }
- *   Integer compute() {
+ *   protected Integer compute() {
  *     if (n <= 1)
  *       return n;
  *     Fibonacci f1 = new Fibonacci(n - 1);
diff --git a/luni/src/main/java/java/util/concurrent/RunnableScheduledFuture.java b/luni/src/main/java/java/util/concurrent/RunnableScheduledFuture.java
index 7125233..604f180 100644
--- a/luni/src/main/java/java/util/concurrent/RunnableScheduledFuture.java
+++ b/luni/src/main/java/java/util/concurrent/RunnableScheduledFuture.java
@@ -19,11 +19,11 @@
 public interface RunnableScheduledFuture<V> extends RunnableFuture<V>, ScheduledFuture<V> {
 
     /**
-     * Returns true if this is a periodic task. A periodic task may
+     * Returns {@code true} if this task is periodic. A periodic task may
      * re-run according to some schedule. A non-periodic task can be
      * run only once.
      *
-     * @return true if this task is periodic
+     * @return {@code true} if this task is periodic
      */
     boolean isPeriodic();
 }
diff --git a/luni/src/main/java/java/util/concurrent/ScheduledExecutorService.java b/luni/src/main/java/java/util/concurrent/ScheduledExecutorService.java
index c07a5b9..eae47b3 100644
--- a/luni/src/main/java/java/util/concurrent/ScheduledExecutorService.java
+++ b/luni/src/main/java/java/util/concurrent/ScheduledExecutorService.java
@@ -41,7 +41,7 @@
  * Here is a class with a method that sets up a ScheduledExecutorService
  * to beep every ten seconds for an hour:
  *
- *  <pre> {@code
+ * <pre> {@code
  * import static java.util.concurrent.TimeUnit.*;
  * class BeeperControl {
  *   private final ScheduledExecutorService scheduler =
@@ -100,23 +100,37 @@
     /**
      * Creates and executes a periodic action that becomes enabled first
      * after the given initial delay, and subsequently with the given
-     * period; that is executions will commence after
-     * {@code initialDelay} then {@code initialDelay+period}, then
+     * period; that is, executions will commence after
+     * {@code initialDelay}, then {@code initialDelay + period}, then
      * {@code initialDelay + 2 * period}, and so on.
-     * If any execution of the task
-     * encounters an exception, subsequent executions are suppressed.
-     * Otherwise, the task will only terminate via cancellation or
-     * termination of the executor.  If any execution of this task
-     * takes longer than its period, then subsequent executions
-     * may start late, but will not concurrently execute.
+     *
+     * <p>The sequence of task executions continues indefinitely until
+     * one of the following exceptional completions occur:
+     * <ul>
+     * <li>The task is {@linkplain Future#cancel explicitly cancelled}
+     * via the returned future.
+     * <li>The executor terminates, also resulting in task cancellation.
+     * <li>An execution of the task throws an exception.  In this case
+     * calling {@link Future#get() get} on the returned future will
+     * throw {@link ExecutionException}.
+     * </ul>
+     * Subsequent executions are suppressed.  Subsequent calls to
+     * {@link Future#isDone isDone()} on the returned future will
+     * return {@code true}.
+     *
+     * <p>If any execution of this task takes longer than its period, then
+     * subsequent executions may start late, but will not concurrently
+     * execute.
      *
      * @param command the task to execute
      * @param initialDelay the time to delay first execution
      * @param period the period between successive executions
      * @param unit the time unit of the initialDelay and period parameters
      * @return a ScheduledFuture representing pending completion of
-     *         the task, and whose {@code get()} method will throw an
-     *         exception upon cancellation
+     *         the series of repeated tasks.  The future's {@link
+     *         Future#get() get()} method will never return normally,
+     *         and will throw an exception upon task cancellation or
+     *         abnormal termination of a task execution.
      * @throws RejectedExecutionException if the task cannot be
      *         scheduled for execution
      * @throws NullPointerException if command is null
@@ -131,10 +145,21 @@
      * Creates and executes a periodic action that becomes enabled first
      * after the given initial delay, and subsequently with the
      * given delay between the termination of one execution and the
-     * commencement of the next.  If any execution of the task
-     * encounters an exception, subsequent executions are suppressed.
-     * Otherwise, the task will only terminate via cancellation or
-     * termination of the executor.
+     * commencement of the next.
+     *
+     * <p>The sequence of task executions continues indefinitely until
+     * one of the following exceptional completions occur:
+     * <ul>
+     * <li>The task is {@linkplain Future#cancel explicitly cancelled}
+     * via the returned future.
+     * <li>The executor terminates, also resulting in task cancellation.
+     * <li>An execution of the task throws an exception.  In this case
+     * calling {@link Future#get() get} on the returned future will
+     * throw {@link ExecutionException}.
+     * </ul>
+     * Subsequent executions are suppressed.  Subsequent calls to
+     * {@link Future#isDone isDone()} on the returned future will
+     * return {@code true}.
      *
      * @param command the task to execute
      * @param initialDelay the time to delay first execution
@@ -142,8 +167,10 @@
      * execution and the commencement of the next
      * @param unit the time unit of the initialDelay and delay parameters
      * @return a ScheduledFuture representing pending completion of
-     *         the task, and whose {@code get()} method will throw an
-     *         exception upon cancellation
+     *         the series of repeated tasks.  The future's {@link
+     *         Future#get() get()} method will never return normally,
+     *         and will throw an exception upon task cancellation or
+     *         abnormal termination of a task execution.
      * @throws RejectedExecutionException if the task cannot be
      *         scheduled for execution
      * @throws NullPointerException if command is null
diff --git a/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java b/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
index 821342d..f9a2000 100644
--- a/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
+++ b/luni/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
@@ -6,12 +6,18 @@
 
 package java.util.concurrent;
 
-import static java.util.concurrent.TimeUnit.NANOSECONDS;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.util.AbstractQueue;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.*;
 
 // BEGIN android-note
 // omit class-level docs on setRemoveOnCancelPolicy()
@@ -32,17 +38,17 @@
  * submission.
  *
  * <p>When a submitted task is cancelled before it is run, execution
- * is suppressed. By default, such a cancelled task is not
- * automatically removed from the work queue until its delay
- * elapses. While this enables further inspection and monitoring, it
- * may also cause unbounded retention of cancelled tasks.
+ * is suppressed.  By default, such a cancelled task is not
+ * automatically removed from the work queue until its delay elapses.
+ * While this enables further inspection and monitoring, it may also
+ * cause unbounded retention of cancelled tasks.
  *
  * <p>Successive executions of a periodic task scheduled via
- * {@link #scheduleAtFixedRate} or
- * {@link #scheduleWithFixedDelay} do not overlap. While different
- * executions may be performed by different threads, the effects of
- * prior executions <a
- * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * {@link #scheduleAtFixedRate scheduleAtFixedRate} or
+ * {@link #scheduleWithFixedDelay scheduleWithFixedDelay}
+ * do not overlap. While different executions may be performed by
+ * different threads, the effects of prior executions
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
  * those of subsequent ones.
  *
  * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
@@ -72,7 +78,7 @@
  * {@link FutureTask}. However, this may be modified or replaced using
  * subclasses of the form:
  *
- *  <pre> {@code
+ * <pre> {@code
  * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor {
  *
  *   static class CustomTask<V> implements RunnableScheduledFuture<V> { ... }
@@ -99,11 +105,10 @@
     /*
      * This class specializes ThreadPoolExecutor implementation by
      *
-     * 1. Using a custom task type, ScheduledFutureTask for
-     *    tasks, even those that don't require scheduling (i.e.,
-     *    those submitted using ExecutorService execute, not
-     *    ScheduledExecutorService methods) which are treated as
-     *    delayed tasks with a delay of zero.
+     * 1. Using a custom task type ScheduledFutureTask, even for tasks
+     *    that don't require scheduling because they are submitted
+     *    using ExecutorService rather than ScheduledExecutorService
+     *    methods, which are treated as tasks with a delay of zero.
      *
      * 2. Using a custom queue (DelayedWorkQueue), a variant of
      *    unbounded DelayQueue. The lack of capacity constraint and
@@ -136,7 +141,7 @@
     /**
      * True if ScheduledFutureTask.cancel should remove from queue.
      */
-    private volatile boolean removeOnCancel = false;
+    volatile boolean removeOnCancel;
 
     /**
      * Sequence number to break scheduling ties, and in turn to
@@ -144,24 +149,17 @@
      */
     private static final AtomicLong sequencer = new AtomicLong();
 
-    /**
-     * Returns current nanosecond time.
-     */
-    final long now() {
-        return System.nanoTime();
-    }
-
     private class ScheduledFutureTask<V>
             extends FutureTask<V> implements RunnableScheduledFuture<V> {
 
         /** Sequence number to break ties FIFO */
         private final long sequenceNumber;
 
-        /** The time the task is enabled to execute in nanoTime units */
-        private long time;
+        /** The nanoTime-based time when the task is enabled to execute. */
+        private volatile long time;
 
         /**
-         * Period in nanoseconds for repeating tasks.
+         * Period for repeating tasks, in nanoseconds.
          * A positive value indicates fixed-rate execution.
          * A negative value indicates fixed-delay execution.
          * A value of 0 indicates a non-repeating (one-shot) task.
@@ -179,11 +177,12 @@
         /**
          * Creates a one-shot action with given nanoTime-based trigger time.
          */
-        ScheduledFutureTask(Runnable r, V result, long triggerTime) {
+        ScheduledFutureTask(Runnable r, V result, long triggerTime,
+                            long sequenceNumber) {
             super(r, result);
             this.time = triggerTime;
             this.period = 0;
-            this.sequenceNumber = sequencer.getAndIncrement();
+            this.sequenceNumber = sequenceNumber;
         }
 
         /**
@@ -191,25 +190,26 @@
          * trigger time and period.
          */
         ScheduledFutureTask(Runnable r, V result, long triggerTime,
-                            long period) {
+                            long period, long sequenceNumber) {
             super(r, result);
             this.time = triggerTime;
             this.period = period;
-            this.sequenceNumber = sequencer.getAndIncrement();
+            this.sequenceNumber = sequenceNumber;
         }
 
         /**
          * Creates a one-shot action with given nanoTime-based trigger time.
          */
-        ScheduledFutureTask(Callable<V> callable, long triggerTime) {
+        ScheduledFutureTask(Callable<V> callable, long triggerTime,
+                            long sequenceNumber) {
             super(callable);
             this.time = triggerTime;
             this.period = 0;
-            this.sequenceNumber = sequencer.getAndIncrement();
+            this.sequenceNumber = sequenceNumber;
         }
 
         public long getDelay(TimeUnit unit) {
-            return unit.convert(time - now(), NANOSECONDS);
+            return unit.convert(time - System.nanoTime(), NANOSECONDS);
         }
 
         public int compareTo(Delayed other) {
@@ -252,6 +252,9 @@
         }
 
         public boolean cancel(boolean mayInterruptIfRunning) {
+            // The racy read of heapIndex below is benign:
+            // if heapIndex < 0, then OOTA guarantees that we have surely
+            // been removed; else we recheck under lock in remove()
             boolean cancelled = super.cancel(mayInterruptIfRunning);
             if (cancelled && removeOnCancel && heapIndex >= 0)
                 remove(this);
@@ -266,8 +269,8 @@
             if (!canRunInCurrentRunState(periodic))
                 cancel(false);
             else if (!periodic)
-                ScheduledFutureTask.super.run();
-            else if (ScheduledFutureTask.super.runAndReset()) {
+                super.run();
+            else if (super.runAndReset()) {
                 setNextRunTime();
                 reExecutePeriodic(outerTask);
             }
@@ -493,7 +496,7 @@
      * Returns the nanoTime-based trigger time of a delayed action.
      */
     long triggerTime(long delay) {
-        return now() +
+        return System.nanoTime() +
             ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
     }
 
@@ -525,7 +528,8 @@
             throw new NullPointerException();
         RunnableScheduledFuture<Void> t = decorateTask(command,
             new ScheduledFutureTask<Void>(command, null,
-                                          triggerTime(delay, unit)));
+                                          triggerTime(delay, unit),
+                                          sequencer.getAndIncrement()));
         delayedExecute(t);
         return t;
     }
@@ -541,7 +545,8 @@
             throw new NullPointerException();
         RunnableScheduledFuture<V> t = decorateTask(callable,
             new ScheduledFutureTask<V>(callable,
-                                       triggerTime(delay, unit)));
+                                       triggerTime(delay, unit),
+                                       sequencer.getAndIncrement()));
         delayedExecute(t);
         return t;
     }
@@ -557,13 +562,14 @@
                                                   TimeUnit unit) {
         if (command == null || unit == null)
             throw new NullPointerException();
-        if (period <= 0)
+        if (period <= 0L)
             throw new IllegalArgumentException();
         ScheduledFutureTask<Void> sft =
             new ScheduledFutureTask<Void>(command,
                                           null,
                                           triggerTime(initialDelay, unit),
-                                          unit.toNanos(period));
+                                          unit.toNanos(period),
+                                          sequencer.getAndIncrement());
         RunnableScheduledFuture<Void> t = decorateTask(command, sft);
         sft.outerTask = t;
         delayedExecute(t);
@@ -581,13 +587,14 @@
                                                      TimeUnit unit) {
         if (command == null || unit == null)
             throw new NullPointerException();
-        if (delay <= 0)
+        if (delay <= 0L)
             throw new IllegalArgumentException();
         ScheduledFutureTask<Void> sft =
             new ScheduledFutureTask<Void>(command,
                                           null,
                                           triggerTime(initialDelay, unit),
-                                          unit.toNanos(-delay));
+                                          -unit.toNanos(delay),
+                                          sequencer.getAndIncrement());
         RunnableScheduledFuture<Void> t = decorateTask(command, sft);
         sft.outerTask = t;
         delayedExecute(t);
@@ -759,7 +766,8 @@
     /**
      * Attempts to stop all actively executing tasks, halts the
      * processing of waiting tasks, and returns a list of the tasks
-     * that were awaiting execution.
+     * that were awaiting execution. These tasks are drained (removed)
+     * from the task queue upon return from this method.
      *
      * <p>This method does not wait for actively executing tasks to
      * terminate.  Use {@link #awaitTermination awaitTermination} to
@@ -767,7 +775,7 @@
      *
      * <p>There are no guarantees beyond best-effort attempts to stop
      * processing actively executing tasks.  This implementation
-     * cancels tasks via {@link Thread#interrupt}, so any task that
+     * interrupts tasks via {@link Thread#interrupt}; any task that
      * fails to respond to interrupts may never terminate.
      *
      * @return list of tasks that never commenced execution.
@@ -775,8 +783,8 @@
      *         For tasks submitted via one of the {@code schedule}
      *         methods, the element will be identical to the returned
      *         {@code ScheduledFuture}.  For tasks submitted using
-     *         {@link #execute}, the element will be a zero-delay {@code
-     *         ScheduledFuture}.
+     *         {@link #execute execute}, the element will be a
+     *         zero-delay {@code ScheduledFuture}.
      */
     // android-note: Removed "throws SecurityException" doc.
     public List<Runnable> shutdownNow() {
@@ -784,12 +792,16 @@
     }
 
     /**
-     * Returns the task queue used by this executor.
-     * Each element of this list is a {@link ScheduledFuture}.
+     * Returns the task queue used by this executor.  Access to the
+     * task queue is intended primarily for debugging and monitoring.
+     * This queue may be in active use.  Retrieving the task queue
+     * does not prevent queued tasks from executing.
+     *
+     * <p>Each element of this queue is a {@link ScheduledFuture}.
      * For tasks submitted via one of the {@code schedule} methods, the
      * element will be identical to the returned {@code ScheduledFuture}.
-     * For tasks submitted using {@link #execute}, the element will be a
-     * zero-delay {@code ScheduledFuture}.
+     * For tasks submitted using {@link #execute execute}, the element
+     * will be a zero-delay {@code ScheduledFuture}.
      *
      * <p>Iteration over this queue is <em>not</em> guaranteed to traverse
      * tasks in the order in which they will execute.
@@ -1061,10 +1073,9 @@
             lock.lock();
             try {
                 RunnableScheduledFuture<?> first = queue[0];
-                if (first == null || first.getDelay(NANOSECONDS) > 0)
-                    return null;
-                else
-                    return finishPoll(first);
+                return (first == null || first.getDelay(NANOSECONDS) > 0)
+                    ? null
+                    : finishPoll(first);
             } finally {
                 lock.unlock();
             }
@@ -1080,7 +1091,7 @@
                         available.await();
                     else {
                         long delay = first.getDelay(NANOSECONDS);
-                        if (delay <= 0)
+                        if (delay <= 0L)
                             return finishPoll(first);
                         first = null; // don't retain ref while waiting
                         if (leader != null)
@@ -1113,15 +1124,15 @@
                 for (;;) {
                     RunnableScheduledFuture<?> first = queue[0];
                     if (first == null) {
-                        if (nanos <= 0)
+                        if (nanos <= 0L)
                             return null;
                         else
                             nanos = available.awaitNanos(nanos);
                     } else {
                         long delay = first.getDelay(NANOSECONDS);
-                        if (delay <= 0)
+                        if (delay <= 0L)
                             return finishPoll(first);
-                        if (nanos <= 0)
+                        if (nanos <= 0L)
                             return null;
                         first = null; // don't retain ref while waiting
                         if (nanos < delay || leader != null)
@@ -1253,8 +1264,8 @@
          */
         private class Itr implements Iterator<Runnable> {
             final RunnableScheduledFuture<?>[] array;
-            int cursor = 0;     // index of next element to return
-            int lastRet = -1;   // index of last element, or -1 if no such
+            int cursor;        // index of next element to return; initially 0
+            int lastRet = -1;  // index of last element returned; -1 if no such
 
             Itr(RunnableScheduledFuture<?>[] array) {
                 this.array = array;
diff --git a/luni/src/main/java/java/util/concurrent/Semaphore.java b/luni/src/main/java/java/util/concurrent/Semaphore.java
index b4b7edd..856b02b 100644
--- a/luni/src/main/java/java/util/concurrent/Semaphore.java
+++ b/luni/src/main/java/java/util/concurrent/Semaphore.java
@@ -20,7 +20,7 @@
  * <p>Semaphores are often used to restrict the number of threads than can
  * access some (physical or logical) resource. For example, here is
  * a class that uses a semaphore to control access to a pool of items:
- *  <pre> {@code
+ * <pre> {@code
  * class Pool {
  *   private static final int MAX_AVAILABLE = 100;
  *   private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
@@ -113,8 +113,13 @@
  *
  * <p>This class also provides convenience methods to {@link
  * #acquire(int) acquire} and {@link #release(int) release} multiple
- * permits at a time.  Beware of the increased risk of indefinite
- * postponement when these methods are used without fairness set true.
+ * permits at a time. These methods are generally more efficient and
+ * effective than loops. However, they do not establish any preference
+ * order. For example, if thread A invokes {@code s.acquire(3}) and
+ * thread B invokes {@code s.acquire(2)}, and two permits become
+ * available, then there is no guarantee that thread B will obtain
+ * them unless its acquire came first and Semaphore {@code s} is in
+ * fair mode.
  *
  * <p>Memory consistency effects: Actions in a thread prior to calling
  * a "release" method such as {@code release()}
@@ -405,14 +410,16 @@
      *
      * <p>Acquires the given number of permits, if they are available,
      * and returns immediately, reducing the number of available permits
-     * by the given amount.
+     * by the given amount. This method has the same effect as the
+     * loop {@code for (int i = 0; i < permits; ++i) acquire();} except
+     * that it atomically acquires the permits all at once:
      *
      * <p>If insufficient permits are available then the current thread becomes
      * disabled for thread scheduling purposes and lies dormant until
      * one of two things happens:
      * <ul>
      * <li>Some other thread invokes one of the {@link #release() release}
-     * methods for this semaphore, the current thread is next to be assigned
+     * methods for this semaphore and the current thread is next to be assigned
      * permits and the number of available permits satisfies this request; or
      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
      * the current thread.
@@ -445,12 +452,14 @@
      *
      * <p>Acquires the given number of permits, if they are available,
      * and returns immediately, reducing the number of available permits
-     * by the given amount.
+     * by the given amount. This method has the same effect as the
+     * loop {@code for (int i = 0; i < permits; ++i) acquireUninterruptibly();}
+     * except that it atomically acquires the permits all at once:
      *
      * <p>If insufficient permits are available then the current thread becomes
      * disabled for thread scheduling purposes and lies dormant until
      * some other thread invokes one of the {@link #release() release}
-     * methods for this semaphore, the current thread is next to be assigned
+     * methods for this semaphore and the current thread is next to be assigned
      * permits and the number of available permits satisfies this request.
      *
      * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
@@ -512,7 +521,7 @@
      * purposes and lies dormant until one of three things happens:
      * <ul>
      * <li>Some other thread invokes one of the {@link #release() release}
-     * methods for this semaphore, the current thread is next to be assigned
+     * methods for this semaphore and the current thread is next to be assigned
      * permits and the number of available permits satisfies this request; or
      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
      * the current thread; or
@@ -559,7 +568,7 @@
      *
      * <p>Releases the given number of permits, increasing the number of
      * available permits by that amount.
-     * If any threads are trying to acquire permits, then one
+     * If any threads are trying to acquire permits, then one thread
      * is selected and given the permits that were just released.
      * If the number of available permits satisfies that thread's request
      * then that thread is (re)enabled for thread scheduling purposes;
@@ -643,7 +652,7 @@
      * Returns an estimate of the number of threads waiting to acquire.
      * The value is only an estimate because the number of threads may
      * change dynamically while this method traverses internal data
-     * structures.  This method is designed for use in monitoring of the
+     * structures.  This method is designed for use in monitoring
      * system state, not for synchronization control.
      *
      * @return the estimated number of threads waiting for this lock
diff --git a/luni/src/main/java/java/util/concurrent/SynchronousQueue.java b/luni/src/main/java/java/util/concurrent/SynchronousQueue.java
index 69452af..a46f672 100644
--- a/luni/src/main/java/java/util/concurrent/SynchronousQueue.java
+++ b/luni/src/main/java/java/util/concurrent/SynchronousQueue.java
@@ -7,9 +7,14 @@
 
 package java.util.concurrent;
 
+import java.util.AbstractQueue;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
 import java.util.concurrent.locks.LockSupport;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.*;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -49,7 +54,7 @@
  *
  * @since 1.5
  * @author Doug Lea and Bill Scherer and Michael Scott
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public class SynchronousQueue<E> extends AbstractQueue<E>
     implements BlockingQueue<E>, java.io.Serializable {
@@ -152,9 +157,6 @@
         abstract E transfer(E e, boolean timed, long nanos);
     }
 
-    /** The number of CPUs, for spin control */
-    static final int NCPUS = Runtime.getRuntime().availableProcessors();
-
     /**
      * The number of times to spin before blocking in timed waits.
      * The value is empirically derived -- it works well across a
@@ -162,20 +164,21 @@
      * seems not to vary with number of CPUs (beyond 2) so is just
      * a constant.
      */
-    static final int maxTimedSpins = (NCPUS < 2) ? 0 : 32;
+    static final int MAX_TIMED_SPINS =
+        (Runtime.getRuntime().availableProcessors() < 2) ? 0 : 32;
 
     /**
      * The number of times to spin before blocking in untimed waits.
      * This is greater than timed value because untimed waits spin
      * faster since they don't need to check times on each spin.
      */
-    static final int maxUntimedSpins = maxTimedSpins * 16;
+    static final int MAX_UNTIMED_SPINS = MAX_TIMED_SPINS * 16;
 
     /**
      * The number of nanoseconds for which it is faster to spin
      * rather than to use timed park. A rough estimate suffices.
      */
-    static final long spinForTimeoutThreshold = 1000L;
+    static final long SPIN_FOR_TIMEOUT_THRESHOLD = 1000L;
 
     /** Dual stack */
     static final class TransferStack<E> extends Transferer<E> {
@@ -215,7 +218,7 @@
 
             boolean casNext(SNode cmp, SNode val) {
                 return cmp == next &&
-                    UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
+                    U.compareAndSwapObject(this, NEXT, cmp, val);
             }
 
             /**
@@ -228,7 +231,7 @@
              */
             boolean tryMatch(SNode s) {
                 if (match == null &&
-                    UNSAFE.compareAndSwapObject(this, matchOffset, null, s)) {
+                    U.compareAndSwapObject(this, MATCH, null, s)) {
                     Thread w = waiter;
                     if (w != null) {    // waiters need at most one unpark
                         waiter = null;
@@ -243,7 +246,7 @@
              * Tries to cancel a wait by matching node to itself.
              */
             void tryCancel() {
-                UNSAFE.compareAndSwapObject(this, matchOffset, null, this);
+                U.compareAndSwapObject(this, MATCH, null, this);
             }
 
             boolean isCancelled() {
@@ -251,19 +254,17 @@
             }
 
             // Unsafe mechanics
-            private static final sun.misc.Unsafe UNSAFE;
-            private static final long matchOffset;
-            private static final long nextOffset;
+            private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+            private static final long MATCH;
+            private static final long NEXT;
 
             static {
                 try {
-                    UNSAFE = sun.misc.Unsafe.getUnsafe();
-                    Class<?> k = SNode.class;
-                    matchOffset = UNSAFE.objectFieldOffset
-                        (k.getDeclaredField("match"));
-                    nextOffset = UNSAFE.objectFieldOffset
-                        (k.getDeclaredField("next"));
-                } catch (Exception e) {
+                    MATCH = U.objectFieldOffset
+                        (SNode.class.getDeclaredField("match"));
+                    NEXT = U.objectFieldOffset
+                        (SNode.class.getDeclaredField("next"));
+                } catch (ReflectiveOperationException e) {
                     throw new Error(e);
                 }
             }
@@ -274,7 +275,7 @@
 
         boolean casHead(SNode h, SNode nh) {
             return h == head &&
-                UNSAFE.compareAndSwapObject(this, headOffset, h, nh);
+                U.compareAndSwapObject(this, HEAD, h, nh);
         }
 
         /**
@@ -323,7 +324,7 @@
             for (;;) {
                 SNode h = head;
                 if (h == null || h.mode == mode) {  // empty or same-mode
-                    if (timed && nanos <= 0) {      // can't wait
+                    if (timed && nanos <= 0L) {     // can't wait
                         if (h != null && h.isCancelled())
                             casHead(h, h.next);     // pop cancelled node
                         else
@@ -405,8 +406,9 @@
              */
             final long deadline = timed ? System.nanoTime() + nanos : 0L;
             Thread w = Thread.currentThread();
-            int spins = (shouldSpin(s) ?
-                         (timed ? maxTimedSpins : maxUntimedSpins) : 0);
+            int spins = shouldSpin(s)
+                ? (timed ? MAX_TIMED_SPINS : MAX_UNTIMED_SPINS)
+                : 0;
             for (;;) {
                 if (w.isInterrupted())
                     s.tryCancel();
@@ -421,12 +423,12 @@
                     }
                 }
                 if (spins > 0)
-                    spins = shouldSpin(s) ? (spins-1) : 0;
+                    spins = shouldSpin(s) ? (spins - 1) : 0;
                 else if (s.waiter == null)
                     s.waiter = w; // establish waiter so can park next iter
                 else if (!timed)
                     LockSupport.park(this);
-                else if (nanos > spinForTimeoutThreshold)
+                else if (nanos > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanos);
             }
         }
@@ -478,15 +480,13 @@
         }
 
         // Unsafe mechanics
-        private static final sun.misc.Unsafe UNSAFE;
-        private static final long headOffset;
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final long HEAD;
         static {
             try {
-                UNSAFE = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = TransferStack.class;
-                headOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("head"));
-            } catch (Exception e) {
+                HEAD = U.objectFieldOffset
+                    (TransferStack.class.getDeclaredField("head"));
+            } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
         }
@@ -517,19 +517,19 @@
 
             boolean casNext(QNode cmp, QNode val) {
                 return next == cmp &&
-                    UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
+                    U.compareAndSwapObject(this, NEXT, cmp, val);
             }
 
             boolean casItem(Object cmp, Object val) {
                 return item == cmp &&
-                    UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
+                    U.compareAndSwapObject(this, ITEM, cmp, val);
             }
 
             /**
              * Tries to cancel by CAS'ing ref to this as item.
              */
             void tryCancel(Object cmp) {
-                UNSAFE.compareAndSwapObject(this, itemOffset, cmp, this);
+                U.compareAndSwapObject(this, ITEM, cmp, this);
             }
 
             boolean isCancelled() {
@@ -546,19 +546,17 @@
             }
 
             // Unsafe mechanics
-            private static final sun.misc.Unsafe UNSAFE;
-            private static final long itemOffset;
-            private static final long nextOffset;
+            private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+            private static final long ITEM;
+            private static final long NEXT;
 
             static {
                 try {
-                    UNSAFE = sun.misc.Unsafe.getUnsafe();
-                    Class<?> k = QNode.class;
-                    itemOffset = UNSAFE.objectFieldOffset
-                        (k.getDeclaredField("item"));
-                    nextOffset = UNSAFE.objectFieldOffset
-                        (k.getDeclaredField("next"));
-                } catch (Exception e) {
+                    ITEM = U.objectFieldOffset
+                        (QNode.class.getDeclaredField("item"));
+                    NEXT = U.objectFieldOffset
+                        (QNode.class.getDeclaredField("next"));
+                } catch (ReflectiveOperationException e) {
                     throw new Error(e);
                 }
             }
@@ -587,7 +585,7 @@
          */
         void advanceHead(QNode h, QNode nh) {
             if (h == head &&
-                UNSAFE.compareAndSwapObject(this, headOffset, h, nh))
+                U.compareAndSwapObject(this, HEAD, h, nh))
                 h.next = h; // forget old next
         }
 
@@ -596,7 +594,7 @@
          */
         void advanceTail(QNode t, QNode nt) {
             if (tail == t)
-                UNSAFE.compareAndSwapObject(this, tailOffset, t, nt);
+                U.compareAndSwapObject(this, TAIL, t, nt);
         }
 
         /**
@@ -604,7 +602,7 @@
          */
         boolean casCleanMe(QNode cmp, QNode val) {
             return cleanMe == cmp &&
-                UNSAFE.compareAndSwapObject(this, cleanMeOffset, cmp, val);
+                U.compareAndSwapObject(this, CLEANME, cmp, val);
         }
 
         /**
@@ -654,7 +652,7 @@
                         advanceTail(t, tn);
                         continue;
                     }
-                    if (timed && nanos <= 0)        // can't wait
+                    if (timed && nanos <= 0L)       // can't wait
                         return null;
                     if (s == null)
                         s = new QNode(e, isData);
@@ -709,8 +707,9 @@
             /* Same idea as TransferStack.awaitFulfill */
             final long deadline = timed ? System.nanoTime() + nanos : 0L;
             Thread w = Thread.currentThread();
-            int spins = ((head.next == s) ?
-                         (timed ? maxTimedSpins : maxUntimedSpins) : 0);
+            int spins = (head.next == s)
+                ? (timed ? MAX_TIMED_SPINS : MAX_UNTIMED_SPINS)
+                : 0;
             for (;;) {
                 if (w.isInterrupted())
                     s.tryCancel(e);
@@ -730,7 +729,7 @@
                     s.waiter = w;
                 else if (!timed)
                     LockSupport.park(this);
-                else if (nanos > spinForTimeoutThreshold)
+                else if (nanos > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanos);
             }
         }
@@ -789,21 +788,19 @@
             }
         }
 
-        private static final sun.misc.Unsafe UNSAFE;
-        private static final long headOffset;
-        private static final long tailOffset;
-        private static final long cleanMeOffset;
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final long HEAD;
+        private static final long TAIL;
+        private static final long CLEANME;
         static {
             try {
-                UNSAFE = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = TransferQueue.class;
-                headOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("head"));
-                tailOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("tail"));
-                cleanMeOffset = UNSAFE.objectFieldOffset
-                    (k.getDeclaredField("cleanMe"));
-            } catch (Exception e) {
+                HEAD = U.objectFieldOffset
+                    (TransferQueue.class.getDeclaredField("head"));
+                TAIL = U.objectFieldOffset
+                    (TransferQueue.class.getDeclaredField("tail"));
+                CLEANME = U.objectFieldOffset
+                    (TransferQueue.class.getDeclaredField("cleanMe"));
+            } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
         }
@@ -1034,19 +1031,19 @@
      *
      * @return an empty iterator
      */
-    @SuppressWarnings("unchecked")
     public Iterator<E> iterator() {
-        return (Iterator<E>) EmptyIterator.EMPTY_ITERATOR;
+        return Collections.emptyIterator();
     }
 
-    // Replicated from a previous version of Collections
-    private static class EmptyIterator<E> implements Iterator<E> {
-        static final EmptyIterator<Object> EMPTY_ITERATOR
-            = new EmptyIterator<Object>();
-
-        public boolean hasNext() { return false; }
-        public E next() { throw new NoSuchElementException(); }
-        public void remove() { throw new IllegalStateException(); }
+    /**
+     * Returns an empty spliterator in which calls to
+     * {@link java.util.Spliterator#trySplit()} always return {@code null}.
+     *
+     * @return an empty spliterator
+     * @since 1.8
+     */
+    public Spliterator<E> spliterator() {
+        return Spliterators.emptySpliterator();
     }
 
     /**
@@ -1072,6 +1069,14 @@
     }
 
     /**
+     * Always returns {@code "[]"}.
+     * @return {@code "[]"}
+     */
+    public String toString() {
+        return "[]";
+    }
+
+    /**
      * @throws UnsupportedOperationException {@inheritDoc}
      * @throws ClassCastException            {@inheritDoc}
      * @throws NullPointerException          {@inheritDoc}
@@ -1131,6 +1136,8 @@
 
     /**
      * Saves this queue to a stream (that is, serializes it).
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void writeObject(java.io.ObjectOutputStream s)
         throws java.io.IOException {
@@ -1150,6 +1157,10 @@
 
     /**
      * Reconstitutes this queue from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
@@ -1160,19 +1171,6 @@
             transferer = new TransferStack<E>();
     }
 
-    // Unsafe mechanics
-    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
-                                  String field, Class<?> klazz) {
-        try {
-            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
-        } catch (NoSuchFieldException e) {
-            // Convert Exception to corresponding Error
-            NoSuchFieldError error = new NoSuchFieldError(field);
-            error.initCause(e);
-            throw error;
-        }
-    }
-
     static {
         // Reduce the risk of rare disastrous classloading in first call to
         // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
diff --git a/luni/src/main/java/java/util/concurrent/ThreadFactory.java b/luni/src/main/java/java/util/concurrent/ThreadFactory.java
index d1a4eb6..fdedea3 100644
--- a/luni/src/main/java/java/util/concurrent/ThreadFactory.java
+++ b/luni/src/main/java/java/util/concurrent/ThreadFactory.java
@@ -13,7 +13,7 @@
  *
  * <p>
  * The simplest implementation of this interface is just:
- *  <pre> {@code
+ * <pre> {@code
  * class SimpleThreadFactory implements ThreadFactory {
  *   public Thread newThread(Runnable r) {
  *     return new Thread(r);
diff --git a/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java b/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
index b007af2..8c65bde 100644
--- a/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
+++ b/luni/src/main/java/java/util/concurrent/ThreadLocalRandom.java
@@ -6,7 +6,19 @@
 
 package java.util.concurrent;
 
+import java.io.ObjectStreamField;
 import java.util.Random;
+import java.util.Spliterator;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+// TODO(streams):
+// import java.util.stream.DoubleStream;
+// import java.util.stream.IntStream;
+// import java.util.stream.LongStream;
+// import java.util.stream.StreamSupport;
 
 /**
  * A random number generator isolated to the current thread.  Like the
@@ -29,50 +41,98 @@
  * <p>This class also provides additional commonly used bounded random
  * generation methods.
  *
+ * <p>Instances of {@code ThreadLocalRandom} are not cryptographically
+ * secure.  Consider instead using {@link java.security.SecureRandom}
+ * in security-sensitive applications. Additionally,
+ * default-constructed instances do not use a cryptographically random
+ * seed unless the {@linkplain System#getProperty system property}
+ * {@code java.util.secureRandomSeed} is set to {@code true}.
+ *
  * @since 1.7
  * @author Doug Lea
  */
 public class ThreadLocalRandom extends Random {
-    // same constants as Random, but must be redeclared because private
-    private static final long multiplier = 0x5DEECE66DL;
-    private static final long addend = 0xBL;
-    private static final long mask = (1L << 48) - 1;
-
-    /**
-     * The random seed. We can't use super.seed.
+    /*
+     * This class implements the java.util.Random API (and subclasses
+     * Random) using a single static instance that accesses random
+     * number state held in class Thread (primarily, field
+     * threadLocalRandomSeed). In doing so, it also provides a home
+     * for managing package-private utilities that rely on exactly the
+     * same state as needed to maintain the ThreadLocalRandom
+     * instances. We leverage the need for an initialization flag
+     * field to also use it as a "probe" -- a self-adjusting thread
+     * hash used for contention avoidance, as well as a secondary
+     * simpler (xorShift) random seed that is conservatively used to
+     * avoid otherwise surprising users by hijacking the
+     * ThreadLocalRandom sequence.  The dual use is a marriage of
+     * convenience, but is a simple and efficient way of reducing
+     * application-level overhead and footprint of most concurrent
+     * programs.
+     *
+     * Even though this class subclasses java.util.Random, it uses the
+     * same basic algorithm as java.util.SplittableRandom.  (See its
+     * internal documentation for explanations, which are not repeated
+     * here.)  Because ThreadLocalRandoms are not splittable
+     * though, we use only a single 64bit gamma.
+     *
+     * Because this class is in a different package than class Thread,
+     * field access methods use Unsafe to bypass access control rules.
+     * To conform to the requirements of the Random superclass
+     * constructor, the common static ThreadLocalRandom maintains an
+     * "initialized" field for the sake of rejecting user calls to
+     * setSeed while still allowing a call from constructor.  Note
+     * that serialization is completely unnecessary because there is
+     * only a static singleton.  But we generate a serial form
+     * containing "rnd" and "initialized" fields to ensure
+     * compatibility across versions.
+     *
+     * Implementations of non-core methods are mostly the same as in
+     * SplittableRandom, that were in part derived from a previous
+     * version of this class.
+     *
+     * The nextLocalGaussian ThreadLocal supports the very rarely used
+     * nextGaussian method by providing a holder for the second of a
+     * pair of them. As is true for the base class version of this
+     * method, this time/space tradeoff is probably never worthwhile,
+     * but we provide identical statistical properties.
      */
-    private long rnd;
+
+    private static long mix64(long z) {
+        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+        z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
+        return z ^ (z >>> 33);
+    }
+
+    private static int mix32(long z) {
+        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+        return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
+    }
 
     /**
-     * Initialization flag to permit calls to setSeed to succeed only
-     * while executing the Random constructor.  We can't allow others
-     * since it would cause setting seed in one part of a program to
-     * unintentionally impact other usages by the thread.
+     * Field used only during singleton initialization.
+     * True when constructor completes.
      */
     boolean initialized;
 
-    // Padding to help avoid memory contention among seed updates in
-    // different TLRs in the common case that they are located near
-    // each other.
-    private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
+    /** Constructor used only for static singleton */
+    private ThreadLocalRandom() {
+        initialized = true; // false during super() call
+    }
 
     /**
-     * The actual ThreadLocal
+     * Initialize Thread fields for the current thread.  Called only
+     * when Thread.threadLocalRandomProbe is zero, indicating that a
+     * thread local seed value needs to be generated. Note that even
+     * though the initialization is purely thread-local, we need to
+     * rely on (static) atomic generators to initialize the values.
      */
-    private static final ThreadLocal<ThreadLocalRandom> localRandom =
-        new ThreadLocal<ThreadLocalRandom>() {
-            protected ThreadLocalRandom initialValue() {
-                return new ThreadLocalRandom();
-            }
-    };
-
-
-    /**
-     * Constructor called only by localRandom.initialValue.
-     */
-    ThreadLocalRandom() {
-        super();
-        initialized = true;
+    static final void localInit() {
+        int p = probeGenerator.addAndGet(PROBE_INCREMENT);
+        int probe = (p == 0) ? 1 : p; // skip 0
+        long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
+        Thread t = Thread.currentThread();
+        U.putLong(t, SEED, seed);
+        U.putInt(t, PROBE, probe);
     }
 
     /**
@@ -81,7 +141,9 @@
      * @return the current thread's {@code ThreadLocalRandom}
      */
     public static ThreadLocalRandom current() {
-        return localRandom.get();
+        if (U.getInt(Thread.currentThread(), PROBE) == 0)
+            localInit();
+        return instance;
     }
 
     /**
@@ -91,107 +153,894 @@
      * @throws UnsupportedOperationException always
      */
     public void setSeed(long seed) {
+        // only allow call from super() constructor
         if (initialized)
             throw new UnsupportedOperationException();
-        rnd = (seed ^ multiplier) & mask;
     }
 
+    final long nextSeed() {
+        Thread t; long r; // read and update per-thread seed
+        U.putLong(t = Thread.currentThread(), SEED,
+                  r = U.getLong(t, SEED) + GAMMA);
+        return r;
+    }
+
+    // We must define this, but never use it.
     protected int next(int bits) {
-        rnd = (rnd * multiplier + addend) & mask;
-        return (int) (rnd >>> (48-bits));
+        return (int)(mix64(nextSeed()) >>> (64 - bits));
     }
 
     /**
-     * Returns a pseudorandom, uniformly distributed value between the
-     * given least value (inclusive) and bound (exclusive).
+     * The form of nextLong used by LongStream Spliterators.  If
+     * origin is greater than bound, acts as unbounded form of
+     * nextLong, else as bounded form.
      *
-     * @param least the least value returned
-     * @param bound the upper bound (exclusive)
-     * @return the next value
-     * @throws IllegalArgumentException if least greater than or equal
-     * to bound
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
      */
-    public int nextInt(int least, int bound) {
-        if (least >= bound)
-            throw new IllegalArgumentException();
-        return nextInt(bound - least) + least;
-    }
-
-    /**
-     * Returns a pseudorandom, uniformly distributed value
-     * between 0 (inclusive) and the specified value (exclusive).
-     *
-     * @param n the bound on the random number to be returned.  Must be
-     *        positive.
-     * @return the next value
-     * @throws IllegalArgumentException if n is not positive
-     */
-    public long nextLong(long n) {
-        if (n <= 0)
-            throw new IllegalArgumentException("n must be positive");
-        // Divide n by two until small enough for nextInt. On each
-        // iteration (at most 31 of them but usually much less),
-        // randomly choose both whether to include high bit in result
-        // (offset) and whether to continue with the lower vs upper
-        // half (which makes a difference only if odd).
-        long offset = 0;
-        while (n >= Integer.MAX_VALUE) {
-            int bits = next(2);
-            long half = n >>> 1;
-            long nextn = ((bits & 2) == 0) ? half : n - half;
-            if ((bits & 1) == 0)
-                offset += n - nextn;
-            n = nextn;
+    final long internalNextLong(long origin, long bound) {
+        long r = mix64(nextSeed());
+        if (origin < bound) {
+            long n = bound - origin, m = n - 1;
+            if ((n & m) == 0L)  // power of two
+                r = (r & m) + origin;
+            else if (n > 0L) {  // reject over-represented candidates
+                for (long u = r >>> 1;            // ensure nonnegative
+                     u + m - (r = u % n) < 0L;    // rejection check
+                     u = mix64(nextSeed()) >>> 1) // retry
+                    ;
+                r += origin;
+            }
+            else {              // range not representable as long
+                while (r < origin || r >= bound)
+                    r = mix64(nextSeed());
+            }
         }
-        return offset + nextInt((int) n);
+        return r;
     }
 
     /**
-     * Returns a pseudorandom, uniformly distributed value between the
-     * given least value (inclusive) and bound (exclusive).
+     * The form of nextInt used by IntStream Spliterators.
+     * Exactly the same as long version, except for types.
      *
-     * @param least the least value returned
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final int internalNextInt(int origin, int bound) {
+        int r = mix32(nextSeed());
+        if (origin < bound) {
+            int n = bound - origin, m = n - 1;
+            if ((n & m) == 0)
+                r = (r & m) + origin;
+            else if (n > 0) {
+                for (int u = r >>> 1;
+                     u + m - (r = u % n) < 0;
+                     u = mix32(nextSeed()) >>> 1)
+                    ;
+                r += origin;
+            }
+            else {
+                while (r < origin || r >= bound)
+                    r = mix32(nextSeed());
+            }
+        }
+        return r;
+    }
+
+    /**
+     * The form of nextDouble used by DoubleStream Spliterators.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final double internalNextDouble(double origin, double bound) {
+        double r = (nextLong() >>> 11) * DOUBLE_UNIT;
+        if (origin < bound) {
+            r = r * (bound - origin) + origin;
+            if (r >= bound) // correct for rounding
+                r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+        }
+        return r;
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value.
+     *
+     * @return a pseudorandom {@code int} value
+     */
+    public int nextInt() {
+        return mix32(nextSeed());
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value between zero (inclusive)
+     * and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code int} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public int nextInt(int bound) {
+        if (bound <= 0)
+            throw new IllegalArgumentException(BAD_BOUND);
+        int r = mix32(nextSeed());
+        int m = bound - 1;
+        if ((bound & m) == 0) // power of two
+            r &= m;
+        else { // reject over-represented candidates
+            for (int u = r >>> 1;
+                 u + m - (r = u % bound) < 0;
+                 u = mix32(nextSeed()) >>> 1)
+                ;
+        }
+        return r;
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value between the specified
+     * origin (inclusive) and the specified bound (exclusive).
+     *
+     * @param origin the least value returned
      * @param bound the upper bound (exclusive)
-     * @return the next value
-     * @throws IllegalArgumentException if least greater than or equal
-     * to bound
+     * @return a pseudorandom {@code int} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
      */
-    public long nextLong(long least, long bound) {
-        if (least >= bound)
-            throw new IllegalArgumentException();
-        return nextLong(bound - least) + least;
+    public int nextInt(int origin, int bound) {
+        if (origin >= bound)
+            throw new IllegalArgumentException(BAD_RANGE);
+        return internalNextInt(origin, bound);
     }
 
     /**
-     * Returns a pseudorandom, uniformly distributed {@code double} value
-     * between 0 (inclusive) and the specified value (exclusive).
+     * Returns a pseudorandom {@code long} value.
      *
-     * @param n the bound on the random number to be returned.  Must be
-     *        positive.
-     * @return the next value
-     * @throws IllegalArgumentException if n is not positive
+     * @return a pseudorandom {@code long} value
      */
-    public double nextDouble(double n) {
-        if (!(n > 0))
-            throw new IllegalArgumentException("n must be positive");
-        return nextDouble() * n;
+    public long nextLong() {
+        return mix64(nextSeed());
     }
 
     /**
-     * Returns a pseudorandom, uniformly distributed value between the
-     * given least value (inclusive) and bound (exclusive).
+     * Returns a pseudorandom {@code long} value between zero (inclusive)
+     * and the specified bound (exclusive).
      *
-     * @param least the least value returned
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code long} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public long nextLong(long bound) {
+        if (bound <= 0)
+            throw new IllegalArgumentException(BAD_BOUND);
+        long r = mix64(nextSeed());
+        long m = bound - 1;
+        if ((bound & m) == 0L) // power of two
+            r &= m;
+        else { // reject over-represented candidates
+            for (long u = r >>> 1;
+                 u + m - (r = u % bound) < 0L;
+                 u = mix64(nextSeed()) >>> 1)
+                ;
+        }
+        return r;
+    }
+
+    /**
+     * Returns a pseudorandom {@code long} value between the specified
+     * origin (inclusive) and the specified bound (exclusive).
+     *
+     * @param origin the least value returned
      * @param bound the upper bound (exclusive)
-     * @return the next value
-     * @throws IllegalArgumentException if least greater than or equal
-     * to bound
+     * @return a pseudorandom {@code long} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
      */
-    public double nextDouble(double least, double bound) {
-        if (least >= bound)
-            throw new IllegalArgumentException();
-        return nextDouble() * (bound - least) + least;
+    public long nextLong(long origin, long bound) {
+        if (origin >= bound)
+            throw new IllegalArgumentException(BAD_RANGE);
+        return internalNextLong(origin, bound);
     }
 
+    /**
+     * Returns a pseudorandom {@code double} value between zero
+     * (inclusive) and one (exclusive).
+     *
+     * @return a pseudorandom {@code double} value between zero
+     *         (inclusive) and one (exclusive)
+     */
+    public double nextDouble() {
+        return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
+    }
+
+    /**
+     * Returns a pseudorandom {@code double} value between 0.0
+     * (inclusive) and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code double} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public double nextDouble(double bound) {
+        if (!(bound > 0.0))
+            throw new IllegalArgumentException(BAD_BOUND);
+        double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
+        return (result < bound) ? result : // correct for rounding
+            Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+    }
+
+    /**
+     * Returns a pseudorandom {@code double} value between the specified
+     * origin (inclusive) and bound (exclusive).
+     *
+     * @param origin the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return a pseudorandom {@code double} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
+     */
+    public double nextDouble(double origin, double bound) {
+        if (!(origin < bound))
+            throw new IllegalArgumentException(BAD_RANGE);
+        return internalNextDouble(origin, bound);
+    }
+
+    /**
+     * Returns a pseudorandom {@code boolean} value.
+     *
+     * @return a pseudorandom {@code boolean} value
+     */
+    public boolean nextBoolean() {
+        return mix32(nextSeed()) < 0;
+    }
+
+    /**
+     * Returns a pseudorandom {@code float} value between zero
+     * (inclusive) and one (exclusive).
+     *
+     * @return a pseudorandom {@code float} value between zero
+     *         (inclusive) and one (exclusive)
+     */
+    public float nextFloat() {
+        return (mix32(nextSeed()) >>> 8) * FLOAT_UNIT;
+    }
+
+    public double nextGaussian() {
+        // Use nextLocalGaussian instead of nextGaussian field
+        Double d = nextLocalGaussian.get();
+        if (d != null) {
+            nextLocalGaussian.set(null);
+            return d.doubleValue();
+        }
+        double v1, v2, s;
+        do {
+            v1 = 2 * nextDouble() - 1; // between -1 and 1
+            v2 = 2 * nextDouble() - 1; // between -1 and 1
+            s = v1 * v1 + v2 * v2;
+        } while (s >= 1 || s == 0);
+        double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
+        nextLocalGaussian.set(new Double(v2 * multiplier));
+        return v1 * multiplier;
+    }
+
+    // stream methods, coded in a way intended to better isolate for
+    // maintenance purposes the small differences across forms.
+
+    // TODO(streams):
+    // /**
+    //  * Returns a stream producing the given {@code streamSize} number of
+    //  * pseudorandom {@code int} values.
+    //  *
+    //  * @param streamSize the number of values to generate
+    //  * @return a stream of pseudorandom {@code int} values
+    //  * @throws IllegalArgumentException if {@code streamSize} is
+    //  *         less than zero
+    //  * @since 1.8
+    //  */
+    // public IntStream ints(long streamSize) {
+    //     if (streamSize < 0L)
+    //         throw new IllegalArgumentException(BAD_SIZE);
+    //     return StreamSupport.intStream
+    //         (new RandomIntsSpliterator
+    //          (0L, streamSize, Integer.MAX_VALUE, 0),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns an effectively unlimited stream of pseudorandom {@code int}
+    //  * values.
+    //  *
+    //  * @implNote This method is implemented to be equivalent to {@code
+    //  * ints(Long.MAX_VALUE)}.
+    //  *
+    //  * @return a stream of pseudorandom {@code int} values
+    //  * @since 1.8
+    //  */
+    // public IntStream ints() {
+    //     return StreamSupport.intStream
+    //         (new RandomIntsSpliterator
+    //          (0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns a stream producing the given {@code streamSize} number
+    //  * of pseudorandom {@code int} values, each conforming to the given
+    //  * origin (inclusive) and bound (exclusive).
+    //  *
+    //  * @param streamSize the number of values to generate
+    //  * @param randomNumberOrigin the origin (inclusive) of each random value
+    //  * @param randomNumberBound the bound (exclusive) of each random value
+    //  * @return a stream of pseudorandom {@code int} values,
+    //  *         each with the given origin (inclusive) and bound (exclusive)
+    //  * @throws IllegalArgumentException if {@code streamSize} is
+    //  *         less than zero, or {@code randomNumberOrigin}
+    //  *         is greater than or equal to {@code randomNumberBound}
+    //  * @since 1.8
+    //  */
+    // public IntStream ints(long streamSize, int randomNumberOrigin,
+    //                       int randomNumberBound) {
+    //     if (streamSize < 0L)
+    //         throw new IllegalArgumentException(BAD_SIZE);
+    //     if (randomNumberOrigin >= randomNumberBound)
+    //         throw new IllegalArgumentException(BAD_RANGE);
+    //     return StreamSupport.intStream
+    //         (new RandomIntsSpliterator
+    //          (0L, streamSize, randomNumberOrigin, randomNumberBound),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns an effectively unlimited stream of pseudorandom {@code
+    //  * int} values, each conforming to the given origin (inclusive) and bound
+    //  * (exclusive).
+    //  *
+    //  * @implNote This method is implemented to be equivalent to {@code
+    //  * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+    //  *
+    //  * @param randomNumberOrigin the origin (inclusive) of each random value
+    //  * @param randomNumberBound the bound (exclusive) of each random value
+    //  * @return a stream of pseudorandom {@code int} values,
+    //  *         each with the given origin (inclusive) and bound (exclusive)
+    //  * @throws IllegalArgumentException if {@code randomNumberOrigin}
+    //  *         is greater than or equal to {@code randomNumberBound}
+    //  * @since 1.8
+    //  */
+    // public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+    //     if (randomNumberOrigin >= randomNumberBound)
+    //         throw new IllegalArgumentException(BAD_RANGE);
+    //     return StreamSupport.intStream
+    //         (new RandomIntsSpliterator
+    //          (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns a stream producing the given {@code streamSize} number of
+    //  * pseudorandom {@code long} values.
+    //  *
+    //  * @param streamSize the number of values to generate
+    //  * @return a stream of pseudorandom {@code long} values
+    //  * @throws IllegalArgumentException if {@code streamSize} is
+    //  *         less than zero
+    //  * @since 1.8
+    //  */
+    // public LongStream longs(long streamSize) {
+    //     if (streamSize < 0L)
+    //         throw new IllegalArgumentException(BAD_SIZE);
+    //     return StreamSupport.longStream
+    //         (new RandomLongsSpliterator
+    //          (0L, streamSize, Long.MAX_VALUE, 0L),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns an effectively unlimited stream of pseudorandom {@code long}
+    //  * values.
+    //  *
+    //  * @implNote This method is implemented to be equivalent to {@code
+    //  * longs(Long.MAX_VALUE)}.
+    //  *
+    //  * @return a stream of pseudorandom {@code long} values
+    //  * @since 1.8
+    //  */
+    // public LongStream longs() {
+    //     return StreamSupport.longStream
+    //         (new RandomLongsSpliterator
+    //          (0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns a stream producing the given {@code streamSize} number of
+    //  * pseudorandom {@code long}, each conforming to the given origin
+    //  * (inclusive) and bound (exclusive).
+    //  *
+    //  * @param streamSize the number of values to generate
+    //  * @param randomNumberOrigin the origin (inclusive) of each random value
+    //  * @param randomNumberBound the bound (exclusive) of each random value
+    //  * @return a stream of pseudorandom {@code long} values,
+    //  *         each with the given origin (inclusive) and bound (exclusive)
+    //  * @throws IllegalArgumentException if {@code streamSize} is
+    //  *         less than zero, or {@code randomNumberOrigin}
+    //  *         is greater than or equal to {@code randomNumberBound}
+    //  * @since 1.8
+    //  */
+    // public LongStream longs(long streamSize, long randomNumberOrigin,
+    //                         long randomNumberBound) {
+    //     if (streamSize < 0L)
+    //         throw new IllegalArgumentException(BAD_SIZE);
+    //     if (randomNumberOrigin >= randomNumberBound)
+    //         throw new IllegalArgumentException(BAD_RANGE);
+    //     return StreamSupport.longStream
+    //         (new RandomLongsSpliterator
+    //          (0L, streamSize, randomNumberOrigin, randomNumberBound),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns an effectively unlimited stream of pseudorandom {@code
+    //  * long} values, each conforming to the given origin (inclusive) and bound
+    //  * (exclusive).
+    //  *
+    //  * @implNote This method is implemented to be equivalent to {@code
+    //  * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+    //  *
+    //  * @param randomNumberOrigin the origin (inclusive) of each random value
+    //  * @param randomNumberBound the bound (exclusive) of each random value
+    //  * @return a stream of pseudorandom {@code long} values,
+    //  *         each with the given origin (inclusive) and bound (exclusive)
+    //  * @throws IllegalArgumentException if {@code randomNumberOrigin}
+    //  *         is greater than or equal to {@code randomNumberBound}
+    //  * @since 1.8
+    //  */
+    // public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+    //     if (randomNumberOrigin >= randomNumberBound)
+    //         throw new IllegalArgumentException(BAD_RANGE);
+    //     return StreamSupport.longStream
+    //         (new RandomLongsSpliterator
+    //          (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns a stream producing the given {@code streamSize} number of
+    //  * pseudorandom {@code double} values, each between zero
+    //  * (inclusive) and one (exclusive).
+    //  *
+    //  * @param streamSize the number of values to generate
+    //  * @return a stream of {@code double} values
+    //  * @throws IllegalArgumentException if {@code streamSize} is
+    //  *         less than zero
+    //  * @since 1.8
+    //  */
+    // public DoubleStream doubles(long streamSize) {
+    //     if (streamSize < 0L)
+    //         throw new IllegalArgumentException(BAD_SIZE);
+    //     return StreamSupport.doubleStream
+    //         (new RandomDoublesSpliterator
+    //          (0L, streamSize, Double.MAX_VALUE, 0.0),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns an effectively unlimited stream of pseudorandom {@code
+    //  * double} values, each between zero (inclusive) and one
+    //  * (exclusive).
+    //  *
+    //  * @implNote This method is implemented to be equivalent to {@code
+    //  * doubles(Long.MAX_VALUE)}.
+    //  *
+    //  * @return a stream of pseudorandom {@code double} values
+    //  * @since 1.8
+    //  */
+    // public DoubleStream doubles() {
+    //     return StreamSupport.doubleStream
+    //         (new RandomDoublesSpliterator
+    //          (0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns a stream producing the given {@code streamSize} number of
+    //  * pseudorandom {@code double} values, each conforming to the given origin
+    //  * (inclusive) and bound (exclusive).
+    //  *
+    //  * @param streamSize the number of values to generate
+    //  * @param randomNumberOrigin the origin (inclusive) of each random value
+    //  * @param randomNumberBound the bound (exclusive) of each random value
+    //  * @return a stream of pseudorandom {@code double} values,
+    //  *         each with the given origin (inclusive) and bound (exclusive)
+    //  * @throws IllegalArgumentException if {@code streamSize} is
+    //  *         less than zero
+    //  * @throws IllegalArgumentException if {@code randomNumberOrigin}
+    //  *         is greater than or equal to {@code randomNumberBound}
+    //  * @since 1.8
+    //  */
+    // public DoubleStream doubles(long streamSize, double randomNumberOrigin,
+    //                             double randomNumberBound) {
+    //     if (streamSize < 0L)
+    //         throw new IllegalArgumentException(BAD_SIZE);
+    //     if (!(randomNumberOrigin < randomNumberBound))
+    //         throw new IllegalArgumentException(BAD_RANGE);
+    //     return StreamSupport.doubleStream
+    //         (new RandomDoublesSpliterator
+    //          (0L, streamSize, randomNumberOrigin, randomNumberBound),
+    //          false);
+    // }
+
+    // /**
+    //  * Returns an effectively unlimited stream of pseudorandom {@code
+    //  * double} values, each conforming to the given origin (inclusive) and bound
+    //  * (exclusive).
+    //  *
+    //  * @implNote This method is implemented to be equivalent to {@code
+    //  * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+    //  *
+    //  * @param randomNumberOrigin the origin (inclusive) of each random value
+    //  * @param randomNumberBound the bound (exclusive) of each random value
+    //  * @return a stream of pseudorandom {@code double} values,
+    //  *         each with the given origin (inclusive) and bound (exclusive)
+    //  * @throws IllegalArgumentException if {@code randomNumberOrigin}
+    //  *         is greater than or equal to {@code randomNumberBound}
+    //  * @since 1.8
+    //  */
+    // public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+    //     if (!(randomNumberOrigin < randomNumberBound))
+    //         throw new IllegalArgumentException(BAD_RANGE);
+    //     return StreamSupport.doubleStream
+    //         (new RandomDoublesSpliterator
+    //          (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+    //          false);
+    // }
+
+    /**
+     * Spliterator for int streams.  We multiplex the four int
+     * versions into one class by treating a bound less than origin as
+     * unbounded, and also by treating "infinite" as equivalent to
+     * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
+     * approach. The long and double versions of this class are
+     * identical except for types.
+     */
+    private static final class RandomIntsSpliterator
+            implements Spliterator.OfInt {
+        long index;
+        final long fence;
+        final int origin;
+        final int bound;
+        RandomIntsSpliterator(long index, long fence,
+                              int origin, int bound) {
+            this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomIntsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomIntsSpliterator(i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(ThreadLocalRandom.current().internalNextInt(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                int o = origin, b = bound;
+                ThreadLocalRandom rng = ThreadLocalRandom.current();
+                do {
+                    consumer.accept(rng.internalNextInt(o, b));
+                } while (++i < f);
+            }
+        }
+    }
+
+    /**
+     * Spliterator for long streams.
+     */
+    private static final class RandomLongsSpliterator
+            implements Spliterator.OfLong {
+        long index;
+        final long fence;
+        final long origin;
+        final long bound;
+        RandomLongsSpliterator(long index, long fence,
+                               long origin, long bound) {
+            this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomLongsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomLongsSpliterator(i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(ThreadLocalRandom.current().internalNextLong(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                long o = origin, b = bound;
+                ThreadLocalRandom rng = ThreadLocalRandom.current();
+                do {
+                    consumer.accept(rng.internalNextLong(o, b));
+                } while (++i < f);
+            }
+        }
+
+    }
+
+    /**
+     * Spliterator for double streams.
+     */
+    private static final class RandomDoublesSpliterator
+            implements Spliterator.OfDouble {
+        long index;
+        final long fence;
+        final double origin;
+        final double bound;
+        RandomDoublesSpliterator(long index, long fence,
+                                 double origin, double bound) {
+            this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomDoublesSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomDoublesSpliterator(i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(ThreadLocalRandom.current().internalNextDouble(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                double o = origin, b = bound;
+                ThreadLocalRandom rng = ThreadLocalRandom.current();
+                do {
+                    consumer.accept(rng.internalNextDouble(o, b));
+                } while (++i < f);
+            }
+        }
+    }
+
+
+    // Within-package utilities
+
+    /*
+     * Descriptions of the usages of the methods below can be found in
+     * the classes that use them. Briefly, a thread's "probe" value is
+     * a non-zero hash code that (probably) does not collide with
+     * other existing threads with respect to any power of two
+     * collision space. When it does collide, it is pseudo-randomly
+     * adjusted (using a Marsaglia XorShift). The nextSecondarySeed
+     * method is used in the same contexts as ThreadLocalRandom, but
+     * only for transient usages such as random adaptive spin/block
+     * sequences for which a cheap RNG suffices and for which it could
+     * in principle disrupt user-visible statistical properties of the
+     * main ThreadLocalRandom if we were to use it.
+     *
+     * Note: Because of package-protection issues, versions of some
+     * these methods also appear in some subpackage classes.
+     */
+
+    /**
+     * Returns the probe value for the current thread without forcing
+     * initialization. Note that invoking ThreadLocalRandom.current()
+     * can be used to force initialization on zero return.
+     */
+    static final int getProbe() {
+        return U.getInt(Thread.currentThread(), PROBE);
+    }
+
+    /**
+     * Pseudo-randomly advances and records the given probe value for the
+     * given thread.
+     */
+    static final int advanceProbe(int probe) {
+        probe ^= probe << 13;   // xorshift
+        probe ^= probe >>> 17;
+        probe ^= probe << 5;
+        U.putInt(Thread.currentThread(), PROBE, probe);
+        return probe;
+    }
+
+    /**
+     * Returns the pseudo-randomly initialized or updated secondary seed.
+     */
+    static final int nextSecondarySeed() {
+        int r;
+        Thread t = Thread.currentThread();
+        if ((r = U.getInt(t, SECONDARY)) != 0) {
+            r ^= r << 13;   // xorshift
+            r ^= r >>> 17;
+            r ^= r << 5;
+        }
+        else if ((r = mix32(seeder.getAndAdd(SEEDER_INCREMENT))) == 0)
+            r = 1; // avoid zero
+        U.putInt(t, SECONDARY, r);
+        return r;
+    }
+
+    // Serialization support
+
     private static final long serialVersionUID = -5851777807851030925L;
+
+    /**
+     * @serialField rnd long
+     *              seed for random computations
+     * @serialField initialized boolean
+     *              always true
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+        new ObjectStreamField("rnd", long.class),
+        new ObjectStreamField("initialized", boolean.class),
+    };
+
+    /**
+     * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+
+        java.io.ObjectOutputStream.PutField fields = s.putFields();
+        fields.put("rnd", U.getLong(Thread.currentThread(), SEED));
+        fields.put("initialized", true);
+        s.writeFields();
+    }
+
+    /**
+     * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
+     * @return the {@link #current() current} thread's {@code ThreadLocalRandom}
+     */
+    private Object readResolve() {
+        return current();
+    }
+
+    // Static initialization
+
+    /**
+     * The seed increment.
+     */
+    private static final long GAMMA = 0x9e3779b97f4a7c15L;
+
+    /**
+     * The increment for generating probe values.
+     */
+    private static final int PROBE_INCREMENT = 0x9e3779b9;
+
+    /**
+     * The increment of seeder per new instance.
+     */
+    private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
+
+    // Constants from SplittableRandom
+    private static final double DOUBLE_UNIT = 0x1.0p-53;  // 1.0  / (1L << 53)
+    private static final float  FLOAT_UNIT  = 0x1.0p-24f; // 1.0f / (1 << 24)
+
+    // IllegalArgumentException messages
+    static final String BAD_BOUND = "bound must be positive";
+    static final String BAD_RANGE = "bound must be greater than origin";
+    static final String BAD_SIZE  = "size must be non-negative";
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long SEED;
+    private static final long PROBE;
+    private static final long SECONDARY;
+    static {
+        try {
+            SEED = U.objectFieldOffset
+                (Thread.class.getDeclaredField("threadLocalRandomSeed"));
+            PROBE = U.objectFieldOffset
+                (Thread.class.getDeclaredField("threadLocalRandomProbe"));
+            SECONDARY = U.objectFieldOffset
+                (Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+
+    /** Rarely-used holder for the second of a pair of Gaussians */
+    private static final ThreadLocal<Double> nextLocalGaussian =
+        new ThreadLocal<>();
+
+    /** Generates per-thread initialization/probe field */
+    private static final AtomicInteger probeGenerator = new AtomicInteger();
+
+    /** The common ThreadLocalRandom */
+    static final ThreadLocalRandom instance = new ThreadLocalRandom();
+
+    /**
+     * The next seed for default constructors.
+     */
+    private static final AtomicLong seeder
+        = new AtomicLong(mix64(System.currentTimeMillis()) ^
+                         mix64(System.nanoTime()));
+
+    // at end of <clinit> to survive static initialization circularity
+    static {
+        if (java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Boolean>() {
+                public Boolean run() {
+                    return Boolean.getBoolean("java.util.secureRandomSeed");
+                }})) {
+            byte[] seedBytes = java.security.SecureRandom.getSeed(8);
+            long s = (long)seedBytes[0] & 0xffL;
+            for (int i = 1; i < 8; ++i)
+                s = (s << 8) | ((long)seedBytes[i] & 0xffL);
+            seeder.set(s);
+        }
+    }
 }
diff --git a/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java b/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
index c484920..e601b6a 100644
--- a/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
+++ b/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
@@ -6,11 +6,15 @@
 
 package java.util.concurrent;
 
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.AbstractQueuedSynchronizer;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.*;
 
 // BEGIN android-note
 // removed security manager docs
@@ -45,7 +49,8 @@
  *
  * <dt>Core and maximum pool sizes</dt>
  *
- * <dd>A {@code ThreadPoolExecutor} will automatically adjust the
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * A {@code ThreadPoolExecutor} will automatically adjust the
  * pool size (see {@link #getPoolSize})
  * according to the bounds set by
  * corePoolSize (see {@link #getCorePoolSize}) and
@@ -67,7 +72,8 @@
  *
  * <dt>On-demand construction</dt>
  *
- * <dd>By default, even core threads are initially created and
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * By default, even core threads are initially created and
  * started only when new tasks arrive, but this can be overridden
  * dynamically using method {@link #prestartCoreThread} or {@link
  * #prestartAllCoreThreads}.  You probably want to prestart threads if
@@ -75,7 +81,8 @@
  *
  * <dt>Creating new threads</dt>
  *
- * <dd>New threads are created using a {@link ThreadFactory}.  If not
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * New threads are created using a {@link ThreadFactory}.  If not
  * otherwise specified, a {@link Executors#defaultThreadFactory} is
  * used, that creates threads to all be in the same {@link
  * ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
@@ -83,11 +90,17 @@
  * alter the thread's name, thread group, priority, daemon status,
  * etc. If a {@code ThreadFactory} fails to create a thread when asked
  * by returning null from {@code newThread}, the executor will
- * continue, but might not be able to execute any tasks.</dd>
+ * continue, but might not be able to execute any tasks. Threads
+ * should possess the "modifyThread" {@code RuntimePermission}. If
+ * worker threads or other threads using the pool do not possess this
+ * permission, service may be degraded: configuration changes may not
+ * take effect in a timely manner, and a shutdown pool may remain in a
+ * state in which termination is possible but not completed.</dd>
  *
  * <dt>Keep-alive times</dt>
  *
- * <dd>If the pool currently has more than corePoolSize threads,
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * If the pool currently has more than corePoolSize threads,
  * excess threads will be terminated if they have been idle for more
  * than the keepAliveTime (see {@link #getKeepAliveTime(TimeUnit)}).
  * This provides a means of reducing resource consumption when the
@@ -97,36 +110,37 @@
  * TimeUnit)}.  Using a value of {@code Long.MAX_VALUE} {@link
  * TimeUnit#NANOSECONDS} effectively disables idle threads from ever
  * terminating prior to shut down. By default, the keep-alive policy
- * applies only when there are more than corePoolSize threads. But
+ * applies only when there are more than corePoolSize threads, but
  * method {@link #allowCoreThreadTimeOut(boolean)} can be used to
  * apply this time-out policy to core threads as well, so long as the
  * keepAliveTime value is non-zero. </dd>
  *
  * <dt>Queuing</dt>
  *
- * <dd>Any {@link BlockingQueue} may be used to transfer and hold
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * Any {@link BlockingQueue} may be used to transfer and hold
  * submitted tasks.  The use of this queue interacts with pool sizing:
  *
  * <ul>
  *
- * <li> If fewer than corePoolSize threads are running, the Executor
+ * <li>If fewer than corePoolSize threads are running, the Executor
  * always prefers adding a new thread
- * rather than queuing.</li>
+ * rather than queuing.
  *
- * <li> If corePoolSize or more threads are running, the Executor
+ * <li>If corePoolSize or more threads are running, the Executor
  * always prefers queuing a request rather than adding a new
- * thread.</li>
+ * thread.
  *
- * <li> If a request cannot be queued, a new thread is created unless
+ * <li>If a request cannot be queued, a new thread is created unless
  * this would exceed maximumPoolSize, in which case, the task will be
- * rejected.</li>
+ * rejected.
  *
  * </ul>
  *
  * There are three general strategies for queuing:
  * <ol>
  *
- * <li> <em> Direct handoffs.</em> A good default choice for a work
+ * <li><em> Direct handoffs.</em> A good default choice for a work
  * queue is a {@link SynchronousQueue} that hands off tasks to threads
  * without otherwise holding them. Here, an attempt to queue a task
  * will fail if no threads are immediately available to run it, so a
@@ -135,7 +149,7 @@
  * Direct handoffs generally require unbounded maximumPoolSizes to
  * avoid rejection of new submitted tasks. This in turn admits the
  * possibility of unbounded thread growth when commands continue to
- * arrive on average faster than they can be processed.  </li>
+ * arrive on average faster than they can be processed.
  *
  * <li><em> Unbounded queues.</em> Using an unbounded queue (for
  * example a {@link LinkedBlockingQueue} without a predefined
@@ -148,7 +162,7 @@
  * While this style of queuing can be useful in smoothing out
  * transient bursts of requests, it admits the possibility of
  * unbounded work queue growth when commands continue to arrive on
- * average faster than they can be processed.  </li>
+ * average faster than they can be processed.
  *
  * <li><em>Bounded queues.</em> A bounded queue (for example, an
  * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when
@@ -161,7 +175,7 @@
  * time for more threads than you otherwise allow. Use of small queues
  * generally requires larger pool sizes, which keeps CPUs busier but
  * may encounter unacceptable scheduling overhead, which also
- * decreases throughput.  </li>
+ * decreases throughput.
  *
  * </ol>
  *
@@ -169,7 +183,8 @@
  *
  * <dt>Rejected tasks</dt>
  *
- * <dd>New tasks submitted in method {@link #execute(Runnable)} will be
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * New tasks submitted in method {@link #execute(Runnable)} will be
  * <em>rejected</em> when the Executor has been shut down, and also when
  * the Executor uses finite bounds for both maximum threads and work queue
  * capacity, and is saturated.  In either case, the {@code execute} method
@@ -180,22 +195,22 @@
  *
  * <ol>
  *
- * <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the
+ * <li>In the default {@link ThreadPoolExecutor.AbortPolicy}, the
  * handler throws a runtime {@link RejectedExecutionException} upon
- * rejection. </li>
+ * rejection.
  *
- * <li> In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
+ * <li>In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
  * that invokes {@code execute} itself runs the task. This provides a
  * simple feedback control mechanism that will slow down the rate that
- * new tasks are submitted. </li>
+ * new tasks are submitted.
  *
- * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
- * cannot be executed is simply dropped.  </li>
+ * <li>In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
+ * cannot be executed is simply dropped.
  *
  * <li>In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the
  * executor is not shut down, the task at the head of the work queue
  * is dropped, and then execution is retried (which can fail again,
- * causing this to be repeated.) </li>
+ * causing this to be repeated.)
  *
  * </ol>
  *
@@ -206,7 +221,8 @@
  *
  * <dt>Hook methods</dt>
  *
- * <dd>This class provides {@code protected} overridable
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * This class provides {@code protected} overridable
  * {@link #beforeExecute(Thread, Runnable)} and
  * {@link #afterExecute(Runnable, Throwable)} methods that are called
  * before and after execution of each task.  These can be used to
@@ -216,12 +232,14 @@
  * any special processing that needs to be done once the Executor has
  * fully terminated.
  *
- * <p>If hook or callback methods throw exceptions, internal worker
- * threads may in turn fail and abruptly terminate.</dd>
+ * <p>If hook, callback, or BlockingQueue methods throw exceptions,
+ * internal worker threads may in turn fail, abruptly terminate, and
+ * possibly be replaced.</dd>
  *
  * <dt>Queue maintenance</dt>
  *
- * <dd>Method {@link #getQueue()} allows access to the work queue
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * Method {@link #getQueue()} allows access to the work queue
  * for purposes of monitoring and debugging.  Use of this method for
  * any other purpose is strongly discouraged.  Two supplied methods,
  * {@link #remove(Runnable)} and {@link #purge} are available to
@@ -230,7 +248,8 @@
  *
  * <dt>Finalization</dt>
  *
- * <dd>A pool that is no longer referenced in a program <em>AND</em>
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * A pool that is no longer referenced in a program <em>AND</em>
  * has no remaining threads will be {@code shutdown} automatically. If
  * you would like to ensure that unreferenced pools are reclaimed even
  * if users forget to call {@link #shutdown}, then you must arrange
@@ -244,7 +263,7 @@
  * override one or more of the protected hook methods. For example,
  * here is a subclass that adds a simple pause/resume feature:
  *
- *  <pre> {@code
+ * <pre> {@code
  * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
  *   private boolean isPaused;
  *   private ReentrantLock pauseLock = new ReentrantLock();
@@ -433,10 +452,10 @@
      * Set containing all worker threads in pool. Accessed only when
      * holding mainLock.
      */
-    private final HashSet<Worker> workers = new HashSet<Worker>();
+    private final HashSet<Worker> workers = new HashSet<>();
 
     /**
-     * Wait condition to support awaitTermination
+     * Wait condition to support awaitTermination.
      */
     private final Condition termination = mainLock.newCondition();
 
@@ -512,7 +531,7 @@
     private volatile int maximumPoolSize;
 
     /**
-     * The default rejected execution handler
+     * The default rejected execution handler.
      */
     private static final RejectedExecutionHandler defaultHandler =
         new AbortPolicy();
@@ -639,6 +658,7 @@
      *        (but not TIDYING or TERMINATED -- use tryTerminate for that)
      */
     private void advanceRunState(int targetState) {
+        // assert targetState == SHUTDOWN || targetState == STOP;
         for (;;) {
             int c = ctl.get();
             if (runStateAtLeast(c, targetState) ||
@@ -821,7 +841,7 @@
      */
     private List<Runnable> drainQueue() {
         BlockingQueue<Runnable> q = workQueue;
-        ArrayList<Runnable> taskList = new ArrayList<Runnable>();
+        ArrayList<Runnable> taskList = new ArrayList<>();
         q.drainTo(taskList);
         if (!q.isEmpty()) {
             for (Runnable r : q.toArray(new Runnable[0])) {
@@ -1376,7 +1396,7 @@
      *
      * <p>There are no guarantees beyond best-effort attempts to stop
      * processing actively executing tasks.  This implementation
-     * cancels tasks via {@link Thread#interrupt}, so any task that
+     * interrupts tasks via {@link Thread#interrupt}; any task that
      * fails to respond to interrupts may never terminate.
      */
     // android-note: Removed @throws SecurityException
@@ -1426,13 +1446,12 @@
         final ReentrantLock mainLock = this.mainLock;
         mainLock.lock();
         try {
-            for (;;) {
-                if (runStateAtLeast(ctl.get(), TERMINATED))
-                    return true;
-                if (nanos <= 0)
+            while (!runStateAtLeast(ctl.get(), TERMINATED)) {
+                if (nanos <= 0L)
                     return false;
                 nanos = termination.awaitNanos(nanos);
             }
+            return true;
         } finally {
             mainLock.unlock();
         }
@@ -1501,10 +1520,12 @@
      *
      * @param corePoolSize the new core size
      * @throws IllegalArgumentException if {@code corePoolSize < 0}
+     *         or {@code corePoolSize} is greater than the {@linkplain
+     *         #getMaximumPoolSize() maximum pool size}
      * @see #getCorePoolSize
      */
     public void setCorePoolSize(int corePoolSize) {
-        if (corePoolSize < 0)
+        if (corePoolSize < 0 || maximumPoolSize < corePoolSize)
             throw new IllegalArgumentException();
         int delta = corePoolSize - this.corePoolSize;
         this.corePoolSize = corePoolSize;
@@ -1647,11 +1668,13 @@
     }
 
     /**
-     * Sets the time limit for which threads may remain idle before
-     * being terminated.  If there are more than the core number of
-     * threads currently in the pool, after waiting this amount of
-     * time without processing a task, excess threads will be
-     * terminated.  This overrides any value set in the constructor.
+     * Sets the thread keep-alive time, which is the amount of time
+     * that threads may remain idle before being terminated.
+     * Threads that wait this amount of time without processing a
+     * task will be terminated if there are more than the core
+     * number of threads currently in the pool, or if this pool
+     * {@linkplain #allowsCoreThreadTimeOut() allows core thread timeout}.
+     * This overrides any value set in the constructor.
      *
      * @param time the time to wait.  A time value of zero will cause
      *        excess threads to terminate immediately after executing tasks.
@@ -1674,8 +1697,11 @@
 
     /**
      * Returns the thread keep-alive time, which is the amount of time
-     * that threads in excess of the core pool size may remain
-     * idle before being terminated.
+     * that threads may remain idle before being terminated.
+     * Threads that wait this amount of time without processing a
+     * task will be terminated if there are more than the core
+     * number of threads currently in the pool, or if this pool
+     * {@linkplain #allowsCoreThreadTimeOut() allows core thread timeout}.
      *
      * @param unit the desired time unit of the result
      * @return the time limit
@@ -1706,8 +1732,8 @@
      *
      * <p>This method may be useful as one part of a cancellation
      * scheme.  It may fail to remove tasks that have been converted
-     * into other forms before being placed on the internal queue. For
-     * example, a task entered using {@code submit} might be
+     * into other forms before being placed on the internal queue.
+     * For example, a task entered using {@code submit} might be
      * converted into a form that maintains {@code Future} status.
      * However, in such cases, method {@link #purge} may be used to
      * remove those Futures that have been cancelled.
@@ -1879,11 +1905,12 @@
             mainLock.unlock();
         }
         int c = ctl.get();
-        String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
-                     (runStateAtLeast(c, TERMINATED) ? "Terminated" :
-                      "Shutting down"));
+        String runState =
+            runStateLessThan(c, SHUTDOWN) ? "Running" :
+            runStateAtLeast(c, TERMINATED) ? "Terminated" :
+            "Shutting down";
         return super.toString() +
-            "[" + rs +
+            "[" + runState +
             ", pool size = " + nworkers +
             ", active threads = " + nactive +
             ", queued tasks = " + workQueue.size() +
@@ -1930,20 +1957,23 @@
      * as in this sample subclass that prints either the direct cause
      * or the underlying exception if a task has been aborted:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * class ExtendedExecutor extends ThreadPoolExecutor {
      *   // ...
      *   protected void afterExecute(Runnable r, Throwable t) {
      *     super.afterExecute(r, t);
-     *     if (t == null && r instanceof Future<?>) {
+     *     if (t == null
+     *         && r instanceof Future<?>
+     *         && ((Future<?>)r).isDone()) {
      *       try {
      *         Object result = ((Future<?>) r).get();
      *       } catch (CancellationException ce) {
-     *           t = ce;
+     *         t = ce;
      *       } catch (ExecutionException ee) {
-     *           t = ee.getCause();
+     *         t = ee.getCause();
      *       } catch (InterruptedException ie) {
-     *           Thread.currentThread().interrupt(); // ignore/reset
+     *         // ignore/reset
+     *         Thread.currentThread().interrupt();
      *       }
      *     }
      *     if (t != null)
diff --git a/luni/src/main/java/java/util/concurrent/TimeUnit.java b/luni/src/main/java/java/util/concurrent/TimeUnit.java
index 8e6a5f7..fff02d8 100644
--- a/luni/src/main/java/java/util/concurrent/TimeUnit.java
+++ b/luni/src/main/java/java/util/concurrent/TimeUnit.java
@@ -6,6 +6,12 @@
 
 package java.util.concurrent;
 
+import java.util.Objects;
+
+// BEGIN android-note
+// removed java 9 ChronoUnit related code
+// END android-note
+
 /**
  * A {@code TimeUnit} represents time durations at a given unit of
  * granularity and provides utility methods to convert across units,
@@ -23,12 +29,12 @@
  * the following code will timeout in 50 milliseconds if the {@link
  * java.util.concurrent.locks.Lock lock} is not available:
  *
- *  <pre> {@code
+ * <pre> {@code
  * Lock lock = ...;
  * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...}</pre>
  *
  * while this code will timeout in 50 seconds:
- *  <pre> {@code
+ * <pre> {@code
  * Lock lock = ...;
  * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...}</pre>
  *
@@ -41,7 +47,7 @@
  */
 public enum TimeUnit {
     /**
-     * Time unit representing one thousandth of a microsecond
+     * Time unit representing one thousandth of a microsecond.
      */
     NANOSECONDS {
         public long toNanos(long d)   { return d; }
@@ -56,7 +62,7 @@
     },
 
     /**
-     * Time unit representing one thousandth of a millisecond
+     * Time unit representing one thousandth of a millisecond.
      */
     MICROSECONDS {
         public long toNanos(long d)   { return x(d, C1/C0, MAX/(C1/C0)); }
@@ -71,7 +77,7 @@
     },
 
     /**
-     * Time unit representing one thousandth of a second
+     * Time unit representing one thousandth of a second.
      */
     MILLISECONDS {
         public long toNanos(long d)   { return x(d, C2/C0, MAX/(C2/C0)); }
@@ -86,7 +92,7 @@
     },
 
     /**
-     * Time unit representing one second
+     * Time unit representing one second.
      */
     SECONDS {
         public long toNanos(long d)   { return x(d, C3/C0, MAX/(C3/C0)); }
@@ -101,7 +107,7 @@
     },
 
     /**
-     * Time unit representing sixty seconds
+     * Time unit representing sixty seconds.
      * @since 1.6
      */
     MINUTES {
@@ -117,7 +123,7 @@
     },
 
     /**
-     * Time unit representing sixty minutes
+     * Time unit representing sixty minutes.
      * @since 1.6
      */
     HOURS {
@@ -133,7 +139,7 @@
     },
 
     /**
-     * Time unit representing twenty four hours
+     * Time unit representing twenty four hours.
      * @since 1.6
      */
     DAYS {
@@ -164,7 +170,7 @@
      * This has a short name to make above code more readable.
      */
     static long x(long d, long m, long over) {
-        if (d >  over) return Long.MAX_VALUE;
+        if (d > +over) return Long.MAX_VALUE;
         if (d < -over) return Long.MIN_VALUE;
         return d * m;
     }
@@ -300,7 +306,7 @@
      * method (see {@link BlockingQueue#poll BlockingQueue.poll})
      * using:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * public synchronized Object poll(long timeout, TimeUnit unit)
      *     throws InterruptedException {
      *   while (empty) {
@@ -360,5 +366,4 @@
             Thread.sleep(ms, ns);
         }
     }
-
 }
diff --git a/luni/src/main/java/java/util/concurrent/TransferQueue.java b/luni/src/main/java/java/util/concurrent/TransferQueue.java
index 4c2be6f..d4166b5 100644
--- a/luni/src/main/java/java/util/concurrent/TransferQueue.java
+++ b/luni/src/main/java/java/util/concurrent/TransferQueue.java
@@ -34,7 +34,7 @@
  *
  * @since 1.7
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public interface TransferQueue<E> extends BlockingQueue<E> {
     /**
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
index f51e6af..01e4b07 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
@@ -6,8 +6,6 @@
 
 package java.util.concurrent.atomic;
 
-import sun.misc.Unsafe;
-
 /**
  * A {@code boolean} value that may be updated atomically. See the
  * {@link java.util.concurrent.atomic} package specification for
@@ -21,15 +19,17 @@
  */
 public class AtomicBoolean implements java.io.Serializable {
     private static final long serialVersionUID = 4654671469794556979L;
-    // setup to use Unsafe.compareAndSwapInt for updates
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final long valueOffset;
+
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long VALUE;
 
     static {
         try {
-            valueOffset = unsafe.objectFieldOffset
+            VALUE = U.objectFieldOffset
                 (AtomicBoolean.class.getDeclaredField("value"));
-        } catch (Exception ex) { throw new Error(ex); }
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
     }
 
     private volatile int value;
@@ -64,13 +64,13 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that
+     * @return {@code true} if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(boolean expect, boolean update) {
-        int e = expect ? 1 : 0;
-        int u = update ? 1 : 0;
-        return unsafe.compareAndSwapInt(this, valueOffset, e, u);
+        return U.compareAndSwapInt(this, VALUE,
+                                   (expect ? 1 : 0),
+                                   (update ? 1 : 0));
     }
 
     /**
@@ -83,12 +83,12 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public boolean weakCompareAndSet(boolean expect, boolean update) {
-        int e = expect ? 1 : 0;
-        int u = update ? 1 : 0;
-        return unsafe.compareAndSwapInt(this, valueOffset, e, u);
+        return U.compareAndSwapInt(this, VALUE,
+                                   (expect ? 1 : 0),
+                                   (update ? 1 : 0));
     }
 
     /**
@@ -107,8 +107,7 @@
      * @since 1.6
      */
     public final void lazySet(boolean newValue) {
-        int v = newValue ? 1 : 0;
-        unsafe.putOrderedInt(this, valueOffset, v);
+        U.putOrderedInt(this, VALUE, (newValue ? 1 : 0));
     }
 
     /**
@@ -118,11 +117,11 @@
      * @return the previous value
      */
     public final boolean getAndSet(boolean newValue) {
-        for (;;) {
-            boolean current = get();
-            if (compareAndSet(current, newValue))
-                return current;
-        }
+        boolean prev;
+        do {
+            prev = get();
+        } while (!compareAndSet(prev, newValue));
+        return prev;
     }
 
     /**
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicInteger.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
index 8a15298..849fd8a 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
@@ -6,7 +6,8 @@
 
 package java.util.concurrent.atomic;
 
-import sun.misc.Unsafe;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntUnaryOperator;
 
 /**
  * An {@code int} value that may be updated atomically.  See the
@@ -20,19 +21,20 @@
  *
  * @since 1.5
  * @author Doug Lea
-*/
+ */
 public class AtomicInteger extends Number implements java.io.Serializable {
     private static final long serialVersionUID = 6214790243416807050L;
 
-    // setup to use Unsafe.compareAndSwapInt for updates
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final long valueOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long VALUE;
 
     static {
         try {
-            valueOffset = unsafe.objectFieldOffset
+            VALUE = U.objectFieldOffset
                 (AtomicInteger.class.getDeclaredField("value"));
-        } catch (Exception ex) { throw new Error(ex); }
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
     }
 
     private volatile int value;
@@ -77,7 +79,7 @@
      * @since 1.6
      */
     public final void lazySet(int newValue) {
-        unsafe.putOrderedInt(this, valueOffset, newValue);
+        U.putOrderedInt(this, VALUE, newValue);
     }
 
     /**
@@ -87,11 +89,7 @@
      * @return the previous value
      */
     public final int getAndSet(int newValue) {
-        for (;;) {
-            int current = get();
-            if (compareAndSet(current, newValue))
-                return current;
-        }
+        return U.getAndSetInt(this, VALUE, newValue);
     }
 
     /**
@@ -100,11 +98,11 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that
+     * @return {@code true} if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int expect, int update) {
-        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+        return U.compareAndSwapInt(this, VALUE, expect, update);
     }
 
     /**
@@ -117,10 +115,10 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public final boolean weakCompareAndSet(int expect, int update) {
-        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+        return U.compareAndSwapInt(this, VALUE, expect, update);
     }
 
     /**
@@ -129,12 +127,7 @@
      * @return the previous value
      */
     public final int getAndIncrement() {
-        for (;;) {
-            int current = get();
-            int next = current + 1;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return U.getAndAddInt(this, VALUE, 1);
     }
 
     /**
@@ -143,12 +136,7 @@
      * @return the previous value
      */
     public final int getAndDecrement() {
-        for (;;) {
-            int current = get();
-            int next = current - 1;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return U.getAndAddInt(this, VALUE, -1);
     }
 
     /**
@@ -158,12 +146,7 @@
      * @return the previous value
      */
     public final int getAndAdd(int delta) {
-        for (;;) {
-            int current = get();
-            int next = current + delta;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return U.getAndAddInt(this, VALUE, delta);
     }
 
     /**
@@ -172,12 +155,7 @@
      * @return the updated value
      */
     public final int incrementAndGet() {
-        for (;;) {
-            int current = get();
-            int next = current + 1;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return U.getAndAddInt(this, VALUE, 1) + 1;
     }
 
     /**
@@ -186,12 +164,7 @@
      * @return the updated value
      */
     public final int decrementAndGet() {
-        for (;;) {
-            int current = get();
-            int next = current - 1;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return U.getAndAddInt(this, VALUE, -1) - 1;
     }
 
     /**
@@ -201,12 +174,93 @@
      * @return the updated value
      */
     public final int addAndGet(int delta) {
-        for (;;) {
-            int current = get();
-            int next = current + delta;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return U.getAndAddInt(this, VALUE, delta) + delta;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function, returning the previous value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param updateFunction a side-effect-free function
+     * @return the previous value
+     * @since 1.8
+     */
+    public final int getAndUpdate(IntUnaryOperator updateFunction) {
+        int prev, next;
+        do {
+            prev = get();
+            next = updateFunction.applyAsInt(prev);
+        } while (!compareAndSet(prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function, returning the updated value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param updateFunction a side-effect-free function
+     * @return the updated value
+     * @since 1.8
+     */
+    public final int updateAndGet(IntUnaryOperator updateFunction) {
+        int prev, next;
+        do {
+            prev = get();
+            next = updateFunction.applyAsInt(prev);
+        } while (!compareAndSet(prev, next));
+        return next;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function to the current and given values,
+     * returning the previous value. The function should be
+     * side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function
+     * is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the previous value
+     * @since 1.8
+     */
+    public final int getAndAccumulate(int x,
+                                      IntBinaryOperator accumulatorFunction) {
+        int prev, next;
+        do {
+            prev = get();
+            next = accumulatorFunction.applyAsInt(prev, x);
+        } while (!compareAndSet(prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function to the current and given values,
+     * returning the updated value. The function should be
+     * side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function
+     * is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the updated value
+     * @since 1.8
+     */
+    public final int accumulateAndGet(int x,
+                                      IntBinaryOperator accumulatorFunction) {
+        int prev, next;
+        do {
+            prev = get();
+            next = accumulatorFunction.applyAsInt(prev, x);
+        } while (!compareAndSet(prev, next));
+        return next;
     }
 
     /**
@@ -219,6 +273,7 @@
 
     /**
      * Returns the value of this {@code AtomicInteger} as an {@code int}.
+     * Equivalent to {@link #get()}.
      */
     public int intValue() {
         return get();
@@ -227,6 +282,7 @@
     /**
      * Returns the value of this {@code AtomicInteger} as a {@code long}
      * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
      */
     public long longValue() {
         return (long)get();
@@ -235,6 +291,7 @@
     /**
      * Returns the value of this {@code AtomicInteger} as a {@code float}
      * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
      */
     public float floatValue() {
         return (float)get();
@@ -243,6 +300,7 @@
     /**
      * Returns the value of this {@code AtomicInteger} as a {@code double}
      * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
      */
     public double doubleValue() {
         return (double)get();
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
index fd492d1..7597e53 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
@@ -6,7 +6,8 @@
 
 package java.util.concurrent.atomic;
 
-import sun.misc.Unsafe;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntUnaryOperator;
 
 /**
  * An {@code int} array in which elements may be updated atomically.
@@ -19,16 +20,17 @@
 public class AtomicIntegerArray implements java.io.Serializable {
     private static final long serialVersionUID = 2862133569453604235L;
 
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final int base = unsafe.arrayBaseOffset(int[].class);
-    private static final int shift;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final int ABASE;
+    private static final int ASHIFT;
     private final int[] array;
 
     static {
-        int scale = unsafe.arrayIndexScale(int[].class);
+        ABASE = U.arrayBaseOffset(int[].class);
+        int scale = U.arrayIndexScale(int[].class);
         if ((scale & (scale - 1)) != 0)
-            throw new Error("data type scale not a power of two");
-        shift = 31 - Integer.numberOfLeadingZeros(scale);
+            throw new Error("array index scale not a power of two");
+        ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
     }
 
     private long checkedByteOffset(int i) {
@@ -39,7 +41,7 @@
     }
 
     private static long byteOffset(int i) {
-        return ((long) i << shift) + base;
+        return ((long) i << ASHIFT) + ABASE;
     }
 
     /**
@@ -84,7 +86,7 @@
     }
 
     private int getRaw(long offset) {
-        return unsafe.getIntVolatile(array, offset);
+        return U.getIntVolatile(array, offset);
     }
 
     /**
@@ -94,7 +96,7 @@
      * @param newValue the new value
      */
     public final void set(int i, int newValue) {
-        unsafe.putIntVolatile(array, checkedByteOffset(i), newValue);
+        U.putIntVolatile(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -105,7 +107,7 @@
      * @since 1.6
      */
     public final void lazySet(int i, int newValue) {
-        unsafe.putOrderedInt(array, checkedByteOffset(i), newValue);
+        U.putOrderedInt(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -117,12 +119,7 @@
      * @return the previous value
      */
     public final int getAndSet(int i, int newValue) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            int current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, newValue))
-                return current;
-        }
+        return U.getAndSetInt(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -132,7 +129,7 @@
      * @param i the index
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that
+     * @return {@code true} if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int i, int expect, int update) {
@@ -140,7 +137,7 @@
     }
 
     private boolean compareAndSetRaw(long offset, int expect, int update) {
-        return unsafe.compareAndSwapInt(array, offset, expect, update);
+        return U.compareAndSwapInt(array, offset, expect, update);
     }
 
     /**
@@ -154,7 +151,7 @@
      * @param i the index
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public final boolean weakCompareAndSet(int i, int expect, int update) {
         return compareAndSet(i, expect, update);
@@ -188,12 +185,7 @@
      * @return the previous value
      */
     public final int getAndAdd(int i, int delta) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            int current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, current + delta))
-                return current;
-        }
+        return U.getAndAddInt(array, checkedByteOffset(i), delta);
     }
 
     /**
@@ -203,7 +195,7 @@
      * @return the updated value
      */
     public final int incrementAndGet(int i) {
-        return addAndGet(i, 1);
+        return getAndAdd(i, 1) + 1;
     }
 
     /**
@@ -213,7 +205,7 @@
      * @return the updated value
      */
     public final int decrementAndGet(int i) {
-        return addAndGet(i, -1);
+        return getAndAdd(i, -1) - 1;
     }
 
     /**
@@ -224,13 +216,101 @@
      * @return the updated value
      */
     public final int addAndGet(int i, int delta) {
+        return getAndAdd(i, delta) + delta;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the results
+     * of applying the given function, returning the previous value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param i the index
+     * @param updateFunction a side-effect-free function
+     * @return the previous value
+     * @since 1.8
+     */
+    public final int getAndUpdate(int i, IntUnaryOperator updateFunction) {
         long offset = checkedByteOffset(i);
-        while (true) {
-            int current = getRaw(offset);
-            int next = current + delta;
-            if (compareAndSetRaw(offset, current, next))
-                return next;
-        }
+        int prev, next;
+        do {
+            prev = getRaw(offset);
+            next = updateFunction.applyAsInt(prev);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the results
+     * of applying the given function, returning the updated value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param i the index
+     * @param updateFunction a side-effect-free function
+     * @return the updated value
+     * @since 1.8
+     */
+    public final int updateAndGet(int i, IntUnaryOperator updateFunction) {
+        long offset = checkedByteOffset(i);
+        int prev, next;
+        do {
+            prev = getRaw(offset);
+            next = updateFunction.applyAsInt(prev);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return next;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the
+     * results of applying the given function to the current and
+     * given values, returning the previous value. The function should
+     * be side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function is
+     * applied with the current value at index {@code i} as its first
+     * argument, and the given update as the second argument.
+     *
+     * @param i the index
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the previous value
+     * @since 1.8
+     */
+    public final int getAndAccumulate(int i, int x,
+                                      IntBinaryOperator accumulatorFunction) {
+        long offset = checkedByteOffset(i);
+        int prev, next;
+        do {
+            prev = getRaw(offset);
+            next = accumulatorFunction.applyAsInt(prev, x);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the
+     * results of applying the given function to the current and
+     * given values, returning the updated value. The function should
+     * be side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function is
+     * applied with the current value at index {@code i} as its first
+     * argument, and the given update as the second argument.
+     *
+     * @param i the index
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the updated value
+     * @since 1.8
+     */
+    public final int accumulateAndGet(int i, int x,
+                                      IntBinaryOperator accumulatorFunction) {
+        long offset = checkedByteOffset(i);
+        int prev, next;
+        do {
+            prev = getRaw(offset);
+            next = accumulatorFunction.applyAsInt(prev, x);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return next;
     }
 
     /**
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
index 15e8840..9c55491 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
@@ -7,12 +7,15 @@
 package java.util.concurrent.atomic;
 
 import dalvik.system.VMStack; // android-added
-import sun.misc.Unsafe;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
 import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntUnaryOperator;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 
 /**
  * A reflection-based utility that enables atomic updates to
@@ -49,8 +52,11 @@
      * or the field is inaccessible to the caller according to Java language
      * access control
      */
-    public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
-        return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
+    @CallerSensitive
+    public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,
+                                                              String fieldName) {
+        return new AtomicIntegerFieldUpdaterImpl<U>
+            (tclass, fieldName, VMStack.getStackClass1()); // android-changed
     }
 
     /**
@@ -69,7 +75,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor
      */
@@ -89,7 +95,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor
      */
@@ -133,11 +139,11 @@
      * @return the previous value
      */
     public int getAndSet(T obj, int newValue) {
-        for (;;) {
-            int current = get(obj);
-            if (compareAndSet(obj, current, newValue))
-                return current;
-        }
+        int prev;
+        do {
+            prev = get(obj);
+        } while (!compareAndSet(obj, prev, newValue));
+        return prev;
     }
 
     /**
@@ -148,12 +154,12 @@
      * @return the previous value
      */
     public int getAndIncrement(T obj) {
-        for (;;) {
-            int current = get(obj);
-            int next = current + 1;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -164,12 +170,12 @@
      * @return the previous value
      */
     public int getAndDecrement(T obj) {
-        for (;;) {
-            int current = get(obj);
-            int next = current - 1;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -181,12 +187,12 @@
      * @return the previous value
      */
     public int getAndAdd(T obj, int delta) {
-        for (;;) {
-            int current = get(obj);
-            int next = current + delta;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -197,12 +203,12 @@
      * @return the updated value
      */
     public int incrementAndGet(T obj) {
-        for (;;) {
-            int current = get(obj);
-            int next = current + 1;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
@@ -213,12 +219,12 @@
      * @return the updated value
      */
     public int decrementAndGet(T obj) {
-        for (;;) {
-            int current = get(obj);
-            int next = current - 1;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
@@ -230,31 +236,131 @@
      * @return the updated value
      */
     public int addAndGet(T obj, int delta) {
-        for (;;) {
-            int current = get(obj);
-            int next = current + delta;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
-     * Standard hotspot implementation using intrinsics
+     * Atomically updates the field of the given object managed by this updater
+     * with the results of applying the given function, returning the previous
+     * value. The function should be side-effect-free, since it may be
+     * re-applied when attempted updates fail due to contention among threads.
+     *
+     * @param obj An object whose field to get and set
+     * @param updateFunction a side-effect-free function
+     * @return the previous value
+     * @since 1.8
      */
-    private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
-        private static final Unsafe unsafe = Unsafe.getUnsafe();
-        private final long offset;
-        private final Class<T> tclass;
-        private final Class<?> cclass;
+    public final int getAndUpdate(T obj, IntUnaryOperator updateFunction) {
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = updateFunction.applyAsInt(prev);
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
+    }
 
-        AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName) {
+    /**
+     * Atomically updates the field of the given object managed by this updater
+     * with the results of applying the given function, returning the updated
+     * value. The function should be side-effect-free, since it may be
+     * re-applied when attempted updates fail due to contention among threads.
+     *
+     * @param obj An object whose field to get and set
+     * @param updateFunction a side-effect-free function
+     * @return the updated value
+     * @since 1.8
+     */
+    public final int updateAndGet(T obj, IntUnaryOperator updateFunction) {
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = updateFunction.applyAsInt(prev);
+        } while (!compareAndSet(obj, prev, next));
+        return next;
+    }
+
+    /**
+     * Atomically updates the field of the given object managed by this
+     * updater with the results of applying the given function to the
+     * current and given values, returning the previous value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.  The
+     * function is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param obj An object whose field to get and set
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the previous value
+     * @since 1.8
+     */
+    public final int getAndAccumulate(T obj, int x,
+                                      IntBinaryOperator accumulatorFunction) {
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = accumulatorFunction.applyAsInt(prev, x);
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the field of the given object managed by this
+     * updater with the results of applying the given function to the
+     * current and given values, returning the updated value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.  The
+     * function is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param obj An object whose field to get and set
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the updated value
+     * @since 1.8
+     */
+    public final int accumulateAndGet(T obj, int x,
+                                      IntBinaryOperator accumulatorFunction) {
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = accumulatorFunction.applyAsInt(prev, x);
+        } while (!compareAndSet(obj, prev, next));
+        return next;
+    }
+
+    /**
+     * Standard hotspot implementation using intrinsics.
+     */
+    private static final class AtomicIntegerFieldUpdaterImpl<T>
+        extends AtomicIntegerFieldUpdater<T> {
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private final long offset;
+        /**
+         * if field is protected, the subclass constructing updater, else
+         * the same as tclass
+         */
+        private final Class<?> cclass;
+        /** class holding the field */
+        private final Class<T> tclass;
+
+        AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,
+                                      final String fieldName,
+                                      final Class<?> caller) {
             final Field field;
-            final Class<?> caller;
             final int modifiers;
             try {
-                field = tclass.getDeclaredField(fieldName); // android-changed
-                caller = VMStack.getStackClass2(); // android-changed
-
+                field = AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Field>() {
+                        public Field run() throws NoSuchFieldException {
+                            return tclass.getDeclaredField(fieldName);
+                        }
+                    });
                 modifiers = field.getModifiers();
                 // BEGIN android-removed
                 // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
@@ -263,7 +369,7 @@
                 // ClassLoader ccl = caller.getClassLoader();
                 // if ((ccl != null) && (ccl != cl) &&
                 //     ((cl == null) || !isAncestor(cl, ccl))) {
-                //   sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
                 // }
                 // END android-removed
             // BEGIN android-removed
@@ -274,17 +380,15 @@
                 throw new RuntimeException(ex);
             }
 
-            Class<?> fieldt = field.getType();
-            if (fieldt != int.class)
+            if (field.getType() != int.class)
                 throw new IllegalArgumentException("Must be integer type");
 
             if (!Modifier.isVolatile(modifiers))
                 throw new IllegalArgumentException("Must be volatile type");
 
-            this.cclass = (Modifier.isProtected(modifiers) &&
-                           caller != tclass) ? caller : null;
+            this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
             this.tclass = tclass;
-            offset = unsafe.objectFieldOffset(field);
+            this.offset = U.objectFieldOffset(field);
         }
 
         // BEGIN android-removed
@@ -293,7 +397,7 @@
         //  * classloader's delegation chain.
         //  * Equivalent to the inaccessible: first.isAncestor(second).
         //  */
-        //  private static boolean isAncestor(ClassLoader first, ClassLoader second) {
+        // private static boolean isAncestor(ClassLoader first, ClassLoader second) {
         //     ClassLoader acl = first;
         //     do {
         //         acl = acl.getParent();
@@ -304,51 +408,88 @@
         //     return false;
         // }
         // END android-removed
-        private void fullCheck(T obj) {
-            if (!tclass.isInstance(obj))
+
+        /**
+         * Checks that target argument is instance of cclass.  On
+         * failure, throws cause.
+         */
+        private final void accessCheck(T obj) {
+            if (!cclass.isInstance(obj))
+                throwAccessCheckException(obj);
+        }
+
+        /**
+         * Throws access exception if accessCheck failed due to
+         * protected access, else ClassCastException.
+         */
+        private final void throwAccessCheckException(T obj) {
+            if (cclass == tclass)
                 throw new ClassCastException();
-            if (cclass != null)
-                ensureProtectedAccess(obj);
+            else
+                throw new RuntimeException(
+                    new IllegalAccessException(
+                        "Class " +
+                        cclass.getName() +
+                        " can not access a protected member of class " +
+                        tclass.getName() +
+                        " using an instance of " +
+                        obj.getClass().getName()));
         }
 
-        public boolean compareAndSet(T obj, int expect, int update) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            return unsafe.compareAndSwapInt(obj, offset, expect, update);
+        public final boolean compareAndSet(T obj, int expect, int update) {
+            accessCheck(obj);
+            return U.compareAndSwapInt(obj, offset, expect, update);
         }
 
-        public boolean weakCompareAndSet(T obj, int expect, int update) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            return unsafe.compareAndSwapInt(obj, offset, expect, update);
+        public final boolean weakCompareAndSet(T obj, int expect, int update) {
+            accessCheck(obj);
+            return U.compareAndSwapInt(obj, offset, expect, update);
         }
 
-        public void set(T obj, int newValue) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            unsafe.putIntVolatile(obj, offset, newValue);
+        public final void set(T obj, int newValue) {
+            accessCheck(obj);
+            U.putIntVolatile(obj, offset, newValue);
         }
 
-        public void lazySet(T obj, int newValue) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            unsafe.putOrderedInt(obj, offset, newValue);
+        public final void lazySet(T obj, int newValue) {
+            accessCheck(obj);
+            U.putOrderedInt(obj, offset, newValue);
         }
 
         public final int get(T obj) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            return unsafe.getIntVolatile(obj, offset);
+            accessCheck(obj);
+            return U.getIntVolatile(obj, offset);
         }
 
-        private void ensureProtectedAccess(T obj) {
-            if (cclass.isInstance(obj)) {
-                return;
-            }
-            throw new RuntimeException(
-                new IllegalAccessException("Class " +
-                    cclass.getName() +
-                    " can not access a protected member of class " +
-                    tclass.getName() +
-                    " using an instance of " +
-                    obj.getClass().getName()
-                )
-            );
+        public final int getAndSet(T obj, int newValue) {
+            accessCheck(obj);
+            return U.getAndSetInt(obj, offset, newValue);
         }
+
+        public final int getAndAdd(T obj, int delta) {
+            accessCheck(obj);
+            return U.getAndAddInt(obj, offset, delta);
+        }
+
+        public final int getAndIncrement(T obj) {
+            return getAndAdd(obj, 1);
+        }
+
+        public final int getAndDecrement(T obj) {
+            return getAndAdd(obj, -1);
+        }
+
+        public final int incrementAndGet(T obj) {
+            return getAndAdd(obj, 1) + 1;
+        }
+
+        public final int decrementAndGet(T obj) {
+            return getAndAdd(obj, -1) - 1;
+        }
+
+        public final int addAndGet(T obj, int delta) {
+            return getAndAdd(obj, delta) + delta;
+        }
+
     }
 }
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicLong.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicLong.java
index ab2961a..fdb5f55 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicLong.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicLong.java
@@ -6,7 +6,8 @@
 
 package java.util.concurrent.atomic;
 
-import sun.misc.Unsafe;
+import java.util.function.LongBinaryOperator;
+import java.util.function.LongUnaryOperator;
 
 /**
  * A {@code long} value that may be updated atomically.  See the
@@ -24,9 +25,8 @@
 public class AtomicLong extends Number implements java.io.Serializable {
     private static final long serialVersionUID = 1927816293512124184L;
 
-    // setup to use Unsafe.compareAndSwapLong for updates
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final long valueOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long VALUE;
 
     /**
      * Records whether the underlying JVM supports lockless
@@ -44,9 +44,11 @@
 
     static {
         try {
-            valueOffset = unsafe.objectFieldOffset
+            VALUE = U.objectFieldOffset
                 (AtomicLong.class.getDeclaredField("value"));
-        } catch (Exception ex) { throw new Error(ex); }
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
     }
 
     private volatile long value;
@@ -81,7 +83,9 @@
      * @param newValue the new value
      */
     public final void set(long newValue) {
-        value = newValue;
+        // Use putLongVolatile instead of ordinary volatile store when
+        // using compareAndSwapLong, for sake of some 32bit systems.
+        U.putLongVolatile(this, VALUE, newValue);
     }
 
     /**
@@ -91,7 +95,7 @@
      * @since 1.6
      */
     public final void lazySet(long newValue) {
-        unsafe.putOrderedLong(this, valueOffset, newValue);
+        U.putOrderedLong(this, VALUE, newValue);
     }
 
     /**
@@ -101,11 +105,7 @@
      * @return the previous value
      */
     public final long getAndSet(long newValue) {
-        while (true) {
-            long current = get();
-            if (compareAndSet(current, newValue))
-                return current;
-        }
+        return U.getAndSetLong(this, VALUE, newValue);
     }
 
     /**
@@ -114,11 +114,11 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that
+     * @return {@code true} if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(long expect, long update) {
-        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+        return U.compareAndSwapLong(this, VALUE, expect, update);
     }
 
     /**
@@ -131,10 +131,10 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public final boolean weakCompareAndSet(long expect, long update) {
-        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+        return U.compareAndSwapLong(this, VALUE, expect, update);
     }
 
     /**
@@ -143,12 +143,7 @@
      * @return the previous value
      */
     public final long getAndIncrement() {
-        while (true) {
-            long current = get();
-            long next = current + 1;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return U.getAndAddLong(this, VALUE, 1L);
     }
 
     /**
@@ -157,12 +152,7 @@
      * @return the previous value
      */
     public final long getAndDecrement() {
-        while (true) {
-            long current = get();
-            long next = current - 1;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return U.getAndAddLong(this, VALUE, -1L);
     }
 
     /**
@@ -172,12 +162,7 @@
      * @return the previous value
      */
     public final long getAndAdd(long delta) {
-        while (true) {
-            long current = get();
-            long next = current + delta;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return U.getAndAddLong(this, VALUE, delta);
     }
 
     /**
@@ -186,12 +171,7 @@
      * @return the updated value
      */
     public final long incrementAndGet() {
-        for (;;) {
-            long current = get();
-            long next = current + 1;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return U.getAndAddLong(this, VALUE, 1L) + 1L;
     }
 
     /**
@@ -200,12 +180,7 @@
      * @return the updated value
      */
     public final long decrementAndGet() {
-        for (;;) {
-            long current = get();
-            long next = current - 1;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return U.getAndAddLong(this, VALUE, -1L) - 1L;
     }
 
     /**
@@ -215,12 +190,93 @@
      * @return the updated value
      */
     public final long addAndGet(long delta) {
-        for (;;) {
-            long current = get();
-            long next = current + delta;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return U.getAndAddLong(this, VALUE, delta) + delta;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function, returning the previous value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param updateFunction a side-effect-free function
+     * @return the previous value
+     * @since 1.8
+     */
+    public final long getAndUpdate(LongUnaryOperator updateFunction) {
+        long prev, next;
+        do {
+            prev = get();
+            next = updateFunction.applyAsLong(prev);
+        } while (!compareAndSet(prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function, returning the updated value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param updateFunction a side-effect-free function
+     * @return the updated value
+     * @since 1.8
+     */
+    public final long updateAndGet(LongUnaryOperator updateFunction) {
+        long prev, next;
+        do {
+            prev = get();
+            next = updateFunction.applyAsLong(prev);
+        } while (!compareAndSet(prev, next));
+        return next;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function to the current and given values,
+     * returning the previous value. The function should be
+     * side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function
+     * is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the previous value
+     * @since 1.8
+     */
+    public final long getAndAccumulate(long x,
+                                       LongBinaryOperator accumulatorFunction) {
+        long prev, next;
+        do {
+            prev = get();
+            next = accumulatorFunction.applyAsLong(prev, x);
+        } while (!compareAndSet(prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function to the current and given values,
+     * returning the updated value. The function should be
+     * side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function
+     * is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the updated value
+     * @since 1.8
+     */
+    public final long accumulateAndGet(long x,
+                                       LongBinaryOperator accumulatorFunction) {
+        long prev, next;
+        do {
+            prev = get();
+            next = accumulatorFunction.applyAsLong(prev, x);
+        } while (!compareAndSet(prev, next));
+        return next;
     }
 
     /**
@@ -234,6 +290,7 @@
     /**
      * Returns the value of this {@code AtomicLong} as an {@code int}
      * after a narrowing primitive conversion.
+     * @jls 5.1.3 Narrowing Primitive Conversions
      */
     public int intValue() {
         return (int)get();
@@ -241,6 +298,7 @@
 
     /**
      * Returns the value of this {@code AtomicLong} as a {@code long}.
+     * Equivalent to {@link #get()}.
      */
     public long longValue() {
         return get();
@@ -249,6 +307,7 @@
     /**
      * Returns the value of this {@code AtomicLong} as a {@code float}
      * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
      */
     public float floatValue() {
         return (float)get();
@@ -257,6 +316,7 @@
     /**
      * Returns the value of this {@code AtomicLong} as a {@code double}
      * after a widening primitive conversion.
+     * @jls 5.1.2 Widening Primitive Conversions
      */
     public double doubleValue() {
         return (double)get();
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
index b7f3d1e..8da1501 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
@@ -6,7 +6,8 @@
 
 package java.util.concurrent.atomic;
 
-import sun.misc.Unsafe;
+import java.util.function.LongBinaryOperator;
+import java.util.function.LongUnaryOperator;
 
 /**
  * A {@code long} array in which elements may be updated atomically.
@@ -18,16 +19,17 @@
 public class AtomicLongArray implements java.io.Serializable {
     private static final long serialVersionUID = -2308431214976778248L;
 
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final int base = unsafe.arrayBaseOffset(long[].class);
-    private static final int shift;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final int ABASE;
+    private static final int ASHIFT;
     private final long[] array;
 
     static {
-        int scale = unsafe.arrayIndexScale(long[].class);
+        ABASE = U.arrayBaseOffset(long[].class);
+        int scale = U.arrayIndexScale(long[].class);
         if ((scale & (scale - 1)) != 0)
-            throw new Error("data type scale not a power of two");
-        shift = 31 - Integer.numberOfLeadingZeros(scale);
+            throw new Error("array index scale not a power of two");
+        ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
     }
 
     private long checkedByteOffset(int i) {
@@ -38,7 +40,7 @@
     }
 
     private static long byteOffset(int i) {
-        return ((long) i << shift) + base;
+        return ((long) i << ASHIFT) + ABASE;
     }
 
     /**
@@ -83,7 +85,7 @@
     }
 
     private long getRaw(long offset) {
-        return unsafe.getLongVolatile(array, offset);
+        return U.getLongVolatile(array, offset);
     }
 
     /**
@@ -93,7 +95,7 @@
      * @param newValue the new value
      */
     public final void set(int i, long newValue) {
-        unsafe.putLongVolatile(array, checkedByteOffset(i), newValue);
+        U.putLongVolatile(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -104,7 +106,7 @@
      * @since 1.6
      */
     public final void lazySet(int i, long newValue) {
-        unsafe.putOrderedLong(array, checkedByteOffset(i), newValue);
+        U.putOrderedLong(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -116,12 +118,7 @@
      * @return the previous value
      */
     public final long getAndSet(int i, long newValue) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            long current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, newValue))
-                return current;
-        }
+        return U.getAndSetLong(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -131,7 +128,7 @@
      * @param i the index
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that
+     * @return {@code true} if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int i, long expect, long update) {
@@ -139,7 +136,7 @@
     }
 
     private boolean compareAndSetRaw(long offset, long expect, long update) {
-        return unsafe.compareAndSwapLong(array, offset, expect, update);
+        return U.compareAndSwapLong(array, offset, expect, update);
     }
 
     /**
@@ -153,7 +150,7 @@
      * @param i the index
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public final boolean weakCompareAndSet(int i, long expect, long update) {
         return compareAndSet(i, expect, update);
@@ -187,12 +184,7 @@
      * @return the previous value
      */
     public final long getAndAdd(int i, long delta) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            long current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, current + delta))
-                return current;
-        }
+        return U.getAndAddLong(array, checkedByteOffset(i), delta);
     }
 
     /**
@@ -202,7 +194,7 @@
      * @return the updated value
      */
     public final long incrementAndGet(int i) {
-        return addAndGet(i, 1);
+        return getAndAdd(i, 1) + 1;
     }
 
     /**
@@ -212,7 +204,7 @@
      * @return the updated value
      */
     public final long decrementAndGet(int i) {
-        return addAndGet(i, -1);
+        return getAndAdd(i, -1) - 1;
     }
 
     /**
@@ -223,13 +215,101 @@
      * @return the updated value
      */
     public long addAndGet(int i, long delta) {
+        return getAndAdd(i, delta) + delta;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the results
+     * of applying the given function, returning the previous value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param i the index
+     * @param updateFunction a side-effect-free function
+     * @return the previous value
+     * @since 1.8
+     */
+    public final long getAndUpdate(int i, LongUnaryOperator updateFunction) {
         long offset = checkedByteOffset(i);
-        while (true) {
-            long current = getRaw(offset);
-            long next = current + delta;
-            if (compareAndSetRaw(offset, current, next))
-                return next;
-        }
+        long prev, next;
+        do {
+            prev = getRaw(offset);
+            next = updateFunction.applyAsLong(prev);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the results
+     * of applying the given function, returning the updated value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param i the index
+     * @param updateFunction a side-effect-free function
+     * @return the updated value
+     * @since 1.8
+     */
+    public final long updateAndGet(int i, LongUnaryOperator updateFunction) {
+        long offset = checkedByteOffset(i);
+        long prev, next;
+        do {
+            prev = getRaw(offset);
+            next = updateFunction.applyAsLong(prev);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return next;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the
+     * results of applying the given function to the current and
+     * given values, returning the previous value. The function should
+     * be side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function is
+     * applied with the current value at index {@code i} as its first
+     * argument, and the given update as the second argument.
+     *
+     * @param i the index
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the previous value
+     * @since 1.8
+     */
+    public final long getAndAccumulate(int i, long x,
+                                      LongBinaryOperator accumulatorFunction) {
+        long offset = checkedByteOffset(i);
+        long prev, next;
+        do {
+            prev = getRaw(offset);
+            next = accumulatorFunction.applyAsLong(prev, x);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the
+     * results of applying the given function to the current and
+     * given values, returning the updated value. The function should
+     * be side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function is
+     * applied with the current value at index {@code i} as its first
+     * argument, and the given update as the second argument.
+     *
+     * @param i the index
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the updated value
+     * @since 1.8
+     */
+    public final long accumulateAndGet(int i, long x,
+                                      LongBinaryOperator accumulatorFunction) {
+        long offset = checkedByteOffset(i);
+        long prev, next;
+        do {
+            prev = getRaw(offset);
+            next = accumulatorFunction.applyAsLong(prev, x);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return next;
     }
 
     /**
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
index 65bd452..c1a02b5 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
@@ -7,9 +7,15 @@
 package java.util.concurrent.atomic;
 
 import dalvik.system.VMStack; // android-added
-import sun.misc.Unsafe;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.function.LongBinaryOperator;
+import java.util.function.LongUnaryOperator;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 
 /**
  * A reflection-based utility that enables atomic updates to
@@ -46,11 +52,14 @@
      * or the field is inaccessible to the caller according to Java language
      * access control
      */
-    public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
+    @CallerSensitive
+    public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,
+                                                           String fieldName) {
+      Class<?> caller = VMStack.getStackClass1(); // android-changed
         if (AtomicLong.VM_SUPPORTS_LONG_CAS)
-            return new CASUpdater<U>(tclass, fieldName);
+            return new CASUpdater<U>(tclass, fieldName, caller);
         else
-            return new LockedUpdater<U>(tclass, fieldName);
+            return new LockedUpdater<U>(tclass, fieldName, caller);
     }
 
     /**
@@ -69,7 +78,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor
      */
@@ -89,7 +98,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor
      */
@@ -133,11 +142,11 @@
      * @return the previous value
      */
     public long getAndSet(T obj, long newValue) {
-        for (;;) {
-            long current = get(obj);
-            if (compareAndSet(obj, current, newValue))
-                return current;
-        }
+        long prev;
+        do {
+            prev = get(obj);
+        } while (!compareAndSet(obj, prev, newValue));
+        return prev;
     }
 
     /**
@@ -148,12 +157,12 @@
      * @return the previous value
      */
     public long getAndIncrement(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + 1;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -164,12 +173,12 @@
      * @return the previous value
      */
     public long getAndDecrement(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current - 1;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -181,12 +190,12 @@
      * @return the previous value
      */
     public long getAndAdd(T obj, long delta) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + delta;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -197,12 +206,12 @@
      * @return the updated value
      */
     public long incrementAndGet(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + 1;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
@@ -213,12 +222,12 @@
      * @return the updated value
      */
     public long decrementAndGet(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current - 1;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
@@ -230,27 +239,121 @@
      * @return the updated value
      */
     public long addAndGet(T obj, long delta) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + delta;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
-    private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
-        private static final Unsafe unsafe = Unsafe.getUnsafe();
-        private final long offset;
-        private final Class<T> tclass;
-        private final Class<?> cclass;
+    /**
+     * Atomically updates the field of the given object managed by this updater
+     * with the results of applying the given function, returning the previous
+     * value. The function should be side-effect-free, since it may be
+     * re-applied when attempted updates fail due to contention among threads.
+     *
+     * @param obj An object whose field to get and set
+     * @param updateFunction a side-effect-free function
+     * @return the previous value
+     * @since 1.8
+     */
+    public final long getAndUpdate(T obj, LongUnaryOperator updateFunction) {
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = updateFunction.applyAsLong(prev);
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
+    }
 
-        CASUpdater(final Class<T> tclass, final String fieldName) {
+    /**
+     * Atomically updates the field of the given object managed by this updater
+     * with the results of applying the given function, returning the updated
+     * value. The function should be side-effect-free, since it may be
+     * re-applied when attempted updates fail due to contention among threads.
+     *
+     * @param obj An object whose field to get and set
+     * @param updateFunction a side-effect-free function
+     * @return the updated value
+     * @since 1.8
+     */
+    public final long updateAndGet(T obj, LongUnaryOperator updateFunction) {
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = updateFunction.applyAsLong(prev);
+        } while (!compareAndSet(obj, prev, next));
+        return next;
+    }
+
+    /**
+     * Atomically updates the field of the given object managed by this
+     * updater with the results of applying the given function to the
+     * current and given values, returning the previous value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.  The
+     * function is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param obj An object whose field to get and set
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the previous value
+     * @since 1.8
+     */
+    public final long getAndAccumulate(T obj, long x,
+                                       LongBinaryOperator accumulatorFunction) {
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = accumulatorFunction.applyAsLong(prev, x);
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the field of the given object managed by this
+     * updater with the results of applying the given function to the
+     * current and given values, returning the updated value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.  The
+     * function is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param obj An object whose field to get and set
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the updated value
+     * @since 1.8
+     */
+    public final long accumulateAndGet(T obj, long x,
+                                       LongBinaryOperator accumulatorFunction) {
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = accumulatorFunction.applyAsLong(prev, x);
+        } while (!compareAndSet(obj, prev, next));
+        return next;
+    }
+
+    private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private final long offset;
+        /**
+         * if field is protected, the subclass constructing updater, else
+         * the same as tclass
+         */
+        private final Class<?> cclass;
+        /** class holding the field */
+        private final Class<T> tclass;
+
+        CASUpdater(final Class<T> tclass, final String fieldName,
+                   final Class<?> caller) {
             final Field field;
-            final Class<?> caller;
             final int modifiers;
             try {
                 field = tclass.getDeclaredField(fieldName); // android-changed
-                caller = VMStack.getStackClass2(); // android-changed
                 modifiers = field.getModifiers();
                 // BEGIN android-removed
                 // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
@@ -259,101 +362,7 @@
                 // ClassLoader ccl = caller.getClassLoader();
                 // if ((ccl != null) && (ccl != cl) &&
                 //     ((cl == null) || !isAncestor(cl, ccl))) {
-                //   sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
-                // }
-                // END android-removed
-            // BEGIN android-removed
-            // } catch (PrivilegedActionException pae) {
-            //    throw new RuntimeException(pae.getException());
-            // END android-removed
-            } catch (Exception ex) {
-                throw new RuntimeException(ex);
-            }
-
-            Class<?> fieldt = field.getType();
-            if (fieldt != long.class)
-                throw new IllegalArgumentException("Must be long type");
-
-            if (!Modifier.isVolatile(modifiers))
-                throw new IllegalArgumentException("Must be volatile type");
-
-            this.cclass = (Modifier.isProtected(modifiers) &&
-                           caller != tclass) ? caller : null;
-            this.tclass = tclass;
-            offset = unsafe.objectFieldOffset(field);
-        }
-
-        private void fullCheck(T obj) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
-            if (cclass != null)
-                ensureProtectedAccess(obj);
-        }
-
-        public boolean compareAndSet(T obj, long expect, long update) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            return unsafe.compareAndSwapLong(obj, offset, expect, update);
-        }
-
-        public boolean weakCompareAndSet(T obj, long expect, long update) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            return unsafe.compareAndSwapLong(obj, offset, expect, update);
-        }
-
-        public void set(T obj, long newValue) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            unsafe.putLongVolatile(obj, offset, newValue);
-        }
-
-        public void lazySet(T obj, long newValue) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            unsafe.putOrderedLong(obj, offset, newValue);
-        }
-
-        public long get(T obj) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
-            return unsafe.getLongVolatile(obj, offset);
-        }
-
-        private void ensureProtectedAccess(T obj) {
-            if (cclass.isInstance(obj)) {
-                return;
-            }
-            throw new RuntimeException(
-                new IllegalAccessException("Class " +
-                    cclass.getName() +
-                    " can not access a protected member of class " +
-                    tclass.getName() +
-                    " using an instance of " +
-                    obj.getClass().getName()
-                )
-            );
-        }
-    }
-
-
-    private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
-        private static final Unsafe unsafe = Unsafe.getUnsafe();
-        private final long offset;
-        private final Class<T> tclass;
-        private final Class<?> cclass;
-
-        LockedUpdater(final Class<T> tclass, final String fieldName) {
-            Field field = null;
-            Class<?> caller = null;
-            int modifiers = 0;
-            try {
-                field = tclass.getDeclaredField(fieldName); // android-changed
-                caller = VMStack.getStackClass2(); // android-changed
-                modifiers = field.getModifiers();
-                // BEGIN android-removed
-                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
-                //     caller, tclass, null, modifiers);
-                // ClassLoader cl = tclass.getClassLoader();
-                // ClassLoader ccl = caller.getClassLoader();
-                // if ((ccl != null) && (ccl != cl) &&
-                //     ((cl == null) || !isAncestor(cl, ccl))) {
-                //   sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
                 // }
                 // END android-removed
             // BEGIN android-removed
@@ -364,73 +373,206 @@
                 throw new RuntimeException(ex);
             }
 
-            Class<?> fieldt = field.getType();
-            if (fieldt != long.class)
+            if (field.getType() != long.class)
                 throw new IllegalArgumentException("Must be long type");
 
             if (!Modifier.isVolatile(modifiers))
                 throw new IllegalArgumentException("Must be volatile type");
 
-            this.cclass = (Modifier.isProtected(modifiers) &&
-                           caller != tclass) ? caller : null;
+            this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
             this.tclass = tclass;
-            offset = unsafe.objectFieldOffset(field);
+            this.offset = U.objectFieldOffset(field);
         }
 
-        private void fullCheck(T obj) {
-            if (!tclass.isInstance(obj))
+        /**
+         * Checks that target argument is instance of cclass.  On
+         * failure, throws cause.
+         */
+        private final void accessCheck(T obj) {
+            if (!cclass.isInstance(obj))
+                throwAccessCheckException(obj);
+        }
+
+        /**
+         * Throws access exception if accessCheck failed due to
+         * protected access, else ClassCastException.
+         */
+        private final void throwAccessCheckException(T obj) {
+            if (cclass == tclass)
                 throw new ClassCastException();
-            if (cclass != null)
-                ensureProtectedAccess(obj);
+            else
+                throw new RuntimeException(
+                    new IllegalAccessException(
+                        "Class " +
+                        cclass.getName() +
+                        " can not access a protected member of class " +
+                        tclass.getName() +
+                        " using an instance of " +
+                        obj.getClass().getName()));
         }
 
-        public boolean compareAndSet(T obj, long expect, long update) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+        public final boolean compareAndSet(T obj, long expect, long update) {
+            accessCheck(obj);
+            return U.compareAndSwapLong(obj, offset, expect, update);
+        }
+
+        public final boolean weakCompareAndSet(T obj, long expect, long update) {
+            accessCheck(obj);
+            return U.compareAndSwapLong(obj, offset, expect, update);
+        }
+
+        public final void set(T obj, long newValue) {
+            accessCheck(obj);
+            U.putLongVolatile(obj, offset, newValue);
+        }
+
+        public final void lazySet(T obj, long newValue) {
+            accessCheck(obj);
+            U.putOrderedLong(obj, offset, newValue);
+        }
+
+        public final long get(T obj) {
+            accessCheck(obj);
+            return U.getLongVolatile(obj, offset);
+        }
+
+        public final long getAndSet(T obj, long newValue) {
+            accessCheck(obj);
+            return U.getAndSetLong(obj, offset, newValue);
+        }
+
+        public final long getAndAdd(T obj, long delta) {
+            accessCheck(obj);
+            return U.getAndAddLong(obj, offset, delta);
+        }
+
+        public final long getAndIncrement(T obj) {
+            return getAndAdd(obj, 1);
+        }
+
+        public final long getAndDecrement(T obj) {
+            return getAndAdd(obj, -1);
+        }
+
+        public final long incrementAndGet(T obj) {
+            return getAndAdd(obj, 1) + 1;
+        }
+
+        public final long decrementAndGet(T obj) {
+            return getAndAdd(obj, -1) - 1;
+        }
+
+        public final long addAndGet(T obj, long delta) {
+            return getAndAdd(obj, delta) + delta;
+        }
+    }
+
+    private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private final long offset;
+        /**
+         * if field is protected, the subclass constructing updater, else
+         * the same as tclass
+         */
+        private final Class<?> cclass;
+        /** class holding the field */
+        private final Class<T> tclass;
+
+        LockedUpdater(final Class<T> tclass, final String fieldName,
+                      final Class<?> caller) {
+            Field field = null;
+            int modifiers = 0;
+            try {
+                field = tclass.getDeclaredField(fieldName); // android-changed
+                modifiers = field.getModifiers();
+                // BEGIN android-removed
+                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                //     caller, tclass, null, modifiers);
+                // ClassLoader cl = tclass.getClassLoader();
+                // ClassLoader ccl = caller.getClassLoader();
+                // if ((ccl != null) && (ccl != cl) &&
+                //     ((cl == null) || !isAncestor(cl, ccl))) {
+                //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                // }
+                // END android-removed
+            // BEGIN android-removed
+            // } catch (PrivilegedActionException pae) {
+            //     throw new RuntimeException(pae.getException());
+            // END android-removed
+            } catch (Exception ex) {
+                throw new RuntimeException(ex);
+            }
+
+            if (field.getType() != long.class)
+                throw new IllegalArgumentException("Must be long type");
+
+            if (!Modifier.isVolatile(modifiers))
+                throw new IllegalArgumentException("Must be volatile type");
+
+            this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
+            this.tclass = tclass;
+            this.offset = U.objectFieldOffset(field);
+        }
+
+        /**
+         * Checks that target argument is instance of cclass.  On
+         * failure, throws cause.
+         */
+        private final void accessCheck(T obj) {
+            if (!cclass.isInstance(obj))
+                throw accessCheckException(obj);
+        }
+
+        /**
+         * Returns access exception if accessCheck failed due to
+         * protected access, else ClassCastException.
+         */
+        private final RuntimeException accessCheckException(T obj) {
+            if (cclass == tclass)
+                return new ClassCastException();
+            else
+                return new RuntimeException(
+                    new IllegalAccessException(
+                        "Class " +
+                        cclass.getName() +
+                        " can not access a protected member of class " +
+                        tclass.getName() +
+                        " using an instance of " +
+                        obj.getClass().getName()));
+        }
+
+        public final boolean compareAndSet(T obj, long expect, long update) {
+            accessCheck(obj);
             synchronized (this) {
-                long v = unsafe.getLong(obj, offset);
+                long v = U.getLong(obj, offset);
                 if (v != expect)
                     return false;
-                unsafe.putLong(obj, offset, update);
+                U.putLong(obj, offset, update);
                 return true;
             }
         }
 
-        public boolean weakCompareAndSet(T obj, long expect, long update) {
+        public final boolean weakCompareAndSet(T obj, long expect, long update) {
             return compareAndSet(obj, expect, update);
         }
 
-        public void set(T obj, long newValue) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+        public final void set(T obj, long newValue) {
+            accessCheck(obj);
             synchronized (this) {
-                unsafe.putLong(obj, offset, newValue);
+                U.putLong(obj, offset, newValue);
             }
         }
 
-        public void lazySet(T obj, long newValue) {
+        public final void lazySet(T obj, long newValue) {
             set(obj, newValue);
         }
 
-        public long get(T obj) {
-            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+        public final long get(T obj) {
+            accessCheck(obj);
             synchronized (this) {
-                return unsafe.getLong(obj, offset);
+                return U.getLong(obj, offset);
             }
         }
-
-        private void ensureProtectedAccess(T obj) {
-            if (cclass.isInstance(obj)) {
-                return;
-            }
-            throw new RuntimeException(
-                new IllegalAccessException("Class " +
-                    cclass.getName() +
-                    " can not access a protected member of class " +
-                    tclass.getName() +
-                    " using an instance of " +
-                    obj.getClass().getName()
-                )
-            );
-        }
     }
 
     // BEGIN android-removed
@@ -439,13 +581,13 @@
     //  * classloader's delegation chain.
     //  * Equivalent to the inaccessible: first.isAncestor(second).
     //  */
-    // private static boolean isAncestor(ClassLoader first, ClassLoader second) {
+    // static boolean isAncestor(ClassLoader first, ClassLoader second) {
     //     ClassLoader acl = first;
     //     do {
     //         acl = acl.getParent();
     //         if (second == acl) {
     //             return true;
-    //        }
+    //         }
     //     } while (acl != null);
     //     return false;
     // }
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
index 18d148f..d11be10 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
@@ -91,7 +91,7 @@
      * @param newReference the new value for the reference
      * @param expectedMark the expected value of the mark
      * @param newMark the new value for the mark
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public boolean weakCompareAndSet(V       expectedReference,
                                      V       newReference,
@@ -111,7 +111,7 @@
      * @param newReference the new value for the reference
      * @param expectedMark the expected value of the mark
      * @param newMark the new value for the mark
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public boolean compareAndSet(V       expectedReference,
                                  V       newReference,
@@ -149,7 +149,7 @@
      *
      * @param expectedReference the expected value of the reference
      * @param newMark the new value for the mark
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public boolean attemptMark(V expectedReference, boolean newMark) {
         Pair<V> current = pair;
@@ -161,23 +161,18 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
-    private static final long pairOffset =
-        objectFieldOffset(UNSAFE, "pair", AtomicMarkableReference.class);
-
-    private boolean casPair(Pair<V> cmp, Pair<V> val) {
-        return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long PAIR;
+    static {
+        try {
+            PAIR = U.objectFieldOffset
+                (AtomicMarkableReference.class.getDeclaredField("pair"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
     }
 
-    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
-                                  String field, Class<?> klazz) {
-        try {
-            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
-        } catch (NoSuchFieldException e) {
-            // Convert Exception to corresponding Error
-            NoSuchFieldError error = new NoSuchFieldError(field);
-            error.initCause(e);
-            throw error;
-        }
+    private boolean casPair(Pair<V> cmp, Pair<V> val) {
+        return U.compareAndSwapObject(this, PAIR, cmp, val);
     }
 }
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicReference.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicReference.java
index 7ea6066..c3a5ede 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicReference.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicReference.java
@@ -6,7 +6,8 @@
 
 package java.util.concurrent.atomic;
 
-import sun.misc.Unsafe;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
 
 /**
  * An object reference that may be updated atomically. See the {@link
@@ -19,14 +20,16 @@
 public class AtomicReference<V> implements java.io.Serializable {
     private static final long serialVersionUID = -1848883965231344442L;
 
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final long valueOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long VALUE;
 
     static {
         try {
-            valueOffset = unsafe.objectFieldOffset
+            VALUE = U.objectFieldOffset
                 (AtomicReference.class.getDeclaredField("value"));
-        } catch (Exception ex) { throw new Error(ex); }
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
     }
 
     private volatile V value;
@@ -71,7 +74,7 @@
      * @since 1.6
      */
     public final void lazySet(V newValue) {
-        unsafe.putOrderedObject(this, valueOffset, newValue);
+        U.putOrderedObject(this, VALUE, newValue);
     }
 
     /**
@@ -79,11 +82,11 @@
      * if the current value {@code ==} the expected value.
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that
+     * @return {@code true} if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(V expect, V update) {
-        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
+        return U.compareAndSwapObject(this, VALUE, expect, update);
     }
 
     /**
@@ -96,10 +99,10 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public final boolean weakCompareAndSet(V expect, V update) {
-        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
+        return U.compareAndSwapObject(this, VALUE, expect, update);
     }
 
     /**
@@ -108,12 +111,95 @@
      * @param newValue the new value
      * @return the previous value
      */
+    @SuppressWarnings("unchecked")
     public final V getAndSet(V newValue) {
-        while (true) {
-            V x = get();
-            if (compareAndSet(x, newValue))
-                return x;
-        }
+        return (V)U.getAndSetObject(this, VALUE, newValue);
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function, returning the previous value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param updateFunction a side-effect-free function
+     * @return the previous value
+     * @since 1.8
+     */
+    public final V getAndUpdate(UnaryOperator<V> updateFunction) {
+        V prev, next;
+        do {
+            prev = get();
+            next = updateFunction.apply(prev);
+        } while (!compareAndSet(prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function, returning the updated value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param updateFunction a side-effect-free function
+     * @return the updated value
+     * @since 1.8
+     */
+    public final V updateAndGet(UnaryOperator<V> updateFunction) {
+        V prev, next;
+        do {
+            prev = get();
+            next = updateFunction.apply(prev);
+        } while (!compareAndSet(prev, next));
+        return next;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function to the current and given values,
+     * returning the previous value. The function should be
+     * side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function
+     * is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the previous value
+     * @since 1.8
+     */
+    public final V getAndAccumulate(V x,
+                                    BinaryOperator<V> accumulatorFunction) {
+        V prev, next;
+        do {
+            prev = get();
+            next = accumulatorFunction.apply(prev, x);
+        } while (!compareAndSet(prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the current value with the results of
+     * applying the given function to the current and given values,
+     * returning the updated value. The function should be
+     * side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function
+     * is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the updated value
+     * @since 1.8
+     */
+    public final V accumulateAndGet(V x,
+                                    BinaryOperator<V> accumulatorFunction) {
+        V prev, next;
+        do {
+            prev = get();
+            next = accumulatorFunction.apply(prev, x);
+        } while (!compareAndSet(prev, next));
+        return next;
     }
 
     /**
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
index 052b839..f5596e8 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
@@ -6,9 +6,10 @@
 
 package java.util.concurrent.atomic;
 
-import java.util.Arrays;
 import java.lang.reflect.Array;
-import sun.misc.Unsafe;
+import java.util.Arrays;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
 
 /**
  * An array of object references in which elements may be updated
@@ -22,23 +23,22 @@
 public class AtomicReferenceArray<E> implements java.io.Serializable {
     private static final long serialVersionUID = -6209656149925076980L;
 
-    private static final Unsafe unsafe;
-    private static final int base;
-    private static final int shift;
-    private static final long arrayFieldOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long ARRAY;
+    private static final int ABASE;
+    private static final int ASHIFT;
     private final Object[] array; // must have exact type Object[]
 
     static {
         try {
-            unsafe = Unsafe.getUnsafe();
-            arrayFieldOffset = unsafe.objectFieldOffset
+            ARRAY = U.objectFieldOffset
                 (AtomicReferenceArray.class.getDeclaredField("array"));
-            base = unsafe.arrayBaseOffset(Object[].class);
-            int scale = unsafe.arrayIndexScale(Object[].class);
+            ABASE = U.arrayBaseOffset(Object[].class);
+            int scale = U.arrayIndexScale(Object[].class);
             if ((scale & (scale - 1)) != 0)
-                throw new Error("data type scale not a power of two");
-            shift = 31 - Integer.numberOfLeadingZeros(scale);
-        } catch (Exception e) {
+                throw new Error("array index scale not a power of two");
+            ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
     }
@@ -51,7 +51,7 @@
     }
 
     private static long byteOffset(int i) {
-        return ((long) i << shift) + base;
+        return ((long) i << ASHIFT) + ABASE;
     }
 
     /**
@@ -97,7 +97,7 @@
 
     @SuppressWarnings("unchecked")
     private E getRaw(long offset) {
-        return (E) unsafe.getObjectVolatile(array, offset);
+        return (E) U.getObjectVolatile(array, offset);
     }
 
     /**
@@ -107,7 +107,7 @@
      * @param newValue the new value
      */
     public final void set(int i, E newValue) {
-        unsafe.putObjectVolatile(array, checkedByteOffset(i), newValue);
+        U.putObjectVolatile(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -118,7 +118,7 @@
      * @since 1.6
      */
     public final void lazySet(int i, E newValue) {
-        unsafe.putOrderedObject(array, checkedByteOffset(i), newValue);
+        U.putOrderedObject(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -129,13 +129,9 @@
      * @param newValue the new value
      * @return the previous value
      */
+    @SuppressWarnings("unchecked")
     public final E getAndSet(int i, E newValue) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            E current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, newValue))
-                return current;
-        }
+        return (E)U.getAndSetObject(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -145,7 +141,7 @@
      * @param i the index
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that
+     * @return {@code true} if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int i, E expect, E update) {
@@ -153,7 +149,7 @@
     }
 
     private boolean compareAndSetRaw(long offset, E expect, E update) {
-        return unsafe.compareAndSwapObject(array, offset, expect, update);
+        return U.compareAndSwapObject(array, offset, expect, update);
     }
 
     /**
@@ -167,13 +163,107 @@
      * @param i the index
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public final boolean weakCompareAndSet(int i, E expect, E update) {
         return compareAndSet(i, expect, update);
     }
 
     /**
+     * Atomically updates the element at index {@code i} with the results
+     * of applying the given function, returning the previous value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param i the index
+     * @param updateFunction a side-effect-free function
+     * @return the previous value
+     * @since 1.8
+     */
+    public final E getAndUpdate(int i, UnaryOperator<E> updateFunction) {
+        long offset = checkedByteOffset(i);
+        E prev, next;
+        do {
+            prev = getRaw(offset);
+            next = updateFunction.apply(prev);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the results
+     * of applying the given function, returning the updated value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.
+     *
+     * @param i the index
+     * @param updateFunction a side-effect-free function
+     * @return the updated value
+     * @since 1.8
+     */
+    public final E updateAndGet(int i, UnaryOperator<E> updateFunction) {
+        long offset = checkedByteOffset(i);
+        E prev, next;
+        do {
+            prev = getRaw(offset);
+            next = updateFunction.apply(prev);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return next;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the
+     * results of applying the given function to the current and
+     * given values, returning the previous value. The function should
+     * be side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function is
+     * applied with the current value at index {@code i} as its first
+     * argument, and the given update as the second argument.
+     *
+     * @param i the index
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the previous value
+     * @since 1.8
+     */
+    public final E getAndAccumulate(int i, E x,
+                                    BinaryOperator<E> accumulatorFunction) {
+        long offset = checkedByteOffset(i);
+        E prev, next;
+        do {
+            prev = getRaw(offset);
+            next = accumulatorFunction.apply(prev, x);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the element at index {@code i} with the
+     * results of applying the given function to the current and
+     * given values, returning the updated value. The function should
+     * be side-effect-free, since it may be re-applied when attempted
+     * updates fail due to contention among threads.  The function is
+     * applied with the current value at index {@code i} as its first
+     * argument, and the given update as the second argument.
+     *
+     * @param i the index
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the updated value
+     * @since 1.8
+     */
+    public final E accumulateAndGet(int i, E x,
+                                    BinaryOperator<E> accumulatorFunction) {
+        long offset = checkedByteOffset(i);
+        E prev, next;
+        do {
+            prev = getRaw(offset);
+            next = accumulatorFunction.apply(prev, x);
+        } while (!compareAndSetRaw(offset, prev, next));
+        return next;
+    }
+
+    /**
      * Returns the String representation of the current values of array.
      * @return the String representation of the current values of array
      */
@@ -194,17 +284,20 @@
 
     /**
      * Reconstitutes the instance from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
-        throws java.io.IOException, ClassNotFoundException,
-        java.io.InvalidObjectException {
+        throws java.io.IOException, ClassNotFoundException {
         // Note: This must be changed if any additional fields are defined
         Object a = s.readFields().get("array", null);
         if (a == null || !a.getClass().isArray())
             throw new java.io.InvalidObjectException("Not array type");
         if (a.getClass() != Object[].class)
             a = Arrays.copyOf((Object[])a, Array.getLength(a), Object[].class);
-        unsafe.putObjectVolatile(this, arrayFieldOffset, a);
+        U.putObjectVolatile(this, ARRAY, a);
     }
 
 }
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
index 13ad3eb..1dc2eb9 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
@@ -7,9 +7,15 @@
 package java.util.concurrent.atomic;
 
 import dalvik.system.VMStack; // android-added
-import sun.misc.Unsafe;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 
 /**
  * A reflection-based utility that enables atomic updates to
@@ -19,7 +25,7 @@
  * independently subject to atomic updates. For example, a tree node
  * might be declared as
  *
- *  <pre> {@code
+ * <pre> {@code
  * class Node {
  *   private volatile Node left, right;
  *
@@ -60,17 +66,19 @@
      * @param <U> the type of instances of tclass
      * @param <W> the type of instances of vclass
      * @return the updater
-     * @throws IllegalArgumentException if the field is not a volatile reference type
+     * @throws ClassCastException if the field is of the wrong type
+     * @throws IllegalArgumentException if the field is not volatile
      * @throws RuntimeException with a nested reflection-based
      * exception if the class does not hold field or is the wrong type,
      * or the field is inaccessible to the caller according to Java language
      * access control
      */
+    @CallerSensitive
     public static <U,W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass,
                                                                     Class<W> vclass,
                                                                     String fieldName) {
         return new AtomicReferenceFieldUpdaterImpl<U,W>
-            (tclass, vclass, fieldName);
+            (tclass, vclass, fieldName, VMStack.getStackClass1()); // android-changed
     }
 
     /**
@@ -89,7 +97,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public abstract boolean compareAndSet(T obj, V expect, V update);
 
@@ -107,7 +115,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public abstract boolean weakCompareAndSet(T obj, V expect, V update);
 
@@ -149,20 +157,116 @@
      * @return the previous value
      */
     public V getAndSet(T obj, V newValue) {
-        for (;;) {
-            V current = get(obj);
-            if (compareAndSet(obj, current, newValue))
-                return current;
-        }
+        V prev;
+        do {
+            prev = get(obj);
+        } while (!compareAndSet(obj, prev, newValue));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the field of the given object managed by this updater
+     * with the results of applying the given function, returning the previous
+     * value. The function should be side-effect-free, since it may be
+     * re-applied when attempted updates fail due to contention among threads.
+     *
+     * @param obj An object whose field to get and set
+     * @param updateFunction a side-effect-free function
+     * @return the previous value
+     * @since 1.8
+     */
+    public final V getAndUpdate(T obj, UnaryOperator<V> updateFunction) {
+        V prev, next;
+        do {
+            prev = get(obj);
+            next = updateFunction.apply(prev);
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the field of the given object managed by this updater
+     * with the results of applying the given function, returning the updated
+     * value. The function should be side-effect-free, since it may be
+     * re-applied when attempted updates fail due to contention among threads.
+     *
+     * @param obj An object whose field to get and set
+     * @param updateFunction a side-effect-free function
+     * @return the updated value
+     * @since 1.8
+     */
+    public final V updateAndGet(T obj, UnaryOperator<V> updateFunction) {
+        V prev, next;
+        do {
+            prev = get(obj);
+            next = updateFunction.apply(prev);
+        } while (!compareAndSet(obj, prev, next));
+        return next;
+    }
+
+    /**
+     * Atomically updates the field of the given object managed by this
+     * updater with the results of applying the given function to the
+     * current and given values, returning the previous value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.  The
+     * function is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param obj An object whose field to get and set
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the previous value
+     * @since 1.8
+     */
+    public final V getAndAccumulate(T obj, V x,
+                                    BinaryOperator<V> accumulatorFunction) {
+        V prev, next;
+        do {
+            prev = get(obj);
+            next = accumulatorFunction.apply(prev, x);
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
+    }
+
+    /**
+     * Atomically updates the field of the given object managed by this
+     * updater with the results of applying the given function to the
+     * current and given values, returning the updated value. The
+     * function should be side-effect-free, since it may be re-applied
+     * when attempted updates fail due to contention among threads.  The
+     * function is applied with the current value as its first argument,
+     * and the given update as the second argument.
+     *
+     * @param obj An object whose field to get and set
+     * @param x the update value
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @return the updated value
+     * @since 1.8
+     */
+    public final V accumulateAndGet(T obj, V x,
+                                    BinaryOperator<V> accumulatorFunction) {
+        V prev, next;
+        do {
+            prev = get(obj);
+            next = accumulatorFunction.apply(prev, x);
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     private static final class AtomicReferenceFieldUpdaterImpl<T,V>
         extends AtomicReferenceFieldUpdater<T,V> {
-        private static final Unsafe unsafe = Unsafe.getUnsafe();
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
         private final long offset;
-        private final Class<T> tclass;
-        private final Class<V> vclass;
+        /**
+         * if field is protected, the subclass constructing updater, else
+         * the same as tclass
+         */
         private final Class<?> cclass;
+        /** class holding the field */
+        private final Class<T> tclass;
+        /** field value type */
+        private final Class<V> vclass;
 
         /*
          * Internal type checks within all update methods contain
@@ -177,26 +281,25 @@
          */
 
         AtomicReferenceFieldUpdaterImpl(final Class<T> tclass,
-                                        Class<V> vclass,
-                                        final String fieldName) {
+                                        final Class<V> vclass,
+                                        final String fieldName,
+                                        final Class<?> caller) {
             final Field field;
             final Class<?> fieldClass;
-            final Class<?> caller;
             final int modifiers;
             try {
                 field = tclass.getDeclaredField(fieldName); // android-changed
-                caller = VMStack.getStackClass2(); // android-changed
                 modifiers = field.getModifiers();
-            // BEGIN android-removed
-            //     sun.reflect.misc.ReflectUtil.ensureMemberAccess(
-            //         caller, tclass, null, modifiers);
-            //     ClassLoader cl = tclass.getClassLoader();
-            //     ClassLoader ccl = caller.getClassLoader();
-            //     if ((ccl != null) && (ccl != cl) &&
-            //         ((cl == null) || !isAncestor(cl, ccl))) {
-            //       sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
-            //     }
-            // END android-removed
+                // BEGIN android-removed
+                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                //     caller, tclass, null, modifiers);
+                // ClassLoader cl = tclass.getClassLoader();
+                // ClassLoader ccl = caller.getClassLoader();
+                // if ((ccl != null) && (ccl != cl) &&
+                //     ((cl == null) || !isAncestor(cl, ccl))) {
+                //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                // }
+                // END android-removed
                 fieldClass = field.getType();
             // BEGIN android-removed
             // } catch (PrivilegedActionException pae) {
@@ -208,18 +311,16 @@
 
             if (vclass != fieldClass)
                 throw new ClassCastException();
+            if (vclass.isPrimitive())
+                throw new IllegalArgumentException("Must be reference type");
 
             if (!Modifier.isVolatile(modifiers))
                 throw new IllegalArgumentException("Must be volatile type");
 
-            this.cclass = (Modifier.isProtected(modifiers) &&
-                           caller != tclass) ? caller : null;
+            this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
             this.tclass = tclass;
-            if (vclass == Object.class)
-                this.vclass = null;
-            else
-                this.vclass = vclass;
-            offset = unsafe.objectFieldOffset(field);
+            this.vclass = vclass;
+            this.offset = U.objectFieldOffset(field);
         }
 
         // BEGIN android-removed
@@ -228,87 +329,90 @@
         //  * classloader's delegation chain.
         //  * Equivalent to the inaccessible: first.isAncestor(second).
         //  */
-        //
         // private static boolean isAncestor(ClassLoader first, ClassLoader second) {
         //     ClassLoader acl = first;
         //     do {
         //         acl = acl.getParent();
         //         if (second == acl) {
         //             return true;
-        //        }
+        //         }
         //     } while (acl != null);
         //     return false;
         // }
         // END android-removed
 
-        void targetCheck(T obj) {
-            if (!tclass.isInstance(obj))
+        /**
+         * Checks that target argument is instance of cclass.  On
+         * failure, throws cause.
+         */
+        private final void accessCheck(T obj) {
+            if (!cclass.isInstance(obj))
+                throwAccessCheckException(obj);
+        }
+
+        /**
+         * Throws access exception if accessCheck failed due to
+         * protected access, else ClassCastException.
+         */
+        private final void throwAccessCheckException(T obj) {
+            if (cclass == tclass)
                 throw new ClassCastException();
-            if (cclass != null)
-                ensureProtectedAccess(obj);
+            else
+                throw new RuntimeException(
+                    new IllegalAccessException(
+                        "Class " +
+                        cclass.getName() +
+                        " can not access a protected member of class " +
+                        tclass.getName() +
+                        " using an instance of " +
+                        obj.getClass().getName()));
         }
 
-        void updateCheck(T obj, V update) {
-            if (!tclass.isInstance(obj) ||
-                (update != null && vclass != null && !vclass.isInstance(update)))
-                throw new ClassCastException();
-            if (cclass != null)
-                ensureProtectedAccess(obj);
+        private final void valueCheck(V v) {
+            if (v != null && !(vclass.isInstance(v)))
+                throwCCE();
         }
 
-        public boolean compareAndSet(T obj, V expect, V update) {
-            if (obj == null || obj.getClass() != tclass || cclass != null ||
-                (update != null && vclass != null &&
-                 vclass != update.getClass()))
-                updateCheck(obj, update);
-            return unsafe.compareAndSwapObject(obj, offset, expect, update);
+        static void throwCCE() {
+            throw new ClassCastException();
         }
 
-        public boolean weakCompareAndSet(T obj, V expect, V update) {
+        public final boolean compareAndSet(T obj, V expect, V update) {
+            accessCheck(obj);
+            valueCheck(update);
+            return U.compareAndSwapObject(obj, offset, expect, update);
+        }
+
+        public final boolean weakCompareAndSet(T obj, V expect, V update) {
             // same implementation as strong form for now
-            if (obj == null || obj.getClass() != tclass || cclass != null ||
-                (update != null && vclass != null &&
-                 vclass != update.getClass()))
-                updateCheck(obj, update);
-            return unsafe.compareAndSwapObject(obj, offset, expect, update);
+            accessCheck(obj);
+            valueCheck(update);
+            return U.compareAndSwapObject(obj, offset, expect, update);
         }
 
-        public void set(T obj, V newValue) {
-            if (obj == null || obj.getClass() != tclass || cclass != null ||
-                (newValue != null && vclass != null &&
-                 vclass != newValue.getClass()))
-                updateCheck(obj, newValue);
-            unsafe.putObjectVolatile(obj, offset, newValue);
+        public final void set(T obj, V newValue) {
+            accessCheck(obj);
+            valueCheck(newValue);
+            U.putObjectVolatile(obj, offset, newValue);
         }
 
-        public void lazySet(T obj, V newValue) {
-            if (obj == null || obj.getClass() != tclass || cclass != null ||
-                (newValue != null && vclass != null &&
-                 vclass != newValue.getClass()))
-                updateCheck(obj, newValue);
-            unsafe.putOrderedObject(obj, offset, newValue);
+        public final void lazySet(T obj, V newValue) {
+            accessCheck(obj);
+            valueCheck(newValue);
+            U.putOrderedObject(obj, offset, newValue);
         }
 
         @SuppressWarnings("unchecked")
-        public V get(T obj) {
-            if (obj == null || obj.getClass() != tclass || cclass != null)
-                targetCheck(obj);
-            return (V)unsafe.getObjectVolatile(obj, offset);
+        public final V get(T obj) {
+            accessCheck(obj);
+            return (V)U.getObjectVolatile(obj, offset);
         }
 
-        private void ensureProtectedAccess(T obj) {
-            if (cclass.isInstance(obj)) {
-                return;
-            }
-            throw new RuntimeException(
-                new IllegalAccessException("Class " +
-                    cclass.getName() +
-                    " can not access a protected member of class " +
-                    tclass.getName() +
-                    " using an instance of " +
-                    obj.getClass().getName()
-                )
-            );
+        @SuppressWarnings("unchecked")
+        public final V getAndSet(T obj, V newValue) {
+            accessCheck(obj);
+            valueCheck(newValue);
+            return (V)U.getAndSetObject(obj, offset, newValue);
         }
     }
 }
diff --git a/luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java b/luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
index 1449856..69fab23 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
@@ -91,7 +91,7 @@
      * @param newReference the new value for the reference
      * @param expectedStamp the expected value of the stamp
      * @param newStamp the new value for the stamp
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public boolean weakCompareAndSet(V   expectedReference,
                                      V   newReference,
@@ -111,7 +111,7 @@
      * @param newReference the new value for the reference
      * @param expectedStamp the expected value of the stamp
      * @param newStamp the new value for the stamp
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public boolean compareAndSet(V   expectedReference,
                                  V   newReference,
@@ -149,7 +149,7 @@
      *
      * @param expectedReference the expected value of the reference
      * @param newStamp the new value for the stamp
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public boolean attemptStamp(V expectedReference, int newStamp) {
         Pair<V> current = pair;
@@ -161,23 +161,18 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
-    private static final long pairOffset =
-        objectFieldOffset(UNSAFE, "pair", AtomicStampedReference.class);
-
-    private boolean casPair(Pair<V> cmp, Pair<V> val) {
-        return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long PAIR;
+    static {
+        try {
+            PAIR = U.objectFieldOffset
+                (AtomicStampedReference.class.getDeclaredField("pair"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
     }
 
-    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
-                                  String field, Class<?> klazz) {
-        try {
-            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
-        } catch (NoSuchFieldException e) {
-            // Convert Exception to corresponding Error
-            NoSuchFieldError error = new NoSuchFieldError(field);
-            error.initCause(e);
-            throw error;
-        }
+    private boolean casPair(Pair<V> cmp, Pair<V> val) {
+        return U.compareAndSwapObject(this, PAIR, cmp, val);
     }
 }
diff --git a/luni/src/main/java/java/util/concurrent/atomic/DoubleAccumulator.java b/luni/src/main/java/java/util/concurrent/atomic/DoubleAccumulator.java
new file mode 100644
index 0000000..1ea088d
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/atomic/DoubleAccumulator.java
@@ -0,0 +1,270 @@
+/*
+ * 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.atomic;
+
+import java.io.Serializable;
+import java.util.function.DoubleBinaryOperator;
+
+/**
+ * One or more variables that together maintain a running {@code double}
+ * value updated using a supplied function.  When updates (method
+ * {@link #accumulate}) are contended across threads, the set of variables
+ * may grow dynamically to reduce contention.  Method {@link #get}
+ * (or, equivalently, {@link #doubleValue}) returns the current value
+ * across the variables maintaining updates.
+ *
+ * <p>This class is usually preferable to alternatives when multiple
+ * threads update a common value that is used for purposes such as
+ * summary statistics that are frequently updated but less frequently
+ * read.
+ *
+ * <p>The supplied accumulator function should be side-effect-free,
+ * since it may be re-applied when attempted updates fail due to
+ * contention among threads. The function is applied with the current
+ * value as its first argument, and the given update as the second
+ * argument.  For example, to maintain a running maximum value, you
+ * could supply {@code Double::max} along with {@code
+ * Double.NEGATIVE_INFINITY} as the identity. The order of
+ * accumulation within or across threads is not guaranteed. Thus, this
+ * class may not be applicable if numerical stability is required,
+ * especially when combining values of substantially different orders
+ * of magnitude.
+ *
+ * <p>Class {@link DoubleAdder} provides analogs of the functionality
+ * of this class for the common special case of maintaining sums.  The
+ * call {@code new DoubleAdder()} is equivalent to {@code new
+ * DoubleAccumulator((x, y) -> x + y, 0.0)}.
+ *
+ * <p>This class extends {@link Number}, but does <em>not</em> define
+ * methods such as {@code equals}, {@code hashCode} and {@code
+ * compareTo} because instances are expected to be mutated, and so are
+ * not useful as collection keys.
+ *
+ * @since 1.8
+ * @author Doug Lea
+ */
+public class DoubleAccumulator extends Striped64 implements Serializable {
+    private static final long serialVersionUID = 7249069246863182397L;
+
+    private final DoubleBinaryOperator function;
+    private final long identity; // use long representation
+
+    /**
+     * Creates a new instance using the given accumulator function
+     * and identity element.
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @param identity identity (initial value) for the accumulator function
+     */
+    public DoubleAccumulator(DoubleBinaryOperator accumulatorFunction,
+                             double identity) {
+        this.function = accumulatorFunction;
+        base = this.identity = Double.doubleToRawLongBits(identity);
+    }
+
+    /**
+     * Updates with the given value.
+     *
+     * @param x the value
+     */
+    public void accumulate(double x) {
+        Cell[] as; long b, v, r; int m; Cell a;
+        if ((as = cells) != null ||
+            (r = Double.doubleToRawLongBits
+             (function.applyAsDouble
+              (Double.longBitsToDouble(b = base), x))) != b  && !casBase(b, r)) {
+            boolean uncontended = true;
+            if (as == null || (m = as.length - 1) < 0 ||
+                (a = as[getProbe() & m]) == null ||
+                !(uncontended =
+                  (r = Double.doubleToRawLongBits
+                   (function.applyAsDouble
+                    (Double.longBitsToDouble(v = a.value), x))) == v ||
+                  a.cas(v, r)))
+                doubleAccumulate(x, function, uncontended);
+        }
+    }
+
+    /**
+     * Returns the current value.  The returned value is <em>NOT</em>
+     * an atomic snapshot; invocation in the absence of concurrent
+     * updates returns an accurate result, but concurrent updates that
+     * occur while the value is being calculated might not be
+     * incorporated.
+     *
+     * @return the current value
+     */
+    public double get() {
+        Cell[] as = cells;
+        double result = Double.longBitsToDouble(base);
+        if (as != null) {
+            for (Cell a : as)
+                if (a != null)
+                    result = function.applyAsDouble
+                        (result, Double.longBitsToDouble(a.value));
+        }
+        return result;
+    }
+
+    /**
+     * Resets variables maintaining updates to the identity value.
+     * This method may be a useful alternative to creating a new
+     * updater, but is only effective if there are no concurrent
+     * updates.  Because this method is intrinsically racy, it should
+     * only be used when it is known that no threads are concurrently
+     * updating.
+     */
+    public void reset() {
+        Cell[] as = cells;
+        base = identity;
+        if (as != null) {
+            for (Cell a : as)
+                if (a != null)
+                    a.reset(identity);
+        }
+    }
+
+    /**
+     * Equivalent in effect to {@link #get} followed by {@link
+     * #reset}. This method may apply for example during quiescent
+     * points between multithreaded computations.  If there are
+     * updates concurrent with this method, the returned value is
+     * <em>not</em> guaranteed to be the final value occurring before
+     * the reset.
+     *
+     * @return the value before reset
+     */
+    public double getThenReset() {
+        Cell[] as = cells;
+        double result = Double.longBitsToDouble(base);
+        base = identity;
+        if (as != null) {
+            for (Cell a : as) {
+                if (a != null) {
+                    double v = Double.longBitsToDouble(a.value);
+                    a.reset(identity);
+                    result = function.applyAsDouble(result, v);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the String representation of the current value.
+     * @return the String representation of the current value
+     */
+    public String toString() {
+        return Double.toString(get());
+    }
+
+    /**
+     * Equivalent to {@link #get}.
+     *
+     * @return the current value
+     */
+    public double doubleValue() {
+        return get();
+    }
+
+    /**
+     * Returns the {@linkplain #get current value} as a {@code long}
+     * after a narrowing primitive conversion.
+     */
+    public long longValue() {
+        return (long)get();
+    }
+
+    /**
+     * Returns the {@linkplain #get current value} as an {@code int}
+     * after a narrowing primitive conversion.
+     */
+    public int intValue() {
+        return (int)get();
+    }
+
+    /**
+     * Returns the {@linkplain #get current value} as a {@code float}
+     * after a narrowing primitive conversion.
+     */
+    public float floatValue() {
+        return (float)get();
+    }
+
+    /**
+     * Serialization proxy, used to avoid reference to the non-public
+     * Striped64 superclass in serialized forms.
+     * @serial include
+     */
+    private static class SerializationProxy implements Serializable {
+        private static final long serialVersionUID = 7249069246863182397L;
+
+        /**
+         * The current value returned by get().
+         * @serial
+         */
+        private final double value;
+
+        /**
+         * The function used for updates.
+         * @serial
+         */
+        private final DoubleBinaryOperator function;
+
+        /**
+         * The identity value, represented as a long, as converted by
+         * {@link Double#doubleToRawLongBits}.  The original identity
+         * can be recovered using {@link Double#longBitsToDouble}.
+         * @serial
+         */
+        private final long identity;
+
+        SerializationProxy(double value,
+                           DoubleBinaryOperator function,
+                           long identity) {
+            this.value = value;
+            this.function = function;
+            this.identity = identity;
+        }
+
+        /**
+         * Returns a {@code DoubleAccumulator} object with initial state
+         * held by this proxy.
+         *
+         * @return a {@code DoubleAccumulator} object with initial state
+         * held by this proxy
+         */
+        private Object readResolve() {
+            double d = Double.longBitsToDouble(identity);
+            DoubleAccumulator a = new DoubleAccumulator(function, d);
+            a.base = Double.doubleToRawLongBits(value);
+            return a;
+        }
+    }
+
+    /**
+     * Returns a
+     * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.DoubleAccumulator.SerializationProxy">
+     * SerializationProxy</a>
+     * representing the state of this instance.
+     *
+     * @return a {@link SerializationProxy}
+     * representing the state of this instance
+     */
+    private Object writeReplace() {
+        return new SerializationProxy(get(), function, identity);
+    }
+
+    /**
+     * @param s the stream
+     * @throws java.io.InvalidObjectException always
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.InvalidObjectException {
+        throw new java.io.InvalidObjectException("Proxy required");
+    }
+
+}
diff --git a/luni/src/main/java/java/util/concurrent/atomic/DoubleAdder.java b/luni/src/main/java/java/util/concurrent/atomic/DoubleAdder.java
new file mode 100644
index 0000000..94844d5
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/atomic/DoubleAdder.java
@@ -0,0 +1,237 @@
+/*
+ * 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.atomic;
+
+import java.io.Serializable;
+
+/**
+ * One or more variables that together maintain an initially zero
+ * {@code double} sum.  When updates (method {@link #add}) are
+ * contended across threads, the set of variables may grow dynamically
+ * to reduce contention.  Method {@link #sum} (or, equivalently {@link
+ * #doubleValue}) returns the current total combined across the
+ * variables maintaining the sum. The order of accumulation within or
+ * across threads is not guaranteed. Thus, this class may not be
+ * applicable if numerical stability is required, especially when
+ * combining values of substantially different orders of magnitude.
+ *
+ * <p>This class is usually preferable to alternatives when multiple
+ * threads update a common value that is used for purposes such as
+ * summary statistics that are frequently updated but less frequently
+ * read.
+ *
+ * <p>This class extends {@link Number}, but does <em>not</em> define
+ * methods such as {@code equals}, {@code hashCode} and {@code
+ * compareTo} because instances are expected to be mutated, and so are
+ * not useful as collection keys.
+ *
+ * @since 1.8
+ * @author Doug Lea
+ */
+public class DoubleAdder extends Striped64 implements Serializable {
+    private static final long serialVersionUID = 7249069246863182397L;
+
+    /*
+     * Note that we must use "long" for underlying representations,
+     * because there is no compareAndSet for double, due to the fact
+     * that the bitwise equals used in any CAS implementation is not
+     * the same as double-precision equals.  However, we use CAS only
+     * to detect and alleviate contention, for which bitwise equals
+     * works best anyway. In principle, the long/double conversions
+     * used here should be essentially free on most platforms since
+     * they just re-interpret bits.
+     */
+
+    /**
+     * Creates a new adder with initial sum of zero.
+     */
+    public DoubleAdder() {
+    }
+
+    /**
+     * Adds the given value.
+     *
+     * @param x the value to add
+     */
+    public void add(double x) {
+        Cell[] as; long b, v; int m; Cell a;
+        if ((as = cells) != null ||
+            !casBase(b = base,
+                     Double.doubleToRawLongBits
+                     (Double.longBitsToDouble(b) + x))) {
+            boolean uncontended = true;
+            if (as == null || (m = as.length - 1) < 0 ||
+                (a = as[getProbe() & m]) == null ||
+                !(uncontended = a.cas(v = a.value,
+                                      Double.doubleToRawLongBits
+                                      (Double.longBitsToDouble(v) + x))))
+                doubleAccumulate(x, null, uncontended);
+        }
+    }
+
+    /**
+     * Returns the current sum.  The returned value is <em>NOT</em> an
+     * atomic snapshot; invocation in the absence of concurrent
+     * updates returns an accurate result, but concurrent updates that
+     * occur while the sum is being calculated might not be
+     * incorporated.  Also, because floating-point arithmetic is not
+     * strictly associative, the returned result need not be identical
+     * to the value that would be obtained in a sequential series of
+     * updates to a single variable.
+     *
+     * @return the sum
+     */
+    public double sum() {
+        Cell[] as = cells;
+        double sum = Double.longBitsToDouble(base);
+        if (as != null) {
+            for (Cell a : as)
+                if (a != null)
+                    sum += Double.longBitsToDouble(a.value);
+        }
+        return sum;
+    }
+
+    /**
+     * Resets variables maintaining the sum to zero.  This method may
+     * be a useful alternative to creating a new adder, but is only
+     * effective if there are no concurrent updates.  Because this
+     * method is intrinsically racy, it should only be used when it is
+     * known that no threads are concurrently updating.
+     */
+    public void reset() {
+        Cell[] as = cells;
+        base = 0L; // relies on fact that double 0 must have same rep as long
+        if (as != null) {
+            for (Cell a : as)
+                if (a != null)
+                    a.reset();
+        }
+    }
+
+    /**
+     * Equivalent in effect to {@link #sum} followed by {@link
+     * #reset}. This method may apply for example during quiescent
+     * points between multithreaded computations.  If there are
+     * updates concurrent with this method, the returned value is
+     * <em>not</em> guaranteed to be the final value occurring before
+     * the reset.
+     *
+     * @return the sum
+     */
+    public double sumThenReset() {
+        Cell[] as = cells;
+        double sum = Double.longBitsToDouble(base);
+        base = 0L;
+        if (as != null) {
+            for (Cell a : as) {
+                if (a != null) {
+                    long v = a.value;
+                    a.reset();
+                    sum += Double.longBitsToDouble(v);
+                }
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * Returns the String representation of the {@link #sum}.
+     * @return the String representation of the {@link #sum}
+     */
+    public String toString() {
+        return Double.toString(sum());
+    }
+
+    /**
+     * Equivalent to {@link #sum}.
+     *
+     * @return the sum
+     */
+    public double doubleValue() {
+        return sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as a {@code long} after a
+     * narrowing primitive conversion.
+     */
+    public long longValue() {
+        return (long)sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as an {@code int} after a
+     * narrowing primitive conversion.
+     */
+    public int intValue() {
+        return (int)sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as a {@code float}
+     * after a narrowing primitive conversion.
+     */
+    public float floatValue() {
+        return (float)sum();
+    }
+
+    /**
+     * Serialization proxy, used to avoid reference to the non-public
+     * Striped64 superclass in serialized forms.
+     * @serial include
+     */
+    private static class SerializationProxy implements Serializable {
+        private static final long serialVersionUID = 7249069246863182397L;
+
+        /**
+         * The current value returned by sum().
+         * @serial
+         */
+        private final double value;
+
+        SerializationProxy(DoubleAdder a) {
+            value = a.sum();
+        }
+
+        /**
+         * Returns a {@code DoubleAdder} object with initial state
+         * held by this proxy.
+         *
+         * @return a {@code DoubleAdder} object with initial state
+         * held by this proxy
+         */
+        private Object readResolve() {
+            DoubleAdder a = new DoubleAdder();
+            a.base = Double.doubleToRawLongBits(value);
+            return a;
+        }
+    }
+
+    /**
+     * Returns a
+     * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.DoubleAdder.SerializationProxy">
+     * SerializationProxy</a>
+     * representing the state of this instance.
+     *
+     * @return a {@link SerializationProxy}
+     * representing the state of this instance
+     */
+    private Object writeReplace() {
+        return new SerializationProxy(this);
+    }
+
+    /**
+     * @param s the stream
+     * @throws java.io.InvalidObjectException always
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.InvalidObjectException {
+        throw new java.io.InvalidObjectException("Proxy required");
+    }
+
+}
diff --git a/luni/src/main/java/java/util/concurrent/atomic/Fences.java b/luni/src/main/java/java/util/concurrent/atomic/Fences.java
deleted file mode 100644
index d907faf..0000000
--- a/luni/src/main/java/java/util/concurrent/atomic/Fences.java
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * 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.atomic;
-
-/**
- * A set of methods providing fine-grained control over happens-before
- * and synchronization order relations among reads and/or writes.  The
- * methods of this class are designed for use in uncommon situations
- * where declaring variables {@code volatile} or {@code final}, using
- * instances of atomic classes, using {@code synchronized} blocks or
- * methods, or using other synchronization facilities are not possible
- * or do not provide the desired control.
- *
- * <p><b>Memory Ordering.</b> There are three methods for controlling
- * ordering relations among memory accesses (i.e., reads and
- * writes). Method {@code orderWrites} is typically used to enforce
- * order between two writes, and {@code orderAccesses} between a write
- * and a read.  Method {@code orderReads} is used to enforce order
- * between two reads with respect to other {@code orderWrites} and/or
- * {@code orderAccesses} invocations.  The formally specified
- * properties of these methods described below provide
- * platform-independent guarantees that are honored by all levels of a
- * platform (compilers, systems, processors).  The use of these
- * methods may result in the suppression of otherwise valid compiler
- * transformations and optimizations that could visibly violate the
- * specified orderings, and may or may not entail the use of
- * processor-level "memory barrier" instructions.
- *
- * <p>Each ordering method accepts a {@code ref} argument, and
- * controls ordering among accesses with respect to this reference.
- * Invocations must be placed <em>between</em> accesses performed in
- * expression evaluations and assignment statements to control the
- * orderings of prior versus subsequent accesses appearing in program
- * order. These methods also return their arguments to simplify
- * correct usage in these contexts.
- *
- * <p>Usages of ordering methods almost always take one of the forms
- * illustrated in the examples below.  These idioms arrange some of
- * the ordering properties associated with {@code volatile} and
- * related language-based constructions, but without other
- * compile-time and runtime benefits that make language-based
- * constructions far better choices when they are applicable.  Usages
- * should be restricted to the control of strictly internal
- * implementation matters inside a class or package, and must either
- * avoid or document any consequent violations of ordering or safety
- * properties expected by users of a class employing them.
- *
- * <p><b>Reachability.</b> Method {@code reachabilityFence}
- * establishes an ordering for strong reachability (as defined in the
- * {@link java.lang.ref} package specification) with respect to
- * garbage collection.  Method {@code reachabilityFence} differs from
- * the others in that it controls relations that are otherwise only
- * implicit in a program -- the reachability conditions triggering
- * garbage collection.  As illustrated in the sample usages below,
- * this method is applicable only when reclamation may have visible
- * effects, which is possible for objects with finalizers (see Section
- * 12.6 of the Java Language Specification) that are implemented in
- * ways that rely on ordering control for correctness.
- *
- * <p><b>Sample Usages</b>
- *
- * <p><b>Safe publication.</b> With care, method {@code orderWrites}
- * may be used to obtain the memory safety effects of {@code final}
- * for a field that cannot be declared as {@code final}, because its
- * primary initialization cannot be performed in a constructor, in
- * turn because it is used in a framework requiring that all classes
- * have a no-argument constructor; as in:
- *
- * <pre> {@code
- * class WidgetHolder {
- *   private Widget widget;
- *   public WidgetHolder() {}
- *   public static WidgetHolder newWidgetHolder(Params params) {
- *     WidgetHolder h = new WidgetHolder();
- *     h.widget = new Widget(params);
- *     return Fences.orderWrites(h);
- *   }
- * }}</pre>
- *
- * Here, the invocation of {@code orderWrites} ensures that the
- * effects of the widget assignment are ordered before those of any
- * (unknown) subsequent stores of {@code h} in other variables that
- * make {@code h} available for use by other objects.  Initialization
- * sequences using {@code orderWrites} require more care than those
- * involving {@code final} fields.  When {@code final} is not used,
- * compilers cannot help you to ensure that the field is set correctly
- * across all usages.  You must fully initialize objects
- * <em>before</em> the {@code orderWrites} invocation that makes
- * references to them safe to assign to accessible variables. Further,
- * initialization sequences must not internally "leak" the reference
- * by using it as an argument to a callback method or adding it to a
- * static data structure.  If less constrained usages were required,
- * it may be possible to cope using more extensive sets of fences, or
- * as a normally better choice, using synchronization (locking).
- * Conversely, if it were possible to do so, the best option would be
- * to rewrite class {@code WidgetHolder} to use {@code final}.
- *
- * <p>An alternative approach is to place similar mechanics in the
- * (sole) method that makes such objects available for use by others.
- * Here is a stripped-down example illustrating the essentials. In
- * practice, among other changes, you would use access methods instead
- * of a public field.
- *
- * <pre> {@code
- * class AnotherWidgetHolder {
- *   public Widget widget;
- *   void publish(Widget w) {
- *     this.widget = Fences.orderWrites(w);
- *   }
- *   // ...
- * }}</pre>
- *
- * In this case, the {@code orderWrites} invocation occurs before the
- * store making the object available. Correctness again relies on
- * ensuring that there are no leaks prior to invoking this method, and
- * that it really is the <em>only</em> means of accessing the
- * published object.  This approach is not often applicable --
- * normally you would publish objects using a thread-safe collection
- * that itself guarantees the expected ordering relations. However, it
- * may come into play in the construction of such classes themselves.
- *
- * <p><b>Safely updating fields.</b> Outside of the initialization
- * idioms illustrated above, Fence methods ordering writes must be
- * paired with those ordering reads. To illustrate, suppose class
- * {@code c} contains an accessible variable {@code data} that should
- * have been declared as {@code volatile} but wasn't:
- *
- * <pre> {@code
- * class C {
- *   Object data;  // need volatile access but not volatile
- *   // ...
- * }
- *
- * class App {
- *   Object getData(C c) {
- *     return Fences.orderReads(c).data;
- *   }
- *
- *   void setData(C c) {
- *     Object newValue = ...;
- *     c.data = Fences.orderWrites(newValue);
- *     Fences.orderAccesses(c);
- *   }
- *   // ...
- * }}</pre>
- *
- * Method {@code getData} provides an emulation of {@code volatile}
- * reads of (non-long/double) fields by ensuring that the read of
- * {@code c} obtained as an argument is ordered before subsequent
- * reads using this reference, and then performs the read of its
- * field. Method {@code setData} provides an emulation of volatile
- * writes, ensuring that all other relevant writes have completed,
- * then performing the assignment, and then ensuring that the write is
- * ordered before any other access.  These techniques may apply even
- * when fields are not directly accessible, in which case calls to
- * fence methods would surround calls to methods such as {@code
- * c.getData()}.  However, these techniques cannot be applied to
- * {@code long} or {@code double} fields because reads and writes of
- * fields of these types are not guaranteed to be
- * atomic. Additionally, correctness may require that all accesses of
- * such data use these kinds of wrapper methods, which you would need
- * to manually ensure.
- *
- * <p>More generally, Fence methods can be used in this way to achieve
- * the safety properties of {@code volatile}. However their use does
- * not necessarily guarantee the full sequential consistency
- * properties specified in the Java Language Specification chapter 17
- * for programs using {@code volatile}. In particular, emulation using
- * Fence methods is not guaranteed to maintain the property that
- * {@code volatile} operations performed by different threads are
- * observed in the same order by all observer threads.
- *
- * <p><b>Acquire/Release management of threadsafe objects</b>. It may
- * be possible to use weaker conventions for volatile-like variables
- * when they are used to keep track of objects that fully manage their
- * own thread-safety and synchronization.  Here, an acquiring read
- * operation remains the same as a volatile-read, but a releasing
- * write differs by virtue of not itself ensuring an ordering of its
- * write with subsequent reads, because the required effects are
- * already ensured by the referenced objects.
- * For example:
- *
- * <pre> {@code
- * class Item {
- *   synchronized f(); // ALL methods are synchronized
- *   // ...
- * }
- *
- * class ItemHolder {
- *   private Item item;
- *   Item acquireItem() {
- *     return Fences.orderReads(item);
- *   }
- *
- *   void releaseItem(Item x) {
- *     item = Fences.orderWrites(x);
- *   }
- *
- *   // ...
- * }}</pre>
- *
- * Because this construction avoids use of {@code orderAccesses},
- * which is typically more costly than the other fence methods, it may
- * result in better performance than using {@code volatile} or its
- * emulation. However, as is the case with most applications of fence
- * methods, correctness relies on the usage context -- here, the
- * thread safety of {@code Item}, as well as the lack of need for full
- * volatile semantics inside this class itself. However, the second
- * concern means that it can be difficult to extend the {@code
- * ItemHolder} class in this example to be more useful.
- *
- * <p><b>Avoiding premature finalization.</b> Finalization may occur
- * whenever a Java Virtual Machine detects that no reference to an
- * object will ever be stored in the heap: A garbage collector may
- * reclaim an object even if the fields of that object are still in
- * use, so long as the object has otherwise become unreachable. This
- * may have surprising and undesirable effects in cases such as the
- * following example in which the bookkeeping associated with a class
- * is managed through array indices. Here, method {@code action}
- * uses a {@code reachabilityFence} to ensure that the Resource
- * object is not reclaimed before bookkeeping on an associated
- * ExternalResource has been performed; in particular here, to ensure
- * that the array slot holding the ExternalResource is not nulled out
- * in method {@link Object#finalize}, which may otherwise run
- * concurrently.
- *
- * <pre> {@code
- * class Resource {
- *   private static ExternalResource[] externalResourceArray = ...
- *
- *   int myIndex;
- *   Resource(...) {
- *     myIndex = ...
- *     externalResourceArray[myIndex] = ...;
- *     ...
- *   }
- *   protected void finalize() {
- *     externalResourceArray[myIndex] = null;
- *     ...
- *   }
- *   public void action() {
- *     try {
- *       // ...
- *       int i = myIndex;
- *       Resource.update(externalResourceArray[i]);
- *     } finally {
- *       Fences.reachabilityFence(this);
- *     }
- *   }
- *   private static void update(ExternalResource ext) {
- *     ext.status = ...;
- *   }
- * }}</pre>
- *
- * Here, the call to {@code reachabilityFence} is nonintuitively
- * placed <em>after</em> the call to {@code update}, to ensure that
- * the array slot is not nulled out by {@link Object#finalize} before
- * the update, even if the call to {@code action} was the last use of
- * this object. This might be the case if for example a usage in a
- * user program had the form {@code new Resource().action();} which
- * retains no other reference to this Resource.  While probably
- * overkill here, {@code reachabilityFence} is placed in a {@code
- * finally} block to ensure that it is invoked across all paths in the
- * method.  In a method with more complex control paths, you might
- * need further precautions to ensure that {@code reachabilityFence}
- * is encountered along all of them.
- *
- * <p>It is sometimes possible to better encapsulate use of
- * {@code reachabilityFence}. Continuing the above example, if it
- * were OK for the call to method update to proceed even if the
- * finalizer had already executed (nulling out slot), then you could
- * localize use of {@code reachabilityFence}:
- *
- * <pre> {@code
- * public void action2() {
- *   // ...
- *   Resource.update(getExternalResource());
- * }
- * private ExternalResource getExternalResource() {
- *   ExternalResource ext = externalResourceArray[myIndex];
- *   Fences.reachabilityFence(this);
- *   return ext;
- * }}</pre>
- *
- * <p>Method {@code reachabilityFence} is not required in
- * constructions that themselves ensure reachability. For example,
- * because objects that are locked cannot in general be reclaimed, it
- * would suffice if all accesses of the object, in all methods of
- * class Resource (including {@code finalize}) were enclosed in {@code
- * synchronized (this)} blocks. (Further, such blocks must not include
- * infinite loops, or themselves be unreachable, which fall into the
- * corner case exceptions to the "in general" disclaimer.) However,
- * method {@code reachabilityFence} remains a better option in cases
- * where this approach is not as efficient, desirable, or possible;
- * for example because it would encounter deadlock.
- *
- * <p><b>Formal Properties.</b>
- *
- * <p>Using the terminology of The Java Language Specification chapter
- * 17, the rules governing the semantics of the methods of this class
- * are as follows:
- *
- * <p>The following is still under construction.
- *
- * <dl>
- *
- *   <dt><b>[Definitions]</b>
- *   <dd>
- *   <ul>
- *
- *     <li>Define <em>sequenced(a, b)</em> to be true if <em>a</em>
- *     occurs before <em>b</em> in <em>program order</em>.
- *
- *     <li>Define <em>accesses(a, p)</em> to be true if
- *     <em>a</em> is a read or write of a field (or if an array, an
- *     element) of the object referenced by <em>p</em>.
- *
- *     <li>Define <em>deeplyAccesses(a, p)</em> to be true if either
- *     <em>accesses(a, p)</em> or <em>deeplyAccesses(a, q)</em> where
- *     <em>q</em> is the value seen by some read <em>r</em>
- *     such that <em>accesses(r, p)</em>.
- *
- *   </ul>
- *   <dt><b>[Matching]</b>
- *   <dd>Given:
- *
- *   <ul>
- *
- *     <li><em>p</em>, a reference to an object
- *
- *     <li><em>wf</em>, an invocation of {@code orderWrites(p)} or
- *       {@code orderAccesses(p)}
- *
- *     <li><em>w</em>, a write of value <em>p</em>
- *
- *     <li> <em>rf</em>, an invocation of {@code orderReads(p)} or
- *     {@code orderAccesses(p)}
- *
- *     <li> <em>r</em>, a read returning value <em>p</em>
- *
- *   </ul>
- *   If:
- *   <ul>
- *     <li>sequenced(wf, w)
- *     <li>read <em>r</em> sees write <em>w</em>
- *     <li>sequenced(r, rf)
- *   </ul>
- *   Then:
- *   <ul>
- *
- *     <li> <em>wf happens-before rf</em>
- *
- *     <li> <em>wf</em> precedes <em>rf</em> in the
- *          <em>synchronization order</em>
- *
- *     <li> If (<em>r1</em>, <em>w1</em>) and (<em>r2</em>,
- *     <em>w2</em>) are two pairs of reads and writes, both
- *     respectively satisfying the above conditions for <em>p</em>,
- *     and sequenced(r1, r2) then it is not the case that <em>w2
- *     happens-before w1</em>.
- *
- *   </ul>
- *   <dt><b>[Initial Reads]</b>
- *   <dd>Given:
- *
- *   <ul>
- *
- *     <li><em>p</em>, a reference to an object
- *
- *     <li> <em>a</em>, an access where deeplyAccesses(a, p)
- *
- *     <li><em>wf</em>, an invocation of {@code orderWrites(p)} or
- *       {@code orderAccesses(p)}
- *
- *     <li><em>w</em>, a write of value <em>p</em>
- *
- *     <li> <em>r</em>, a read returning value <em>p</em>
- *
- *     <li> <em>b</em>, an access where accesses(b, p)
- *
- *   </ul>
- *   If:
- *   <ul>
- *     <li>sequenced(a, wf);
- *     <li>sequenced(wf, w)
- *     <li>read <em>r</em> sees write <em>w</em>, and
- *         <em>r</em> is the first read by some thread
- *         <em>t</em> that sees value <em>p</em>
- *     <li>sequenced(r, b)
- *   </ul>
- *   Then:
- *   <ul>
- *     <li> the effects of <em>b</em> are constrained
- *          by the relation <em>a happens-before b</em>.
- *   </ul>
- *  <dt><b>[orderAccesses]</b>
- *  <dd>Given:
- *
- *   <ul>
- *     <li><em>p</em>, a reference to an object
- *     <li><em>f</em>, an invocation of {@code orderAccesses(p)}
- *   </ul>
- *   If:
- *   <ul>
- *     <li>sequenced(f, w)
- *   </ul>
- *
- *    Then:
- *
- *   <ul>
- *
- *     <li> <em>f</em> is an element of the <em>synchronization order</em>.
- *
- *   </ul>
- *   <dt><b>[Reachability]</b>
- *   <dd>Given:
- *
- *   <ul>
- *
- *     <li><em>p</em>, a reference to an object
- *
- *     <li><em>f</em>, an invocation of {@code reachabilityFence(p)}
- *
- *     <li><em>a</em>, an access where accesses(a, p)
- *
- *     <li><em>b</em>, an action (by a garbage collector) taking
- *     the form of an invocation of {@code
- *     p.finalize()} or of enqueuing any {@link
- *     java.lang.ref.Reference} constructed with argument <em>p</em>
- *
- *   </ul>
- *
- *   If:
- *   <ul>
- *     <li>sequenced(a, f)
- *   </ul>
- *
- *    Then:
- *
- *   <ul>
- *
- *     <li> <em>a happens-before b</em>.
- *
- *   </ul>
- *
- * </dl>
- *
- * @hide
- * @author Doug Lea
- */
-public class Fences {
-    private Fences() {} // Non-instantiable
-
-    /**
-     * The methods of this class are intended to be intrinisified by a
-     * JVM. However, we provide correct but inefficient Java-level
-     * code that simply reads and writes a static volatile
-     * variable. Without JVM support, the consistency effects are
-     * stronger than necessary, and the memory contention effects can
-     * be a serious performance issue.
-     */
-    private static volatile int theVolatile;
-
-    /**
-     * Informally: Ensures that a read of the given reference prior to
-     * the invocation of this method occurs before a subsequent use of
-     * the given reference with the effect of reading or writing a
-     * field (or if an array, element) of the referenced object.  The
-     * use of this method is sensible only when paired with other
-     * invocations of {@link #orderWrites} and/or {@link
-     * #orderAccesses} for the given reference. For details, see the
-     * class documentation for this class.
-     *
-     * @param ref the reference. If null, this method has no effect.
-     * @param <T> the type of the reference
-     * @return the given ref, to simplify usage
-     */
-    public static <T> T orderReads(T ref) {
-        int ignore = theVolatile;
-        return ref;
-    }
-
-    /**
-     * Informally: Ensures that a use of the given reference with the
-     * effect of reading or writing a field (or if an array, element)
-     * of the referenced object, prior to the invocation of this
-     * method occur before a subsequent write of the reference. For
-     * details, see the class documentation for this class.
-     *
-     * @param ref the reference. If null, this method has no effect.
-     * @param <T> the type of the reference
-     * @return the given ref, to simplify usage
-     */
-    public static <T> T orderWrites(T ref) {
-        theVolatile = 0;
-        return ref;
-    }
-
-    /**
-     * Informally: Ensures that accesses (reads or writes) using the
-     * given reference prior to the invocation of this method occur
-     * before subsequent accesses.  For details, see the class
-     * documentation for this class.
-     *
-     * @param ref the reference. If null, this method has no effect.
-     * @param <T> the type of the reference
-     * @return the given ref, to simplify usage
-     */
-    public static <T> T orderAccesses(T ref) {
-        theVolatile = 0;
-        return ref;
-    }
-
-    /**
-     * Ensures that the object referenced by the given reference
-     * remains <em>strongly reachable</em> (as defined in the {@link
-     * java.lang.ref} package documentation), regardless of any prior
-     * actions of the program that might otherwise cause the object to
-     * become unreachable; thus, the referenced object is not
-     * reclaimable by garbage collection at least until after the
-     * invocation of this method. Invocation of this method does not
-     * itself initiate garbage collection or finalization.
-     *
-     * <p>See the class-level documentation for further explanation
-     * and usage examples.
-     *
-     * @param ref the reference. If null, this method has no effect.
-     */
-    public static void reachabilityFence(Object ref) {
-        if (ref != null) {
-            synchronized (ref) {}
-        }
-    }
-}
diff --git a/luni/src/main/java/java/util/concurrent/atomic/LongAccumulator.java b/luni/src/main/java/java/util/concurrent/atomic/LongAccumulator.java
new file mode 100644
index 0000000..85e3241
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/atomic/LongAccumulator.java
@@ -0,0 +1,264 @@
+/*
+ * 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.atomic;
+
+import java.io.Serializable;
+import java.util.function.LongBinaryOperator;
+
+/**
+ * One or more variables that together maintain a running {@code long}
+ * value updated using a supplied function.  When updates (method
+ * {@link #accumulate}) are contended across threads, the set of variables
+ * may grow dynamically to reduce contention.  Method {@link #get}
+ * (or, equivalently, {@link #longValue}) returns the current value
+ * across the variables maintaining updates.
+ *
+ * <p>This class is usually preferable to {@link AtomicLong} when
+ * multiple threads update a common value that is used for purposes such
+ * as collecting statistics, not for fine-grained synchronization
+ * control.  Under low update contention, the two classes have similar
+ * characteristics. But under high contention, expected throughput of
+ * this class is significantly higher, at the expense of higher space
+ * consumption.
+ *
+ * <p>The order of accumulation within or across threads is not
+ * guaranteed and cannot be depended upon, so this class is only
+ * applicable to functions for which the order of accumulation does
+ * not matter. The supplied accumulator function should be
+ * side-effect-free, since it may be re-applied when attempted updates
+ * fail due to contention among threads. The function is applied with
+ * the current value as its first argument, and the given update as
+ * the second argument.  For example, to maintain a running maximum
+ * value, you could supply {@code Long::max} along with {@code
+ * Long.MIN_VALUE} as the identity.
+ *
+ * <p>Class {@link LongAdder} provides analogs of the functionality of
+ * this class for the common special case of maintaining counts and
+ * sums.  The call {@code new LongAdder()} is equivalent to {@code new
+ * LongAccumulator((x, y) -> x + y, 0L}.
+ *
+ * <p>This class extends {@link Number}, but does <em>not</em> define
+ * methods such as {@code equals}, {@code hashCode} and {@code
+ * compareTo} because instances are expected to be mutated, and so are
+ * not useful as collection keys.
+ *
+ * @since 1.8
+ * @author Doug Lea
+ */
+public class LongAccumulator extends Striped64 implements Serializable {
+    private static final long serialVersionUID = 7249069246863182397L;
+
+    private final LongBinaryOperator function;
+    private final long identity;
+
+    /**
+     * Creates a new instance using the given accumulator function
+     * and identity element.
+     * @param accumulatorFunction a side-effect-free function of two arguments
+     * @param identity identity (initial value) for the accumulator function
+     */
+    public LongAccumulator(LongBinaryOperator accumulatorFunction,
+                           long identity) {
+        this.function = accumulatorFunction;
+        base = this.identity = identity;
+    }
+
+    /**
+     * Updates with the given value.
+     *
+     * @param x the value
+     */
+    public void accumulate(long x) {
+        Cell[] as; long b, v, r; int m; Cell a;
+        if ((as = cells) != null ||
+            (r = function.applyAsLong(b = base, x)) != b && !casBase(b, r)) {
+            boolean uncontended = true;
+            if (as == null || (m = as.length - 1) < 0 ||
+                (a = as[getProbe() & m]) == null ||
+                !(uncontended =
+                  (r = function.applyAsLong(v = a.value, x)) == v ||
+                  a.cas(v, r)))
+                longAccumulate(x, function, uncontended);
+        }
+    }
+
+    /**
+     * Returns the current value.  The returned value is <em>NOT</em>
+     * an atomic snapshot; invocation in the absence of concurrent
+     * updates returns an accurate result, but concurrent updates that
+     * occur while the value is being calculated might not be
+     * incorporated.
+     *
+     * @return the current value
+     */
+    public long get() {
+        Cell[] as = cells;
+        long result = base;
+        if (as != null) {
+            for (Cell a : as)
+                if (a != null)
+                    result = function.applyAsLong(result, a.value);
+        }
+        return result;
+    }
+
+    /**
+     * Resets variables maintaining updates to the identity value.
+     * This method may be a useful alternative to creating a new
+     * updater, but is only effective if there are no concurrent
+     * updates.  Because this method is intrinsically racy, it should
+     * only be used when it is known that no threads are concurrently
+     * updating.
+     */
+    public void reset() {
+        Cell[] as = cells;
+        base = identity;
+        if (as != null) {
+            for (Cell a : as)
+                if (a != null)
+                    a.reset(identity);
+        }
+    }
+
+    /**
+     * Equivalent in effect to {@link #get} followed by {@link
+     * #reset}. This method may apply for example during quiescent
+     * points between multithreaded computations.  If there are
+     * updates concurrent with this method, the returned value is
+     * <em>not</em> guaranteed to be the final value occurring before
+     * the reset.
+     *
+     * @return the value before reset
+     */
+    public long getThenReset() {
+        Cell[] as = cells;
+        long result = base;
+        base = identity;
+        if (as != null) {
+            for (Cell a : as) {
+                if (a != null) {
+                    long v = a.value;
+                    a.reset(identity);
+                    result = function.applyAsLong(result, v);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the String representation of the current value.
+     * @return the String representation of the current value
+     */
+    public String toString() {
+        return Long.toString(get());
+    }
+
+    /**
+     * Equivalent to {@link #get}.
+     *
+     * @return the current value
+     */
+    public long longValue() {
+        return get();
+    }
+
+    /**
+     * Returns the {@linkplain #get current value} as an {@code int}
+     * after a narrowing primitive conversion.
+     */
+    public int intValue() {
+        return (int)get();
+    }
+
+    /**
+     * Returns the {@linkplain #get current value} as a {@code float}
+     * after a widening primitive conversion.
+     */
+    public float floatValue() {
+        return (float)get();
+    }
+
+    /**
+     * Returns the {@linkplain #get current value} as a {@code double}
+     * after a widening primitive conversion.
+     */
+    public double doubleValue() {
+        return (double)get();
+    }
+
+    /**
+     * Serialization proxy, used to avoid reference to the non-public
+     * Striped64 superclass in serialized forms.
+     * @serial include
+     */
+    private static class SerializationProxy implements Serializable {
+        private static final long serialVersionUID = 7249069246863182397L;
+
+        /**
+         * The current value returned by get().
+         * @serial
+         */
+        private final long value;
+
+        /**
+         * The function used for updates.
+         * @serial
+         */
+        private final LongBinaryOperator function;
+
+        /**
+         * The identity value.
+         * @serial
+         */
+        private final long identity;
+
+        SerializationProxy(long value,
+                           LongBinaryOperator function,
+                           long identity) {
+            this.value = value;
+            this.function = function;
+            this.identity = identity;
+        }
+
+        /**
+         * Returns a {@code LongAccumulator} object with initial state
+         * held by this proxy.
+         *
+         * @return a {@code LongAccumulator} object with initial state
+         * held by this proxy
+         */
+        private Object readResolve() {
+            LongAccumulator a = new LongAccumulator(function, identity);
+            a.base = value;
+            return a;
+        }
+    }
+
+    /**
+     * Returns a
+     * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.LongAccumulator.SerializationProxy">
+     * SerializationProxy</a>
+     * representing the state of this instance.
+     *
+     * @return a {@link SerializationProxy}
+     * representing the state of this instance
+     */
+    private Object writeReplace() {
+        return new SerializationProxy(get(), function, identity);
+    }
+
+    /**
+     * @param s the stream
+     * @throws java.io.InvalidObjectException always
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.InvalidObjectException {
+        throw new java.io.InvalidObjectException("Proxy required");
+    }
+
+}
diff --git a/luni/src/main/java/java/util/concurrent/atomic/LongAdder.java b/luni/src/main/java/java/util/concurrent/atomic/LongAdder.java
new file mode 100644
index 0000000..a17d52a
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/atomic/LongAdder.java
@@ -0,0 +1,238 @@
+/*
+ * 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.atomic;
+
+import java.io.Serializable;
+
+/**
+ * One or more variables that together maintain an initially zero
+ * {@code long} sum.  When updates (method {@link #add}) are contended
+ * across threads, the set of variables may grow dynamically to reduce
+ * contention. Method {@link #sum} (or, equivalently, {@link
+ * #longValue}) returns the current total combined across the
+ * variables maintaining the sum.
+ *
+ * <p>This class is usually preferable to {@link AtomicLong} when
+ * multiple threads update a common sum that is used for purposes such
+ * as collecting statistics, not for fine-grained synchronization
+ * control.  Under low update contention, the two classes have similar
+ * characteristics. But under high contention, expected throughput of
+ * this class is significantly higher, at the expense of higher space
+ * consumption.
+ *
+ * <p>LongAdders can be used with a {@link
+ * java.util.concurrent.ConcurrentHashMap} to maintain a scalable
+ * frequency map (a form of histogram or multiset). For example, to
+ * add a count to a {@code ConcurrentHashMap<String,LongAdder> freqs},
+ * initializing if not already present, you can use {@code
+ * freqs.computeIfAbsent(key, k -> new LongAdder()).increment();}
+ *
+ * <p>This class extends {@link Number}, but does <em>not</em> define
+ * methods such as {@code equals}, {@code hashCode} and {@code
+ * compareTo} because instances are expected to be mutated, and so are
+ * not useful as collection keys.
+ *
+ * @since 1.8
+ * @author Doug Lea
+ */
+public class LongAdder extends Striped64 implements Serializable {
+    private static final long serialVersionUID = 7249069246863182397L;
+
+    /**
+     * Creates a new adder with initial sum of zero.
+     */
+    public LongAdder() {
+    }
+
+    /**
+     * Adds the given value.
+     *
+     * @param x the value to add
+     */
+    public void add(long x) {
+        Cell[] as; long b, v; int m; Cell a;
+        if ((as = cells) != null || !casBase(b = base, b + x)) {
+            boolean uncontended = true;
+            if (as == null || (m = as.length - 1) < 0 ||
+                (a = as[getProbe() & m]) == null ||
+                !(uncontended = a.cas(v = a.value, v + x)))
+                longAccumulate(x, null, uncontended);
+        }
+    }
+
+    /**
+     * Equivalent to {@code add(1)}.
+     */
+    public void increment() {
+        add(1L);
+    }
+
+    /**
+     * Equivalent to {@code add(-1)}.
+     */
+    public void decrement() {
+        add(-1L);
+    }
+
+    /**
+     * Returns the current sum.  The returned value is <em>NOT</em> an
+     * atomic snapshot; invocation in the absence of concurrent
+     * updates returns an accurate result, but concurrent updates that
+     * occur while the sum is being calculated might not be
+     * incorporated.
+     *
+     * @return the sum
+     */
+    public long sum() {
+        Cell[] as = cells;
+        long sum = base;
+        if (as != null) {
+            for (Cell a : as)
+                if (a != null)
+                    sum += a.value;
+        }
+        return sum;
+    }
+
+    /**
+     * Resets variables maintaining the sum to zero.  This method may
+     * be a useful alternative to creating a new adder, but is only
+     * effective if there are no concurrent updates.  Because this
+     * method is intrinsically racy, it should only be used when it is
+     * known that no threads are concurrently updating.
+     */
+    public void reset() {
+        Cell[] as = cells;
+        base = 0L;
+        if (as != null) {
+            for (Cell a : as)
+                if (a != null)
+                    a.reset();
+        }
+    }
+
+    /**
+     * Equivalent in effect to {@link #sum} followed by {@link
+     * #reset}. This method may apply for example during quiescent
+     * points between multithreaded computations.  If there are
+     * updates concurrent with this method, the returned value is
+     * <em>not</em> guaranteed to be the final value occurring before
+     * the reset.
+     *
+     * @return the sum
+     */
+    public long sumThenReset() {
+        Cell[] as = cells;
+        long sum = base;
+        base = 0L;
+        if (as != null) {
+            for (Cell a : as) {
+                if (a != null) {
+                    sum += a.value;
+                    a.reset();
+                }
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * Returns the String representation of the {@link #sum}.
+     * @return the String representation of the {@link #sum}
+     */
+    public String toString() {
+        return Long.toString(sum());
+    }
+
+    /**
+     * Equivalent to {@link #sum}.
+     *
+     * @return the sum
+     */
+    public long longValue() {
+        return sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as an {@code int} after a narrowing
+     * primitive conversion.
+     */
+    public int intValue() {
+        return (int)sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as a {@code float}
+     * after a widening primitive conversion.
+     */
+    public float floatValue() {
+        return (float)sum();
+    }
+
+    /**
+     * Returns the {@link #sum} as a {@code double} after a widening
+     * primitive conversion.
+     */
+    public double doubleValue() {
+        return (double)sum();
+    }
+
+    /**
+     * Serialization proxy, used to avoid reference to the non-public
+     * Striped64 superclass in serialized forms.
+     * @serial include
+     */
+    private static class SerializationProxy implements Serializable {
+        private static final long serialVersionUID = 7249069246863182397L;
+
+        /**
+         * The current value returned by sum().
+         * @serial
+         */
+        private final long value;
+
+        SerializationProxy(LongAdder a) {
+            value = a.sum();
+        }
+
+        /**
+         * Returns a {@code LongAdder} object with initial state
+         * held by this proxy.
+         *
+         * @return a {@code LongAdder} object with initial state
+         * held by this proxy
+         */
+        private Object readResolve() {
+            LongAdder a = new LongAdder();
+            a.base = value;
+            return a;
+        }
+    }
+
+    /**
+     * Returns a
+     * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.LongAdder.SerializationProxy">
+     * SerializationProxy</a>
+     * representing the state of this instance.
+     *
+     * @return a {@link SerializationProxy}
+     * representing the state of this instance
+     */
+    private Object writeReplace() {
+        return new SerializationProxy(this);
+    }
+
+    /**
+     * @param s the stream
+     * @throws java.io.InvalidObjectException always
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.InvalidObjectException {
+        throw new java.io.InvalidObjectException("Proxy required");
+    }
+
+}
diff --git a/luni/src/main/java/java/util/concurrent/atomic/Striped64.java b/luni/src/main/java/java/util/concurrent/atomic/Striped64.java
new file mode 100644
index 0000000..fc88849
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/atomic/Striped64.java
@@ -0,0 +1,365 @@
+/*
+ * 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.atomic;
+
+import java.util.Arrays;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.LongBinaryOperator;
+
+/**
+ * A package-local class holding common representation and mechanics
+ * for classes supporting dynamic striping on 64bit values. The class
+ * extends Number so that concrete subclasses must publicly do so.
+ */
+@SuppressWarnings("serial")
+abstract class Striped64 extends Number {
+    /*
+     * This class maintains a lazily-initialized table of atomically
+     * updated variables, plus an extra "base" field. The table size
+     * is a power of two. Indexing uses masked per-thread hash codes.
+     * Nearly all declarations in this class are package-private,
+     * accessed directly by subclasses.
+     *
+     * Table entries are of class Cell; a variant of AtomicLong padded
+     * (via @Contended) to reduce cache contention. Padding is
+     * overkill for most Atomics because they are usually irregularly
+     * scattered in memory and thus don't interfere much with each
+     * other. But Atomic objects residing in arrays will tend to be
+     * placed adjacent to each other, and so will most often share
+     * cache lines (with a huge negative performance impact) without
+     * this precaution.
+     *
+     * In part because Cells are relatively large, we avoid creating
+     * them until they are needed.  When there is no contention, all
+     * updates are made to the base field.  Upon first contention (a
+     * failed CAS on base update), the table is initialized to size 2.
+     * The table size is doubled upon further contention until
+     * reaching the nearest power of two greater than or equal to the
+     * number of CPUS. Table slots remain empty (null) until they are
+     * needed.
+     *
+     * A single spinlock ("cellsBusy") is used for initializing and
+     * resizing the table, as well as populating slots with new Cells.
+     * There is no need for a blocking lock; when the lock is not
+     * available, threads try other slots (or the base).  During these
+     * retries, there is increased contention and reduced locality,
+     * which is still better than alternatives.
+     *
+     * The Thread probe fields maintained via ThreadLocalRandom serve
+     * as per-thread hash codes. We let them remain uninitialized as
+     * zero (if they come in this way) until they contend at slot
+     * 0. They are then initialized to values that typically do not
+     * often conflict with others.  Contention and/or table collisions
+     * are indicated by failed CASes when performing an update
+     * operation. Upon a collision, if the table size is less than
+     * the capacity, it is doubled in size unless some other thread
+     * holds the lock. If a hashed slot is empty, and lock is
+     * available, a new Cell is created. Otherwise, if the slot
+     * exists, a CAS is tried.  Retries proceed by "double hashing",
+     * using a secondary hash (Marsaglia XorShift) to try to find a
+     * free slot.
+     *
+     * The table size is capped because, when there are more threads
+     * than CPUs, supposing that each thread were bound to a CPU,
+     * there would exist a perfect hash function mapping threads to
+     * slots that eliminates collisions. When we reach capacity, we
+     * search for this mapping by randomly varying the hash codes of
+     * colliding threads.  Because search is random, and collisions
+     * only become known via CAS failures, convergence can be slow,
+     * and because threads are typically not bound to CPUS forever,
+     * may not occur at all. However, despite these limitations,
+     * observed contention rates are typically low in these cases.
+     *
+     * It is possible for a Cell to become unused when threads that
+     * once hashed to it terminate, as well as in the case where
+     * doubling the table causes no thread to hash to it under
+     * expanded mask.  We do not try to detect or remove such cells,
+     * under the assumption that for long-running instances, observed
+     * contention levels will recur, so the cells will eventually be
+     * needed again; and for short-lived ones, it does not matter.
+     */
+
+    /**
+     * Padded variant of AtomicLong supporting only raw accesses plus CAS.
+     *
+     * JVM intrinsics note: It would be possible to use a release-only
+     * form of CAS here, if it were provided.
+     */
+    // @jdk.internal.vm.annotation.Contended // android-removed
+    static final class Cell {
+        volatile long value;
+        Cell(long x) { value = x; }
+        final boolean cas(long cmp, long val) {
+            return U.compareAndSwapLong(this, VALUE, cmp, val);
+        }
+        final void reset() {
+            U.putLongVolatile(this, VALUE, 0L);
+        }
+        final void reset(long identity) {
+            U.putLongVolatile(this, VALUE, identity);
+        }
+
+        // Unsafe mechanics
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final long VALUE;
+        static {
+            try {
+                VALUE = U.objectFieldOffset
+                    (Cell.class.getDeclaredField("value"));
+            } catch (ReflectiveOperationException e) {
+                throw new Error(e);
+            }
+        }
+    }
+
+    /** Number of CPUS, to place bound on table size */
+    static final int NCPU = Runtime.getRuntime().availableProcessors();
+
+    /**
+     * Table of cells. When non-null, size is a power of 2.
+     */
+    transient volatile Cell[] cells;
+
+    /**
+     * Base value, used mainly when there is no contention, but also as
+     * a fallback during table initialization races. Updated via CAS.
+     */
+    transient volatile long base;
+
+    /**
+     * Spinlock (locked via CAS) used when resizing and/or creating Cells.
+     */
+    transient volatile int cellsBusy;
+
+    /**
+     * Package-private default constructor.
+     */
+    Striped64() {
+    }
+
+    /**
+     * CASes the base field.
+     */
+    final boolean casBase(long cmp, long val) {
+        return U.compareAndSwapLong(this, BASE, cmp, val);
+    }
+
+    /**
+     * CASes the cellsBusy field from 0 to 1 to acquire lock.
+     */
+    final boolean casCellsBusy() {
+        return U.compareAndSwapInt(this, CELLSBUSY, 0, 1);
+    }
+
+    /**
+     * Returns the probe value for the current thread.
+     * Duplicated from ThreadLocalRandom because of packaging restrictions.
+     */
+    static final int getProbe() {
+        return U.getInt(Thread.currentThread(), PROBE);
+    }
+
+    /**
+     * Pseudo-randomly advances and records the given probe value for the
+     * given thread.
+     * Duplicated from ThreadLocalRandom because of packaging restrictions.
+     */
+    static final int advanceProbe(int probe) {
+        probe ^= probe << 13;   // xorshift
+        probe ^= probe >>> 17;
+        probe ^= probe << 5;
+        U.putInt(Thread.currentThread(), PROBE, probe);
+        return probe;
+    }
+
+    /**
+     * Handles cases of updates involving initialization, resizing,
+     * creating new Cells, and/or contention. See above for
+     * explanation. This method suffers the usual non-modularity
+     * problems of optimistic retry code, relying on rechecked sets of
+     * reads.
+     *
+     * @param x the value
+     * @param fn the update function, or null for add (this convention
+     * avoids the need for an extra field or function in LongAdder).
+     * @param wasUncontended false if CAS failed before call
+     */
+    final void longAccumulate(long x, LongBinaryOperator fn,
+                              boolean wasUncontended) {
+        int h;
+        if ((h = getProbe()) == 0) {
+            ThreadLocalRandom.current(); // force initialization
+            h = getProbe();
+            wasUncontended = true;
+        }
+        boolean collide = false;                // True if last slot nonempty
+        done: for (;;) {
+            Cell[] as; Cell a; int n; long v;
+            if ((as = cells) != null && (n = as.length) > 0) {
+                if ((a = as[(n - 1) & h]) == null) {
+                    if (cellsBusy == 0) {       // Try to attach new Cell
+                        Cell r = new Cell(x);   // Optimistically create
+                        if (cellsBusy == 0 && casCellsBusy()) {
+                            try {               // Recheck under lock
+                                Cell[] rs; int m, j;
+                                if ((rs = cells) != null &&
+                                    (m = rs.length) > 0 &&
+                                    rs[j = (m - 1) & h] == null) {
+                                    rs[j] = r;
+                                    break done;
+                                }
+                            } finally {
+                                cellsBusy = 0;
+                            }
+                            continue;           // Slot is now non-empty
+                        }
+                    }
+                    collide = false;
+                }
+                else if (!wasUncontended)       // CAS already known to fail
+                    wasUncontended = true;      // Continue after rehash
+                else if (a.cas(v = a.value,
+                               (fn == null) ? v + x : fn.applyAsLong(v, x)))
+                    break;
+                else if (n >= NCPU || cells != as)
+                    collide = false;            // At max size or stale
+                else if (!collide)
+                    collide = true;
+                else if (cellsBusy == 0 && casCellsBusy()) {
+                    try {
+                        if (cells == as)        // Expand table unless stale
+                            cells = Arrays.copyOf(as, n << 1);
+                    } finally {
+                        cellsBusy = 0;
+                    }
+                    collide = false;
+                    continue;                   // Retry with expanded table
+                }
+                h = advanceProbe(h);
+            }
+            else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
+                try {                           // Initialize table
+                    if (cells == as) {
+                        Cell[] rs = new Cell[2];
+                        rs[h & 1] = new Cell(x);
+                        cells = rs;
+                        break done;
+                    }
+                } finally {
+                    cellsBusy = 0;
+                }
+            }
+            // Fall back on using base
+            else if (casBase(v = base,
+                             (fn == null) ? v + x : fn.applyAsLong(v, x)))
+                break done;
+        }
+    }
+
+    private static long apply(DoubleBinaryOperator fn, long v, double x) {
+        double d = Double.longBitsToDouble(v);
+        d = (fn == null) ? d + x : fn.applyAsDouble(d, x);
+        return Double.doubleToRawLongBits(d);
+    }
+
+    /**
+     * Same as longAccumulate, but injecting long/double conversions
+     * in too many places to sensibly merge with long version, given
+     * the low-overhead requirements of this class. So must instead be
+     * maintained by copy/paste/adapt.
+     */
+    final void doubleAccumulate(double x, DoubleBinaryOperator fn,
+                                boolean wasUncontended) {
+        int h;
+        if ((h = getProbe()) == 0) {
+            ThreadLocalRandom.current(); // force initialization
+            h = getProbe();
+            wasUncontended = true;
+        }
+        boolean collide = false;                // True if last slot nonempty
+        done: for (;;) {
+            Cell[] as; Cell a; int n; long v;
+            if ((as = cells) != null && (n = as.length) > 0) {
+                if ((a = as[(n - 1) & h]) == null) {
+                    if (cellsBusy == 0) {       // Try to attach new Cell
+                        Cell r = new Cell(Double.doubleToRawLongBits(x));
+                        if (cellsBusy == 0 && casCellsBusy()) {
+                            try {               // Recheck under lock
+                                Cell[] rs; int m, j;
+                                if ((rs = cells) != null &&
+                                    (m = rs.length) > 0 &&
+                                    rs[j = (m - 1) & h] == null) {
+                                    rs[j] = r;
+                                    break done;
+                                }
+                            } finally {
+                                cellsBusy = 0;
+                            }
+                            continue;           // Slot is now non-empty
+                        }
+                    }
+                    collide = false;
+                }
+                else if (!wasUncontended)       // CAS already known to fail
+                    wasUncontended = true;      // Continue after rehash
+                else if (a.cas(v = a.value, apply(fn, v, x)))
+                    break;
+                else if (n >= NCPU || cells != as)
+                    collide = false;            // At max size or stale
+                else if (!collide)
+                    collide = true;
+                else if (cellsBusy == 0 && casCellsBusy()) {
+                    try {
+                        if (cells == as)        // Expand table unless stale
+                            cells = Arrays.copyOf(as, n << 1);
+                    } finally {
+                        cellsBusy = 0;
+                    }
+                    collide = false;
+                    continue;                   // Retry with expanded table
+                }
+                h = advanceProbe(h);
+            }
+            else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
+                try {                           // Initialize table
+                    if (cells == as) {
+                        Cell[] rs = new Cell[2];
+                        rs[h & 1] = new Cell(Double.doubleToRawLongBits(x));
+                        cells = rs;
+                        break done;
+                    }
+                } finally {
+                    cellsBusy = 0;
+                }
+            }
+            // Fall back on using base
+            else if (casBase(v = base, apply(fn, v, x)))
+                break done;
+        }
+    }
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long BASE;
+    private static final long CELLSBUSY;
+    private static final long PROBE;
+    static {
+        try {
+            BASE = U.objectFieldOffset
+                (Striped64.class.getDeclaredField("base"));
+            CELLSBUSY = U.objectFieldOffset
+                (Striped64.class.getDeclaredField("cellsBusy"));
+
+            PROBE = U.objectFieldOffset
+                (Thread.class.getDeclaredField("threadLocalRandomProbe"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+
+}
diff --git a/luni/src/main/java/java/util/concurrent/atomic/package-info.java b/luni/src/main/java/java/util/concurrent/atomic/package-info.java
index 568d2c6..b19dd49 100644
--- a/luni/src/main/java/java/util/concurrent/atomic/package-info.java
+++ b/luni/src/main/java/java/util/concurrent/atomic/package-info.java
@@ -11,7 +11,7 @@
  * array elements to those that also provide an atomic conditional update
  * operation of the form:
  *
- *  <pre> {@code boolean compareAndSet(expectedValue, updateValue);}</pre>
+ * <pre> {@code boolean compareAndSet(expectedValue, updateValue);}</pre>
  *
  * <p>This method (which varies in argument types across different
  * classes) atomically sets a variable to the {@code updateValue} if it
@@ -38,7 +38,7 @@
  * {@code AtomicInteger} provide atomic increment methods.  One
  * application is to generate sequence numbers, as in:
  *
- *  <pre> {@code
+ * <pre> {@code
  * class Sequencer {
  *   private final AtomicLong sequenceNumber
  *     = new AtomicLong(0);
@@ -53,31 +53,31 @@
  * <pre> {@code long transform(long input)}</pre>
  *
  * write your utility method as follows:
- *  <pre> {@code
+ * <pre> {@code
  * long getAndTransform(AtomicLong var) {
- *   while (true) {
- *     long current = var.get();
- *     long next = transform(current);
- *     if (var.compareAndSet(current, next))
- *         return current;
- *         // return next; for transformAndGet
- *   }
+ *   long prev, next;
+ *   do {
+ *     prev = var.get();
+ *     next = transform(prev);
+ *   } while (!var.compareAndSet(prev, next));
+ *   return prev; // return next; for transformAndGet
  * }}</pre>
  *
  * <p>The memory effects for accesses and updates of atomics generally
  * follow the rules for volatiles, as stated in
- * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4">
- * The Java Language Specification (17.4 Memory Model)</a>:
+ * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
+ * Chapter 17 of
+ * <cite>The Java&trade; Language Specification</cite></a>:
  *
  * <ul>
  *
- *   <li> {@code get} has the memory effects of reading a
+ *   <li>{@code get} has the memory effects of reading a
  * {@code volatile} variable.
  *
- *   <li> {@code set} has the memory effects of writing (assigning) a
+ *   <li>{@code set} has the memory effects of writing (assigning) a
  * {@code volatile} variable.
  *
- *   <li> {@code lazySet} has the memory effects of writing (assigning)
+ *   <li>{@code lazySet} has the memory effects of writing (assigning)
  *   a {@code volatile} variable except that it permits reorderings with
  *   subsequent (but not previous) memory actions that do not themselves
  *   impose reordering constraints with ordinary non-{@code volatile}
@@ -91,7 +91,7 @@
  *   with respect to previous or subsequent reads and writes of any
  *   variables other than the target of the {@code weakCompareAndSet}.
  *
- *   <li> {@code compareAndSet}
+ *   <li>{@code compareAndSet}
  *   and all other read-and-update operations such as {@code getAndIncrement}
  *   have the memory effects of both reading and
  *   writing {@code volatile} variables.
diff --git a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
index a74fb24..3c10805 100644
--- a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
+++ b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
@@ -6,11 +6,11 @@
 
 package java.util.concurrent.locks;
 
-import java.util.concurrent.TimeUnit;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
-import sun.misc.Unsafe;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer.Node;
 
 /**
  * A version of {@link AbstractQueuedSynchronizer} in
@@ -49,221 +49,6 @@
     protected AbstractQueuedLongSynchronizer() { }
 
     /**
-     * Wait queue node class.
-     *
-     * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
-     * Hagersten) lock queue. CLH locks are normally used for
-     * spinlocks.  We instead use them for blocking synchronizers, but
-     * use the same basic tactic of holding some of the control
-     * information about a thread in the predecessor of its node.  A
-     * "status" field in each node keeps track of whether a thread
-     * should block.  A node is signalled when its predecessor
-     * releases.  Each node of the queue otherwise serves as a
-     * specific-notification-style monitor holding a single waiting
-     * thread. The status field does NOT control whether threads are
-     * granted locks etc though.  A thread may try to acquire if it is
-     * first in the queue. But being first does not guarantee success;
-     * it only gives the right to contend.  So the currently released
-     * contender thread may need to rewait.
-     *
-     * <p>To enqueue into a CLH lock, you atomically splice it in as new
-     * tail. To dequeue, you just set the head field.
-     * <pre>
-     *      +------+  prev +-----+       +-----+
-     * head |      | <---- |     | <---- |     |  tail
-     *      +------+       +-----+       +-----+
-     * </pre>
-     *
-     * <p>Insertion into a CLH queue requires only a single atomic
-     * operation on "tail", so there is a simple atomic point of
-     * demarcation from unqueued to queued. Similarly, dequeuing
-     * involves only updating the "head". However, it takes a bit
-     * more work for nodes to determine who their successors are,
-     * in part to deal with possible cancellation due to timeouts
-     * and interrupts.
-     *
-     * <p>The "prev" links (not used in original CLH locks), are mainly
-     * needed to handle cancellation. If a node is cancelled, its
-     * successor is (normally) relinked to a non-cancelled
-     * predecessor. For explanation of similar mechanics in the case
-     * of spin locks, see the papers by Scott and Scherer at
-     * http://www.cs.rochester.edu/u/scott/synchronization/
-     *
-     * <p>We also use "next" links to implement blocking mechanics.
-     * The thread id for each node is kept in its own node, so a
-     * predecessor signals the next node to wake up by traversing
-     * next link to determine which thread it is.  Determination of
-     * successor must avoid races with newly queued nodes to set
-     * the "next" fields of their predecessors.  This is solved
-     * when necessary by checking backwards from the atomically
-     * updated "tail" when a node's successor appears to be null.
-     * (Or, said differently, the next-links are an optimization
-     * so that we don't usually need a backward scan.)
-     *
-     * <p>Cancellation introduces some conservatism to the basic
-     * algorithms.  Since we must poll for cancellation of other
-     * nodes, we can miss noticing whether a cancelled node is
-     * ahead or behind us. This is dealt with by always unparking
-     * successors upon cancellation, allowing them to stabilize on
-     * a new predecessor, unless we can identify an uncancelled
-     * predecessor who will carry this responsibility.
-     *
-     * <p>CLH queues need a dummy header node to get started. But
-     * we don't create them on construction, because it would be wasted
-     * effort if there is never contention. Instead, the node
-     * is constructed and head and tail pointers are set upon first
-     * contention.
-     *
-     * <p>Threads waiting on Conditions use the same nodes, but
-     * use an additional link. Conditions only need to link nodes
-     * in simple (non-concurrent) linked queues because they are
-     * only accessed when exclusively held.  Upon await, a node is
-     * inserted into a condition queue.  Upon signal, the node is
-     * transferred to the main queue.  A special value of status
-     * field is used to mark which queue a node is on.
-     *
-     * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
-     * Scherer and Michael Scott, along with members of JSR-166
-     * expert group, for helpful ideas, discussions, and critiques
-     * on the design of this class.
-     */
-    static final class Node {
-        /** Marker to indicate a node is waiting in shared mode */
-        static final Node SHARED = new Node();
-        /** Marker to indicate a node is waiting in exclusive mode */
-        static final Node EXCLUSIVE = null;
-
-        /** waitStatus value to indicate thread has cancelled */
-        static final int CANCELLED =  1;
-        /** waitStatus value to indicate successor's thread needs unparking */
-        static final int SIGNAL    = -1;
-        /** waitStatus value to indicate thread is waiting on condition */
-        static final int CONDITION = -2;
-        /**
-         * waitStatus value to indicate the next acquireShared should
-         * unconditionally propagate
-         */
-        static final int PROPAGATE = -3;
-
-        /**
-         * Status field, taking on only the values:
-         *   SIGNAL:     The successor of this node is (or will soon be)
-         *               blocked (via park), so the current node must
-         *               unpark its successor when it releases or
-         *               cancels. To avoid races, acquire methods must
-         *               first indicate they need a signal,
-         *               then retry the atomic acquire, and then,
-         *               on failure, block.
-         *   CANCELLED:  This node is cancelled due to timeout or interrupt.
-         *               Nodes never leave this state. In particular,
-         *               a thread with cancelled node never again blocks.
-         *   CONDITION:  This node is currently on a condition queue.
-         *               It will not be used as a sync queue node
-         *               until transferred, at which time the status
-         *               will be set to 0. (Use of this value here has
-         *               nothing to do with the other uses of the
-         *               field, but simplifies mechanics.)
-         *   PROPAGATE:  A releaseShared should be propagated to other
-         *               nodes. This is set (for head node only) in
-         *               doReleaseShared to ensure propagation
-         *               continues, even if other operations have
-         *               since intervened.
-         *   0:          None of the above
-         *
-         * The values are arranged numerically to simplify use.
-         * Non-negative values mean that a node doesn't need to
-         * signal. So, most code doesn't need to check for particular
-         * values, just for sign.
-         *
-         * The field is initialized to 0 for normal sync nodes, and
-         * CONDITION for condition nodes.  It is modified using CAS
-         * (or when possible, unconditional volatile writes).
-         */
-        volatile int waitStatus;
-
-        /**
-         * Link to predecessor node that current node/thread relies on
-         * for checking waitStatus. Assigned during enqueuing, and nulled
-         * out (for sake of GC) only upon dequeuing.  Also, upon
-         * cancellation of a predecessor, we short-circuit while
-         * finding a non-cancelled one, which will always exist
-         * because the head node is never cancelled: A node becomes
-         * head only as a result of successful acquire. A
-         * cancelled thread never succeeds in acquiring, and a thread only
-         * cancels itself, not any other node.
-         */
-        volatile Node prev;
-
-        /**
-         * Link to the successor node that the current node/thread
-         * unparks upon release. Assigned during enqueuing, adjusted
-         * when bypassing cancelled predecessors, and nulled out (for
-         * sake of GC) when dequeued.  The enq operation does not
-         * assign next field of a predecessor until after attachment,
-         * so seeing a null next field does not necessarily mean that
-         * node is at end of queue. However, if a next field appears
-         * to be null, we can scan prev's from the tail to
-         * double-check.  The next field of cancelled nodes is set to
-         * point to the node itself instead of null, to make life
-         * easier for isOnSyncQueue.
-         */
-        volatile Node next;
-
-        /**
-         * The thread that enqueued this node.  Initialized on
-         * construction and nulled out after use.
-         */
-        volatile Thread thread;
-
-        /**
-         * Link to next node waiting on condition, or the special
-         * value SHARED.  Because condition queues are accessed only
-         * when holding in exclusive mode, we just need a simple
-         * linked queue to hold nodes while they are waiting on
-         * conditions. They are then transferred to the queue to
-         * re-acquire. And because conditions can only be exclusive,
-         * we save a field by using special value to indicate shared
-         * mode.
-         */
-        Node nextWaiter;
-
-        /**
-         * Returns true if node is waiting in shared mode.
-         */
-        final boolean isShared() {
-            return nextWaiter == SHARED;
-        }
-
-        /**
-         * Returns previous node, or throws NullPointerException if null.
-         * Use when predecessor cannot be null.  The null check could
-         * be elided, but is present to help the VM.
-         *
-         * @return the predecessor of this node
-         */
-        final Node predecessor() throws NullPointerException {
-            Node p = prev;
-            if (p == null)
-                throw new NullPointerException();
-            else
-                return p;
-        }
-
-        Node() {    // Used to establish initial head or SHARED marker
-        }
-
-        Node(Thread thread, Node mode) {     // Used by addWaiter
-            this.nextWaiter = mode;
-            this.thread = thread;
-        }
-
-        Node(Thread thread, int waitStatus) { // Used by Condition
-            this.waitStatus = waitStatus;
-            this.thread = thread;
-        }
-    }
-
-    /**
      * Head of the wait queue, lazily initialized.  Except for
      * initialization, it is modified only via method setHead.  Note:
      * If head exists, its waitStatus is guaranteed not to be
@@ -297,7 +82,9 @@
      * @param newState the new state value
      */
     protected final void setState(long newState) {
-        state = newState;
+        // Use putLongVolatile instead of ordinary volatile store when
+        // using compareAndSwapLong, for sake of some 32bit systems.
+        U.putLongVolatile(this, STATE, newState);
     }
 
     /**
@@ -308,12 +95,11 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that the actual
+     * @return {@code true} if successful. False return indicates that the actual
      *         value was not equal to the expected value.
      */
     protected final boolean compareAndSetState(long expect, long update) {
-        // See below for intrinsics setup to support this
-        return unsafe.compareAndSwapLong(this, stateOffset, expect, update);
+        return U.compareAndSwapLong(this, STATE, expect, update);
     }
 
     // Queuing utilities
@@ -323,25 +109,24 @@
      * rather than to use timed park. A rough estimate suffices
      * to improve responsiveness with very short timeouts.
      */
-    static final long spinForTimeoutThreshold = 1000L;
+    static final long SPIN_FOR_TIMEOUT_THRESHOLD = 1000L;
 
     /**
      * Inserts node into queue, initializing if necessary. See picture above.
      * @param node the node to insert
      * @return node's predecessor
      */
-    private Node enq(final Node node) {
+    private Node enq(Node node) {
         for (;;) {
-            Node t = tail;
-            if (t == null) { // Must initialize
-                if (compareAndSetHead(new Node()))
-                    tail = head;
-            } else {
-                node.prev = t;
-                if (compareAndSetTail(t, node)) {
-                    t.next = node;
-                    return t;
+            Node oldTail = tail;
+            if (oldTail != null) {
+                U.putObject(node, Node.PREV, oldTail);
+                if (compareAndSetTail(oldTail, node)) {
+                    oldTail.next = node;
+                    return oldTail;
                 }
+            } else {
+                initializeSyncQueue();
             }
         }
     }
@@ -353,18 +138,20 @@
      * @return the new node
      */
     private Node addWaiter(Node mode) {
-        Node node = new Node(Thread.currentThread(), mode);
-        // Try the fast path of enq; backup to full enq on failure
-        Node pred = tail;
-        if (pred != null) {
-            node.prev = pred;
-            if (compareAndSetTail(pred, node)) {
-                pred.next = node;
-                return node;
+        Node node = new Node(mode);
+
+        for (;;) {
+            Node oldTail = tail;
+            if (oldTail != null) {
+                U.putObject(node, Node.PREV, oldTail);
+                if (compareAndSetTail(oldTail, node)) {
+                    oldTail.next = node;
+                    return node;
+                }
+            } else {
+                initializeSyncQueue();
             }
         }
-        enq(node);
-        return node;
     }
 
     /**
@@ -393,7 +180,7 @@
          */
         int ws = node.waitStatus;
         if (ws < 0)
-            compareAndSetWaitStatus(node, ws, 0);
+            node.compareAndSetWaitStatus(ws, 0);
 
         /*
          * Thread to unpark is held in successor, which is normally
@@ -404,7 +191,7 @@
         Node s = node.next;
         if (s == null || s.waitStatus > 0) {
             s = null;
-            for (Node p = tail; p != null && p != node; p = p.prev)
+            for (Node p = tail; p != node && p != null; p = p.prev)
                 if (p.waitStatus <= 0)
                     s = p;
         }
@@ -434,12 +221,12 @@
             if (h != null && h != tail) {
                 int ws = h.waitStatus;
                 if (ws == Node.SIGNAL) {
-                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
+                    if (!h.compareAndSetWaitStatus(Node.SIGNAL, 0))
                         continue;            // loop to recheck cases
                     unparkSuccessor(h);
                 }
                 else if (ws == 0 &&
-                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
+                         !h.compareAndSetWaitStatus(0, Node.PROPAGATE))
                     continue;                // loop on failed CAS
             }
             if (h == head)                   // loop if head changed
@@ -461,7 +248,8 @@
         /*
          * Try to signal next queued node if:
          *   Propagation was indicated by caller,
-         *     or was recorded (as h.waitStatus) by a previous operation
+         *     or was recorded (as h.waitStatus either before
+         *     or after setHead) by a previous operation
          *     (note: this uses sign-check of waitStatus because
          *      PROPAGATE status may transition to SIGNAL.)
          * and
@@ -473,7 +261,8 @@
          * racing acquires/releases, so most need signals now or soon
          * anyway.
          */
-        if (propagate > 0 || h == null || h.waitStatus < 0) {
+        if (propagate > 0 || h == null || h.waitStatus < 0 ||
+            (h = head) == null || h.waitStatus < 0) {
             Node s = node.next;
             if (s == null || s.isShared())
                 doReleaseShared();
@@ -511,18 +300,18 @@
 
         // If we are the tail, remove ourselves.
         if (node == tail && compareAndSetTail(node, pred)) {
-            compareAndSetNext(pred, predNext, null);
+            pred.compareAndSetNext(predNext, null);
         } else {
             // If successor needs signal, try to set pred's next-link
             // so it will get one. Otherwise wake it up to propagate.
             int ws;
             if (pred != head &&
                 ((ws = pred.waitStatus) == Node.SIGNAL ||
-                 (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
+                 (ws <= 0 && pred.compareAndSetWaitStatus(ws, Node.SIGNAL))) &&
                 pred.thread != null) {
                 Node next = node.next;
                 if (next != null && next.waitStatus <= 0)
-                    compareAndSetNext(pred, predNext, next);
+                    pred.compareAndSetNext(predNext, next);
             } else {
                 unparkSuccessor(node);
             }
@@ -563,7 +352,7 @@
              * need a signal, but don't park yet.  Caller will need to
              * retry to make sure it cannot acquire before parking.
              */
-            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
+            pred.compareAndSetWaitStatus(ws, Node.SIGNAL);
         }
         return false;
     }
@@ -576,7 +365,7 @@
     }
 
     /**
-     * Convenience method to park and then check if interrupted
+     * Convenience method to park and then check if interrupted.
      *
      * @return {@code true} if interrupted
      */
@@ -603,7 +392,6 @@
      * @return {@code true} if interrupted while waiting
      */
     final boolean acquireQueued(final Node node, long arg) {
-        boolean failed = true;
         try {
             boolean interrupted = false;
             for (;;) {
@@ -611,16 +399,15 @@
                 if (p == head && tryAcquire(arg)) {
                     setHead(node);
                     p.next = null; // help GC
-                    failed = false;
                     return interrupted;
                 }
                 if (shouldParkAfterFailedAcquire(p, node) &&
                     parkAndCheckInterrupt())
                     interrupted = true;
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -631,23 +418,21 @@
     private void doAcquireInterruptibly(long arg)
         throws InterruptedException {
         final Node node = addWaiter(Node.EXCLUSIVE);
-        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
                 if (p == head && tryAcquire(arg)) {
                     setHead(node);
                     p.next = null; // help GC
-                    failed = false;
                     return;
                 }
                 if (shouldParkAfterFailedAcquire(p, node) &&
                     parkAndCheckInterrupt())
                     throw new InterruptedException();
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -664,28 +449,28 @@
             return false;
         final long deadline = System.nanoTime() + nanosTimeout;
         final Node node = addWaiter(Node.EXCLUSIVE);
-        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
                 if (p == head && tryAcquire(arg)) {
                     setHead(node);
                     p.next = null; // help GC
-                    failed = false;
                     return true;
                 }
                 nanosTimeout = deadline - System.nanoTime();
-                if (nanosTimeout <= 0L)
+                if (nanosTimeout <= 0L) {
+                    cancelAcquire(node);
                     return false;
+                }
                 if (shouldParkAfterFailedAcquire(p, node) &&
-                    nanosTimeout > spinForTimeoutThreshold)
+                    nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanosTimeout);
                 if (Thread.interrupted())
                     throw new InterruptedException();
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -695,7 +480,6 @@
      */
     private void doAcquireShared(long arg) {
         final Node node = addWaiter(Node.SHARED);
-        boolean failed = true;
         try {
             boolean interrupted = false;
             for (;;) {
@@ -707,7 +491,6 @@
                         p.next = null; // help GC
                         if (interrupted)
                             selfInterrupt();
-                        failed = false;
                         return;
                     }
                 }
@@ -715,9 +498,9 @@
                     parkAndCheckInterrupt())
                     interrupted = true;
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -728,7 +511,6 @@
     private void doAcquireSharedInterruptibly(long arg)
         throws InterruptedException {
         final Node node = addWaiter(Node.SHARED);
-        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
@@ -737,7 +519,6 @@
                     if (r >= 0) {
                         setHeadAndPropagate(node, r);
                         p.next = null; // help GC
-                        failed = false;
                         return;
                     }
                 }
@@ -745,9 +526,9 @@
                     parkAndCheckInterrupt())
                     throw new InterruptedException();
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -764,7 +545,6 @@
             return false;
         final long deadline = System.nanoTime() + nanosTimeout;
         final Node node = addWaiter(Node.SHARED);
-        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
@@ -773,22 +553,23 @@
                     if (r >= 0) {
                         setHeadAndPropagate(node, r);
                         p.next = null; // help GC
-                        failed = false;
                         return true;
                     }
                 }
                 nanosTimeout = deadline - System.nanoTime();
-                if (nanosTimeout <= 0L)
+                if (nanosTimeout <= 0L) {
+                    cancelAcquire(node);
                     return false;
+                }
                 if (shouldParkAfterFailedAcquire(p, node) &&
-                    nanosTimeout > spinForTimeoutThreshold)
+                    nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanosTimeout);
                 if (Thread.interrupted())
                     throw new InterruptedException();
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -1112,7 +893,7 @@
 
     /**
      * Queries whether any threads have ever contended to acquire this
-     * synchronizer; that is if an acquire method has ever blocked.
+     * synchronizer; that is, if an acquire method has ever blocked.
      *
      * <p>In this implementation, this operation returns in
      * constant time.
@@ -1140,7 +921,7 @@
     }
 
     /**
-     * Version of getFirstQueuedThread called when fastpath fails
+     * Version of getFirstQueuedThread called when fastpath fails.
      */
     private Thread fullGetFirstQueuedThread() {
         /*
@@ -1167,13 +948,11 @@
          * guaranteeing termination.
          */
 
-        Node t = tail;
         Thread firstThread = null;
-        while (t != null && t != head) {
-            Thread tt = t.thread;
-            if (tt != null)
-                firstThread = tt;
-            t = t.prev;
+        for (Node p = tail; p != null && p != head; p = p.prev) {
+            Thread t = p.thread;
+            if (t != null)
+                firstThread = t;
         }
         return firstThread;
     }
@@ -1220,9 +999,9 @@
      *
      * <p>An invocation of this method is equivalent to (but may be
      * more efficient than):
-     *  <pre> {@code
-     * getFirstQueuedThread() != Thread.currentThread() &&
-     * hasQueuedThreads()}</pre>
+     * <pre> {@code
+     * getFirstQueuedThread() != Thread.currentThread()
+     *   && hasQueuedThreads()}</pre>
      *
      * <p>Note that because cancellations due to interrupts and
      * timeouts may occur at any time, a {@code true} return does not
@@ -1240,7 +1019,7 @@
      * tryAcquire} method for a fair, reentrant, exclusive mode
      * synchronizer might look like this:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * protected boolean tryAcquire(int arg) {
      *   if (isHeldExclusively()) {
      *     // A reentrant acquire; increment hold count
@@ -1276,8 +1055,7 @@
      * acquire.  The value is only an estimate because the number of
      * threads may change dynamically while this method traverses
      * internal data structures.  This method is designed for use in
-     * monitoring system state, not for synchronization
-     * control.
+     * monitoring system state, not for synchronization control.
      *
      * @return the estimated number of threads waiting to acquire
      */
@@ -1302,7 +1080,7 @@
      * @return the collection of threads
      */
     public final Collection<Thread> getQueuedThreads() {
-        ArrayList<Thread> list = new ArrayList<Thread>();
+        ArrayList<Thread> list = new ArrayList<>();
         for (Node p = tail; p != null; p = p.prev) {
             Thread t = p.thread;
             if (t != null)
@@ -1320,7 +1098,7 @@
      * @return the collection of threads
      */
     public final Collection<Thread> getExclusiveQueuedThreads() {
-        ArrayList<Thread> list = new ArrayList<Thread>();
+        ArrayList<Thread> list = new ArrayList<>();
         for (Node p = tail; p != null; p = p.prev) {
             if (!p.isShared()) {
                 Thread t = p.thread;
@@ -1340,7 +1118,7 @@
      * @return the collection of threads
      */
     public final Collection<Thread> getSharedQueuedThreads() {
-        ArrayList<Thread> list = new ArrayList<Thread>();
+        ArrayList<Thread> list = new ArrayList<>();
         for (Node p = tail; p != null; p = p.prev) {
             if (p.isShared()) {
                 Thread t = p.thread;
@@ -1361,10 +1139,9 @@
      * @return a string identifying this synchronizer, as well as its state
      */
     public String toString() {
-        long s = getState();
-        String q  = hasQueuedThreads() ? "non" : "";
-        return super.toString() +
-            "[State = " + s + ", " + q + "empty queue]";
+        return super.toString()
+            + "[State = " + getState() + ", "
+            + (hasQueuedThreads() ? "non" : "") + "empty queue]";
     }
 
 
@@ -1398,8 +1175,10 @@
      * @return true if present
      */
     private boolean findNodeFromTail(Node node) {
-        Node p = tail;
-        for (;;) {
+        // We check for node first, since it's likely to be at or near tail.
+        // tail is known to be non-null, so we could re-order to "save"
+        // one null check, but we leave it this way to help the VM.
+        for (Node p = tail;;) {
             if (p == node)
                 return true;
             if (p == null)
@@ -1419,7 +1198,7 @@
         /*
          * If cannot change waitStatus, the node has been cancelled.
          */
-        if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
+        if (!node.compareAndSetWaitStatus(Node.CONDITION, 0))
             return false;
 
         /*
@@ -1430,7 +1209,7 @@
          */
         Node p = enq(node);
         int ws = p.waitStatus;
-        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
+        if (ws > 0 || !p.compareAndSetWaitStatus(ws, Node.SIGNAL))
             LockSupport.unpark(node.thread);
         return true;
     }
@@ -1443,7 +1222,7 @@
      * @return true if cancelled before the node was signalled
      */
     final boolean transferAfterCancelledWait(Node node) {
-        if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
+        if (node.compareAndSetWaitStatus(Node.CONDITION, 0)) {
             enq(node);
             return true;
         }
@@ -1465,18 +1244,14 @@
      * @return previous sync state
      */
     final long fullyRelease(Node node) {
-        boolean failed = true;
         try {
             long savedState = getState();
-            if (release(savedState)) {
-                failed = false;
+            if (release(savedState))
                 return savedState;
-            } else {
-                throw new IllegalMonitorStateException();
-            }
-        } finally {
-            if (failed)
-                node.waitStatus = Node.CANCELLED;
+            throw new IllegalMonitorStateException();
+        } catch (Throwable t) {
+            node.waitStatus = Node.CANCELLED;
+            throw t;
         }
     }
 
@@ -1521,8 +1296,8 @@
      * given condition associated with this synchronizer. Note that
      * because timeouts and interrupts may occur at any time, the
      * estimate serves only as an upper bound on the actual number of
-     * waiters.  This method is designed for use in monitoring of the
-     * system state, not for synchronization control.
+     * waiters.  This method is designed for use in monitoring system
+     * state, not for synchronization control.
      *
      * @param condition the condition
      * @return the estimated number of waiting threads
@@ -1602,7 +1377,9 @@
                 unlinkCancelledWaiters();
                 t = lastWaiter;
             }
-            Node node = new Node(Thread.currentThread(), Node.CONDITION);
+
+            Node node = new Node(Node.CONDITION);
+
             if (t == null)
                 firstWaiter = node;
             else
@@ -1710,12 +1487,12 @@
         /**
          * Implements uninterruptible condition wait.
          * <ol>
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
          * </ol>
          */
         public final void awaitUninterruptibly() {
@@ -1769,14 +1546,14 @@
         /**
          * Implements interruptible condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException.
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled or interrupted.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * <li>If current thread is interrupted, throw InterruptedException.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled or interrupted.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
+         * <li>If interrupted while blocked in step 4, throw InterruptedException.
          * </ol>
          */
         public final void await() throws InterruptedException {
@@ -1801,31 +1578,33 @@
         /**
          * Implements timed condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException.
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled, interrupted, or timed out.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * <li>If current thread is interrupted, throw InterruptedException.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled, interrupted, or timed out.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
+         * <li>If interrupted while blocked in step 4, throw InterruptedException.
          * </ol>
          */
         public final long awaitNanos(long nanosTimeout)
                 throws InterruptedException {
             if (Thread.interrupted())
                 throw new InterruptedException();
+            // We don't check for nanosTimeout <= 0L here, to allow
+            // awaitNanos(0) as a way to "yield the lock".
+            final long deadline = System.nanoTime() + nanosTimeout;
             long initialNanos = nanosTimeout;
             Node node = addConditionWaiter();
             long savedState = fullyRelease(node);
-            final long deadline = System.nanoTime() + nanosTimeout;
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
                 if (nanosTimeout <= 0L) {
                     transferAfterCancelledWait(node);
                     break;
                 }
-                if (nanosTimeout >= spinForTimeoutThreshold)
+                if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanosTimeout);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
@@ -1838,24 +1617,21 @@
             if (interruptMode != 0)
                 reportInterruptAfterWait(interruptMode);
             long remaining = deadline - System.nanoTime(); // avoid overflow
-            // BEGIN android-note Changed from < to <= http://b/24284239
-            // return (remaining < initialNanos) ? remaining : Long.MIN_VALUE;
             return (remaining <= initialNanos) ? remaining : Long.MIN_VALUE;
-            // END android-note
         }
 
         /**
          * Implements absolute timed condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException.
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled, interrupted, or timed out.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException.
-         * <li> If timed out while blocked in step 4, return false, else true.
+         * <li>If current thread is interrupted, throw InterruptedException.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled, interrupted, or timed out.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
+         * <li>If interrupted while blocked in step 4, throw InterruptedException.
+         * <li>If timed out while blocked in step 4, return false, else true.
          * </ol>
          */
         public final boolean awaitUntil(Date deadline)
@@ -1868,7 +1644,7 @@
             boolean timedout = false;
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
-                if (System.currentTimeMillis() > abstime) {
+                if (System.currentTimeMillis() >= abstime) {
                     timedout = transferAfterCancelledWait(node);
                     break;
                 }
@@ -1888,15 +1664,15 @@
         /**
          * Implements timed condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException.
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled, interrupted, or timed out.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException.
-         * <li> If timed out while blocked in step 4, return false, else true.
+         * <li>If current thread is interrupted, throw InterruptedException.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled, interrupted, or timed out.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
+         * <li>If interrupted while blocked in step 4, throw InterruptedException.
+         * <li>If timed out while blocked in step 4, return false, else true.
          * </ol>
          */
         public final boolean await(long time, TimeUnit unit)
@@ -1904,9 +1680,11 @@
             long nanosTimeout = unit.toNanos(time);
             if (Thread.interrupted())
                 throw new InterruptedException();
+            // We don't check for nanosTimeout <= 0L here, to allow
+            // await(0, unit) as a way to "yield the lock".
+            final long deadline = System.nanoTime() + nanosTimeout;
             Node node = addConditionWaiter();
             long savedState = fullyRelease(node);
-            final long deadline = System.nanoTime() + nanosTimeout;
             boolean timedout = false;
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
@@ -1914,7 +1692,7 @@
                     timedout = transferAfterCancelledWait(node);
                     break;
                 }
-                if (nanosTimeout >= spinForTimeoutThreshold)
+                if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanosTimeout);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
@@ -1943,7 +1721,7 @@
 
         /**
          * Queries whether any threads are waiting on this condition.
-         * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters}.
+         * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters(ConditionObject)}.
          *
          * @return {@code true} if there are any waiting threads
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
@@ -1962,7 +1740,7 @@
         /**
          * Returns an estimate of the number of threads waiting on
          * this condition.
-         * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength}.
+         * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength(ConditionObject)}.
          *
          * @return the estimated number of waiting threads
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
@@ -1982,7 +1760,7 @@
         /**
          * Returns a collection containing those threads that may be
          * waiting on this Condition.
-         * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads}.
+         * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads(ConditionObject)}.
          *
          * @return the collection of threads
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
@@ -1991,7 +1769,7 @@
         protected final Collection<Thread> getWaitingThreads() {
             if (!isHeldExclusively())
                 throw new IllegalMonitorStateException();
-            ArrayList<Thread> list = new ArrayList<Thread>();
+            ArrayList<Thread> list = new ArrayList<>();
             for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                 if (w.waitStatus == Node.CONDITION) {
                     Thread t = w.thread;
@@ -2012,27 +1790,22 @@
      * are at it, we do the same for other CASable fields (which could
      * otherwise be done with atomic field updaters).
      */
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final long stateOffset;
-    private static final long headOffset;
-    private static final long tailOffset;
-    private static final long waitStatusOffset;
-    private static final long nextOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long STATE;
+    private static final long HEAD;
+    private static final long TAIL;
 
     static {
         try {
-            stateOffset = unsafe.objectFieldOffset
+            STATE = U.objectFieldOffset
                 (AbstractQueuedLongSynchronizer.class.getDeclaredField("state"));
-            headOffset = unsafe.objectFieldOffset
+            HEAD = U.objectFieldOffset
                 (AbstractQueuedLongSynchronizer.class.getDeclaredField("head"));
-            tailOffset = unsafe.objectFieldOffset
+            TAIL = U.objectFieldOffset
                 (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail"));
-            waitStatusOffset = unsafe.objectFieldOffset
-                (Node.class.getDeclaredField("waitStatus"));
-            nextOffset = unsafe.objectFieldOffset
-                (Node.class.getDeclaredField("next"));
-
-        } catch (Exception ex) { throw new Error(ex); }
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
 
         // Reduce the risk of rare disastrous classloading in first call to
         // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
@@ -2040,35 +1813,18 @@
     }
 
     /**
-     * CAS head field. Used only by enq.
+     * Initializes head and tail fields on first contention.
      */
-    private final boolean compareAndSetHead(Node update) {
-        return unsafe.compareAndSwapObject(this, headOffset, null, update);
+    private final void initializeSyncQueue() {
+        Node h;
+        if (U.compareAndSwapObject(this, HEAD, null, (h = new Node())))
+            tail = h;
     }
 
     /**
-     * CAS tail field. Used only by enq.
+     * CASes tail field.
      */
     private final boolean compareAndSetTail(Node expect, Node update) {
-        return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
-    }
-
-    /**
-     * CAS waitStatus field of a node.
-     */
-    private static final boolean compareAndSetWaitStatus(Node node,
-                                                         int expect,
-                                                         int update) {
-        return unsafe.compareAndSwapInt(node, waitStatusOffset,
-                                        expect, update);
-    }
-
-    /**
-     * CAS next field of a node.
-     */
-    private static final boolean compareAndSetNext(Node node,
-                                                   Node expect,
-                                                   Node update) {
-        return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
+        return U.compareAndSwapObject(this, TAIL, expect, update);
     }
 }
diff --git a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
index 8823b6f..2c41000 100644
--- a/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
+++ b/luni/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -6,15 +6,11 @@
 
 package java.util.concurrent.locks;
 
-import java.util.concurrent.TimeUnit;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
-import sun.misc.Unsafe;
-
-// BEGIN android-note
-// Use older class level documentation to not @link to hasQueuedPredecessors
-// END android-changed
+import java.util.concurrent.TimeUnit;
+/// OPENJDK-9 import jdk.internal.vm.annotation.ReservedStackAccess;
 
 /**
  * Provides a framework for implementing blocking locks and related
@@ -86,11 +82,11 @@
  * #setState} and/or {@link #compareAndSetState}:
  *
  * <ul>
- * <li> {@link #tryAcquire}
- * <li> {@link #tryRelease}
- * <li> {@link #tryAcquireShared}
- * <li> {@link #tryReleaseShared}
- * <li> {@link #isHeldExclusively}
+ * <li>{@link #tryAcquire}
+ * <li>{@link #tryRelease}
+ * <li>{@link #tryAcquireShared}
+ * <li>{@link #tryReleaseShared}
+ * <li>{@link #isHeldExclusively}
  * </ul>
  *
  * Each of these methods by default throws {@link
@@ -131,7 +127,7 @@
  * disable barging by internally invoking one or more of the inspection
  * methods, thereby providing a <em>fair</em> FIFO acquisition order.
  * In particular, most fair synchronizers can define {@code tryAcquire}
- * to return {@code false} if {@code hasQueuedPredecessors} (a method
+ * to return {@code false} if {@link #hasQueuedPredecessors} (a method
  * specifically designed to be used by fair synchronizers) returns
  * {@code true}.  Other variations are possible.
  *
@@ -171,7 +167,7 @@
  * It also supports conditions and exposes
  * one of the instrumentation methods:
  *
- *  <pre> {@code
+ * <pre> {@code
  * class Mutex implements Lock, java.io.Serializable {
  *
  *   // Our internal helper class
@@ -235,7 +231,7 @@
  * fire. Because a latch is non-exclusive, it uses the {@code shared}
  * acquire and release methods.
  *
- *  <pre> {@code
+ * <pre> {@code
  * class BooleanLatch {
  *
  *   private static class Sync extends AbstractQueuedSynchronizer {
@@ -359,15 +355,15 @@
         /** Marker to indicate a node is waiting in exclusive mode */
         static final Node EXCLUSIVE = null;
 
-        /** waitStatus value to indicate thread has cancelled */
+        /** waitStatus value to indicate thread has cancelled. */
         static final int CANCELLED =  1;
-        /** waitStatus value to indicate successor's thread needs unparking */
+        /** waitStatus value to indicate successor's thread needs unparking. */
         static final int SIGNAL    = -1;
-        /** waitStatus value to indicate thread is waiting on condition */
+        /** waitStatus value to indicate thread is waiting on condition. */
         static final int CONDITION = -2;
         /**
          * waitStatus value to indicate the next acquireShared should
-         * unconditionally propagate
+         * unconditionally propagate.
          */
         static final int PROPAGATE = -3;
 
@@ -475,17 +471,49 @@
                 return p;
         }
 
-        Node() {    // Used to establish initial head or SHARED marker
+        /** Establishes initial head or SHARED marker. */
+        Node() {}
+
+        /** Constructor used by addWaiter. */
+        Node(Node nextWaiter) {
+            this.nextWaiter = nextWaiter;
+            U.putObject(this, THREAD, Thread.currentThread());
         }
 
-        Node(Thread thread, Node mode) {     // Used by addWaiter
-            this.nextWaiter = mode;
-            this.thread = thread;
+        /** Constructor used by addConditionWaiter. */
+        Node(int waitStatus) {
+            U.putInt(this, WAITSTATUS, waitStatus);
+            U.putObject(this, THREAD, Thread.currentThread());
         }
 
-        Node(Thread thread, int waitStatus) { // Used by Condition
-            this.waitStatus = waitStatus;
-            this.thread = thread;
+        /** CASes waitStatus field. */
+        final boolean compareAndSetWaitStatus(int expect, int update) {
+            return U.compareAndSwapInt(this, WAITSTATUS, expect, update);
+        }
+
+        /** CASes next field. */
+        final boolean compareAndSetNext(Node expect, Node update) {
+            return U.compareAndSwapObject(this, NEXT, expect, update);
+        }
+
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final long NEXT;
+        static final long PREV;
+        private static final long THREAD;
+        private static final long WAITSTATUS;
+        static {
+            try {
+                NEXT = U.objectFieldOffset
+                    (Node.class.getDeclaredField("next"));
+                PREV = U.objectFieldOffset
+                    (Node.class.getDeclaredField("prev"));
+                THREAD = U.objectFieldOffset
+                    (Node.class.getDeclaredField("thread"));
+                WAITSTATUS = U.objectFieldOffset
+                    (Node.class.getDeclaredField("waitStatus"));
+            } catch (ReflectiveOperationException e) {
+                throw new Error(e);
+            }
         }
     }
 
@@ -534,12 +562,11 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that the actual
+     * @return {@code true} if successful. False return indicates that the actual
      *         value was not equal to the expected value.
      */
     protected final boolean compareAndSetState(int expect, int update) {
-        // See below for intrinsics setup to support this
-        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
+        return U.compareAndSwapInt(this, STATE, expect, update);
     }
 
     // Queuing utilities
@@ -549,25 +576,24 @@
      * rather than to use timed park. A rough estimate suffices
      * to improve responsiveness with very short timeouts.
      */
-    static final long spinForTimeoutThreshold = 1000L;
+    static final long SPIN_FOR_TIMEOUT_THRESHOLD = 1000L;
 
     /**
      * Inserts node into queue, initializing if necessary. See picture above.
      * @param node the node to insert
      * @return node's predecessor
      */
-    private Node enq(final Node node) {
+    private Node enq(Node node) {
         for (;;) {
-            Node t = tail;
-            if (t == null) { // Must initialize
-                if (compareAndSetHead(new Node()))
-                    tail = head;
-            } else {
-                node.prev = t;
-                if (compareAndSetTail(t, node)) {
-                    t.next = node;
-                    return t;
+            Node oldTail = tail;
+            if (oldTail != null) {
+                U.putObject(node, Node.PREV, oldTail);
+                if (compareAndSetTail(oldTail, node)) {
+                    oldTail.next = node;
+                    return oldTail;
                 }
+            } else {
+                initializeSyncQueue();
             }
         }
     }
@@ -579,18 +605,20 @@
      * @return the new node
      */
     private Node addWaiter(Node mode) {
-        Node node = new Node(Thread.currentThread(), mode);
-        // Try the fast path of enq; backup to full enq on failure
-        Node pred = tail;
-        if (pred != null) {
-            node.prev = pred;
-            if (compareAndSetTail(pred, node)) {
-                pred.next = node;
-                return node;
+        Node node = new Node(mode);
+
+        for (;;) {
+            Node oldTail = tail;
+            if (oldTail != null) {
+                U.putObject(node, Node.PREV, oldTail);
+                if (compareAndSetTail(oldTail, node)) {
+                    oldTail.next = node;
+                    return node;
+                }
+            } else {
+                initializeSyncQueue();
             }
         }
-        enq(node);
-        return node;
     }
 
     /**
@@ -619,7 +647,7 @@
          */
         int ws = node.waitStatus;
         if (ws < 0)
-            compareAndSetWaitStatus(node, ws, 0);
+            node.compareAndSetWaitStatus(ws, 0);
 
         /*
          * Thread to unpark is held in successor, which is normally
@@ -630,9 +658,9 @@
         Node s = node.next;
         if (s == null || s.waitStatus > 0) {
             s = null;
-            for (Node t = tail; t != null && t != node; t = t.prev)
-                if (t.waitStatus <= 0)
-                    s = t;
+            for (Node p = tail; p != node && p != null; p = p.prev)
+                if (p.waitStatus <= 0)
+                    s = p;
         }
         if (s != null)
             LockSupport.unpark(s.thread);
@@ -660,12 +688,12 @@
             if (h != null && h != tail) {
                 int ws = h.waitStatus;
                 if (ws == Node.SIGNAL) {
-                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
+                    if (!h.compareAndSetWaitStatus(Node.SIGNAL, 0))
                         continue;            // loop to recheck cases
                     unparkSuccessor(h);
                 }
                 else if (ws == 0 &&
-                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
+                         !h.compareAndSetWaitStatus(0, Node.PROPAGATE))
                     continue;                // loop on failed CAS
             }
             if (h == head)                   // loop if head changed
@@ -687,7 +715,8 @@
         /*
          * Try to signal next queued node if:
          *   Propagation was indicated by caller,
-         *     or was recorded (as h.waitStatus) by a previous operation
+         *     or was recorded (as h.waitStatus either before
+         *     or after setHead) by a previous operation
          *     (note: this uses sign-check of waitStatus because
          *      PROPAGATE status may transition to SIGNAL.)
          * and
@@ -699,7 +728,8 @@
          * racing acquires/releases, so most need signals now or soon
          * anyway.
          */
-        if (propagate > 0 || h == null || h.waitStatus < 0) {
+        if (propagate > 0 || h == null || h.waitStatus < 0 ||
+            (h = head) == null || h.waitStatus < 0) {
             Node s = node.next;
             if (s == null || s.isShared())
                 doReleaseShared();
@@ -737,18 +767,18 @@
 
         // If we are the tail, remove ourselves.
         if (node == tail && compareAndSetTail(node, pred)) {
-            compareAndSetNext(pred, predNext, null);
+            pred.compareAndSetNext(predNext, null);
         } else {
             // If successor needs signal, try to set pred's next-link
             // so it will get one. Otherwise wake it up to propagate.
             int ws;
             if (pred != head &&
                 ((ws = pred.waitStatus) == Node.SIGNAL ||
-                 (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
+                 (ws <= 0 && pred.compareAndSetWaitStatus(ws, Node.SIGNAL))) &&
                 pred.thread != null) {
                 Node next = node.next;
                 if (next != null && next.waitStatus <= 0)
-                    compareAndSetNext(pred, predNext, next);
+                    pred.compareAndSetNext(predNext, next);
             } else {
                 unparkSuccessor(node);
             }
@@ -789,7 +819,7 @@
              * need a signal, but don't park yet.  Caller will need to
              * retry to make sure it cannot acquire before parking.
              */
-            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
+            pred.compareAndSetWaitStatus(ws, Node.SIGNAL);
         }
         return false;
     }
@@ -802,7 +832,7 @@
     }
 
     /**
-     * Convenience method to park and then check if interrupted
+     * Convenience method to park and then check if interrupted.
      *
      * @return {@code true} if interrupted
      */
@@ -828,8 +858,8 @@
      * @param arg the acquire argument
      * @return {@code true} if interrupted while waiting
      */
+/// OPENJDK-9     @ReservedStackAccess
     final boolean acquireQueued(final Node node, int arg) {
-        boolean failed = true;
         try {
             boolean interrupted = false;
             for (;;) {
@@ -837,16 +867,15 @@
                 if (p == head && tryAcquire(arg)) {
                     setHead(node);
                     p.next = null; // help GC
-                    failed = false;
                     return interrupted;
                 }
                 if (shouldParkAfterFailedAcquire(p, node) &&
                     parkAndCheckInterrupt())
                     interrupted = true;
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -857,23 +886,21 @@
     private void doAcquireInterruptibly(int arg)
         throws InterruptedException {
         final Node node = addWaiter(Node.EXCLUSIVE);
-        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
                 if (p == head && tryAcquire(arg)) {
                     setHead(node);
                     p.next = null; // help GC
-                    failed = false;
                     return;
                 }
                 if (shouldParkAfterFailedAcquire(p, node) &&
                     parkAndCheckInterrupt())
                     throw new InterruptedException();
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -890,28 +917,28 @@
             return false;
         final long deadline = System.nanoTime() + nanosTimeout;
         final Node node = addWaiter(Node.EXCLUSIVE);
-        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
                 if (p == head && tryAcquire(arg)) {
                     setHead(node);
                     p.next = null; // help GC
-                    failed = false;
                     return true;
                 }
                 nanosTimeout = deadline - System.nanoTime();
-                if (nanosTimeout <= 0L)
+                if (nanosTimeout <= 0L) {
+                    cancelAcquire(node);
                     return false;
+                }
                 if (shouldParkAfterFailedAcquire(p, node) &&
-                    nanosTimeout > spinForTimeoutThreshold)
+                    nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanosTimeout);
                 if (Thread.interrupted())
                     throw new InterruptedException();
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -921,7 +948,6 @@
      */
     private void doAcquireShared(int arg) {
         final Node node = addWaiter(Node.SHARED);
-        boolean failed = true;
         try {
             boolean interrupted = false;
             for (;;) {
@@ -933,7 +959,6 @@
                         p.next = null; // help GC
                         if (interrupted)
                             selfInterrupt();
-                        failed = false;
                         return;
                     }
                 }
@@ -941,9 +966,9 @@
                     parkAndCheckInterrupt())
                     interrupted = true;
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -954,7 +979,6 @@
     private void doAcquireSharedInterruptibly(int arg)
         throws InterruptedException {
         final Node node = addWaiter(Node.SHARED);
-        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
@@ -963,7 +987,6 @@
                     if (r >= 0) {
                         setHeadAndPropagate(node, r);
                         p.next = null; // help GC
-                        failed = false;
                         return;
                     }
                 }
@@ -971,9 +994,9 @@
                     parkAndCheckInterrupt())
                     throw new InterruptedException();
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -990,7 +1013,6 @@
             return false;
         final long deadline = System.nanoTime() + nanosTimeout;
         final Node node = addWaiter(Node.SHARED);
-        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
@@ -999,22 +1021,23 @@
                     if (r >= 0) {
                         setHeadAndPropagate(node, r);
                         p.next = null; // help GC
-                        failed = false;
                         return true;
                     }
                 }
                 nanosTimeout = deadline - System.nanoTime();
-                if (nanosTimeout <= 0L)
+                if (nanosTimeout <= 0L) {
+                    cancelAcquire(node);
                     return false;
+                }
                 if (shouldParkAfterFailedAcquire(p, node) &&
-                    nanosTimeout > spinForTimeoutThreshold)
+                    nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanosTimeout);
                 if (Thread.interrupted())
                     throw new InterruptedException();
             }
-        } finally {
-            if (failed)
-                cancelAcquire(node);
+        } catch (Throwable t) {
+            cancelAcquire(node);
+            throw t;
         }
     }
 
@@ -1168,6 +1191,7 @@
      *        {@link #tryAcquire} but is otherwise uninterpreted and
      *        can represent anything you like.
      */
+/// OPENJDK-9     @ReservedStackAccess
     public final void acquire(int arg) {
         if (!tryAcquire(arg) &&
             acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
@@ -1231,6 +1255,7 @@
      *        can represent anything you like.
      * @return the value returned from {@link #tryRelease}
      */
+/// OPENJDK-9     @ReservedStackAccess
     public final boolean release(int arg) {
         if (tryRelease(arg)) {
             Node h = head;
@@ -1311,6 +1336,7 @@
      *        and can represent anything you like.
      * @return the value returned from {@link #tryReleaseShared}
      */
+/// OPENJDK-9     @ReservedStackAccess
     public final boolean releaseShared(int arg) {
         if (tryReleaseShared(arg)) {
             doReleaseShared();
@@ -1338,7 +1364,7 @@
 
     /**
      * Queries whether any threads have ever contended to acquire this
-     * synchronizer; that is if an acquire method has ever blocked.
+     * synchronizer; that is, if an acquire method has ever blocked.
      *
      * <p>In this implementation, this operation returns in
      * constant time.
@@ -1366,7 +1392,7 @@
     }
 
     /**
-     * Version of getFirstQueuedThread called when fastpath fails
+     * Version of getFirstQueuedThread called when fastpath fails.
      */
     private Thread fullGetFirstQueuedThread() {
         /*
@@ -1393,13 +1419,11 @@
          * guaranteeing termination.
          */
 
-        Node t = tail;
         Thread firstThread = null;
-        while (t != null && t != head) {
-            Thread tt = t.thread;
-            if (tt != null)
-                firstThread = tt;
-            t = t.prev;
+        for (Node p = tail; p != null && p != head; p = p.prev) {
+            Thread t = p.thread;
+            if (t != null)
+                firstThread = t;
         }
         return firstThread;
     }
@@ -1446,9 +1470,9 @@
      *
      * <p>An invocation of this method is equivalent to (but may be
      * more efficient than):
-     *  <pre> {@code
-     * getFirstQueuedThread() != Thread.currentThread() &&
-     * hasQueuedThreads()}</pre>
+     * <pre> {@code
+     * getFirstQueuedThread() != Thread.currentThread()
+     *   && hasQueuedThreads()}</pre>
      *
      * <p>Note that because cancellations due to interrupts and
      * timeouts may occur at any time, a {@code true} return does not
@@ -1466,7 +1490,7 @@
      * tryAcquire} method for a fair, reentrant, exclusive mode
      * synchronizer might look like this:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * protected boolean tryAcquire(int arg) {
      *   if (isHeldExclusively()) {
      *     // A reentrant acquire; increment hold count
@@ -1502,8 +1526,7 @@
      * acquire.  The value is only an estimate because the number of
      * threads may change dynamically while this method traverses
      * internal data structures.  This method is designed for use in
-     * monitoring system state, not for synchronization
-     * control.
+     * monitoring system state, not for synchronization control.
      *
      * @return the estimated number of threads waiting to acquire
      */
@@ -1528,7 +1551,7 @@
      * @return the collection of threads
      */
     public final Collection<Thread> getQueuedThreads() {
-        ArrayList<Thread> list = new ArrayList<Thread>();
+        ArrayList<Thread> list = new ArrayList<>();
         for (Node p = tail; p != null; p = p.prev) {
             Thread t = p.thread;
             if (t != null)
@@ -1546,7 +1569,7 @@
      * @return the collection of threads
      */
     public final Collection<Thread> getExclusiveQueuedThreads() {
-        ArrayList<Thread> list = new ArrayList<Thread>();
+        ArrayList<Thread> list = new ArrayList<>();
         for (Node p = tail; p != null; p = p.prev) {
             if (!p.isShared()) {
                 Thread t = p.thread;
@@ -1566,7 +1589,7 @@
      * @return the collection of threads
      */
     public final Collection<Thread> getSharedQueuedThreads() {
-        ArrayList<Thread> list = new ArrayList<Thread>();
+        ArrayList<Thread> list = new ArrayList<>();
         for (Node p = tail; p != null; p = p.prev) {
             if (p.isShared()) {
                 Thread t = p.thread;
@@ -1587,10 +1610,9 @@
      * @return a string identifying this synchronizer, as well as its state
      */
     public String toString() {
-        int s = getState();
-        String q  = hasQueuedThreads() ? "non" : "";
-        return super.toString() +
-            "[State = " + s + ", " + q + "empty queue]";
+        return super.toString()
+            + "[State = " + getState() + ", "
+            + (hasQueuedThreads() ? "non" : "") + "empty queue]";
     }
 
 
@@ -1624,13 +1646,15 @@
      * @return true if present
      */
     private boolean findNodeFromTail(Node node) {
-        Node t = tail;
-        for (;;) {
-            if (t == node)
+        // We check for node first, since it's likely to be at or near tail.
+        // tail is known to be non-null, so we could re-order to "save"
+        // one null check, but we leave it this way to help the VM.
+        for (Node p = tail;;) {
+            if (p == node)
                 return true;
-            if (t == null)
+            if (p == null)
                 return false;
-            t = t.prev;
+            p = p.prev;
         }
     }
 
@@ -1645,7 +1669,7 @@
         /*
          * If cannot change waitStatus, the node has been cancelled.
          */
-        if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
+        if (!node.compareAndSetWaitStatus(Node.CONDITION, 0))
             return false;
 
         /*
@@ -1656,7 +1680,7 @@
          */
         Node p = enq(node);
         int ws = p.waitStatus;
-        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
+        if (ws > 0 || !p.compareAndSetWaitStatus(ws, Node.SIGNAL))
             LockSupport.unpark(node.thread);
         return true;
     }
@@ -1669,7 +1693,7 @@
      * @return true if cancelled before the node was signalled
      */
     final boolean transferAfterCancelledWait(Node node) {
-        if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
+        if (node.compareAndSetWaitStatus(Node.CONDITION, 0)) {
             enq(node);
             return true;
         }
@@ -1691,18 +1715,14 @@
      * @return previous sync state
      */
     final int fullyRelease(Node node) {
-        boolean failed = true;
         try {
             int savedState = getState();
-            if (release(savedState)) {
-                failed = false;
+            if (release(savedState))
                 return savedState;
-            } else {
-                throw new IllegalMonitorStateException();
-            }
-        } finally {
-            if (failed)
-                node.waitStatus = Node.CANCELLED;
+            throw new IllegalMonitorStateException();
+        } catch (Throwable t) {
+            node.waitStatus = Node.CANCELLED;
+            throw t;
         }
     }
 
@@ -1747,8 +1767,8 @@
      * given condition associated with this synchronizer. Note that
      * because timeouts and interrupts may occur at any time, the
      * estimate serves only as an upper bound on the actual number of
-     * waiters.  This method is designed for use in monitoring of the
-     * system state, not for synchronization control.
+     * waiters.  This method is designed for use in monitoring system
+     * state, not for synchronization control.
      *
      * @param condition the condition
      * @return the estimated number of waiting threads
@@ -1826,7 +1846,9 @@
                 unlinkCancelledWaiters();
                 t = lastWaiter;
             }
-            Node node = new Node(Thread.currentThread(), Node.CONDITION);
+
+            Node node = new Node(Node.CONDITION);
+
             if (t == null)
                 firstWaiter = node;
             else
@@ -1934,12 +1956,12 @@
         /**
          * Implements uninterruptible condition wait.
          * <ol>
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
          * </ol>
          */
         public final void awaitUninterruptibly() {
@@ -1993,14 +2015,14 @@
         /**
          * Implements interruptible condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException.
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled or interrupted.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * <li>If current thread is interrupted, throw InterruptedException.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled or interrupted.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
+         * <li>If interrupted while blocked in step 4, throw InterruptedException.
          * </ol>
          */
         public final void await() throws InterruptedException {
@@ -2025,31 +2047,33 @@
         /**
          * Implements timed condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException.
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled, interrupted, or timed out.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * <li>If current thread is interrupted, throw InterruptedException.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled, interrupted, or timed out.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
+         * <li>If interrupted while blocked in step 4, throw InterruptedException.
          * </ol>
          */
         public final long awaitNanos(long nanosTimeout)
                 throws InterruptedException {
             if (Thread.interrupted())
                 throw new InterruptedException();
+            // We don't check for nanosTimeout <= 0L here, to allow
+            // awaitNanos(0) as a way to "yield the lock".
+            final long deadline = System.nanoTime() + nanosTimeout;
             long initialNanos = nanosTimeout;
             Node node = addConditionWaiter();
             int savedState = fullyRelease(node);
-            final long deadline = System.nanoTime() + nanosTimeout;
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
                 if (nanosTimeout <= 0L) {
                     transferAfterCancelledWait(node);
                     break;
                 }
-                if (nanosTimeout >= spinForTimeoutThreshold)
+                if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanosTimeout);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
@@ -2062,24 +2086,21 @@
             if (interruptMode != 0)
                 reportInterruptAfterWait(interruptMode);
             long remaining = deadline - System.nanoTime(); // avoid overflow
-            // BEGIN android-note Changed from < to <= http://b/24284239
-            // return (remaining < initialNanos) ? remaining : Long.MIN_VALUE;
             return (remaining <= initialNanos) ? remaining : Long.MIN_VALUE;
-            // END android-note
         }
 
         /**
          * Implements absolute timed condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException.
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled, interrupted, or timed out.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException.
-         * <li> If timed out while blocked in step 4, return false, else true.
+         * <li>If current thread is interrupted, throw InterruptedException.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled, interrupted, or timed out.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
+         * <li>If interrupted while blocked in step 4, throw InterruptedException.
+         * <li>If timed out while blocked in step 4, return false, else true.
          * </ol>
          */
         public final boolean awaitUntil(Date deadline)
@@ -2092,7 +2113,7 @@
             boolean timedout = false;
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
-                if (System.currentTimeMillis() > abstime) {
+                if (System.currentTimeMillis() >= abstime) {
                     timedout = transferAfterCancelledWait(node);
                     break;
                 }
@@ -2112,15 +2133,15 @@
         /**
          * Implements timed condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException.
-         * <li> Save lock state returned by {@link #getState}.
-         * <li> Invoke {@link #release} with saved state as argument,
-         *      throwing IllegalMonitorStateException if it fails.
-         * <li> Block until signalled, interrupted, or timed out.
-         * <li> Reacquire by invoking specialized version of
-         *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException.
-         * <li> If timed out while blocked in step 4, return false, else true.
+         * <li>If current thread is interrupted, throw InterruptedException.
+         * <li>Save lock state returned by {@link #getState}.
+         * <li>Invoke {@link #release} with saved state as argument,
+         *     throwing IllegalMonitorStateException if it fails.
+         * <li>Block until signalled, interrupted, or timed out.
+         * <li>Reacquire by invoking specialized version of
+         *     {@link #acquire} with saved state as argument.
+         * <li>If interrupted while blocked in step 4, throw InterruptedException.
+         * <li>If timed out while blocked in step 4, return false, else true.
          * </ol>
          */
         public final boolean await(long time, TimeUnit unit)
@@ -2128,9 +2149,11 @@
             long nanosTimeout = unit.toNanos(time);
             if (Thread.interrupted())
                 throw new InterruptedException();
+            // We don't check for nanosTimeout <= 0L here, to allow
+            // await(0, unit) as a way to "yield the lock".
+            final long deadline = System.nanoTime() + nanosTimeout;
             Node node = addConditionWaiter();
             int savedState = fullyRelease(node);
-            final long deadline = System.nanoTime() + nanosTimeout;
             boolean timedout = false;
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
@@ -2138,7 +2161,7 @@
                     timedout = transferAfterCancelledWait(node);
                     break;
                 }
-                if (nanosTimeout >= spinForTimeoutThreshold)
+                if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
                     LockSupport.parkNanos(this, nanosTimeout);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
@@ -2167,7 +2190,7 @@
 
         /**
          * Queries whether any threads are waiting on this condition.
-         * Implements {@link AbstractQueuedSynchronizer#hasWaiters}.
+         * Implements {@link AbstractQueuedSynchronizer#hasWaiters(ConditionObject)}.
          *
          * @return {@code true} if there are any waiting threads
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
@@ -2186,7 +2209,7 @@
         /**
          * Returns an estimate of the number of threads waiting on
          * this condition.
-         * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength}.
+         * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength(ConditionObject)}.
          *
          * @return the estimated number of waiting threads
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
@@ -2206,7 +2229,7 @@
         /**
          * Returns a collection containing those threads that may be
          * waiting on this Condition.
-         * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads}.
+         * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads(ConditionObject)}.
          *
          * @return the collection of threads
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
@@ -2215,7 +2238,7 @@
         protected final Collection<Thread> getWaitingThreads() {
             if (!isHeldExclusively())
                 throw new IllegalMonitorStateException();
-            ArrayList<Thread> list = new ArrayList<Thread>();
+            ArrayList<Thread> list = new ArrayList<>();
             for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                 if (w.waitStatus == Node.CONDITION) {
                     Thread t = w.thread;
@@ -2236,27 +2259,22 @@
      * are at it, we do the same for other CASable fields (which could
      * otherwise be done with atomic field updaters).
      */
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final long stateOffset;
-    private static final long headOffset;
-    private static final long tailOffset;
-    private static final long waitStatusOffset;
-    private static final long nextOffset;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long STATE;
+    private static final long HEAD;
+    private static final long TAIL;
 
     static {
         try {
-            stateOffset = unsafe.objectFieldOffset
+            STATE = U.objectFieldOffset
                 (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
-            headOffset = unsafe.objectFieldOffset
+            HEAD = U.objectFieldOffset
                 (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
-            tailOffset = unsafe.objectFieldOffset
+            TAIL = U.objectFieldOffset
                 (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
-            waitStatusOffset = unsafe.objectFieldOffset
-                (Node.class.getDeclaredField("waitStatus"));
-            nextOffset = unsafe.objectFieldOffset
-                (Node.class.getDeclaredField("next"));
-
-        } catch (Exception ex) { throw new Error(ex); }
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
 
         // Reduce the risk of rare disastrous classloading in first call to
         // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
@@ -2264,35 +2282,18 @@
     }
 
     /**
-     * CAS head field. Used only by enq.
+     * Initializes head and tail fields on first contention.
      */
-    private final boolean compareAndSetHead(Node update) {
-        return unsafe.compareAndSwapObject(this, headOffset, null, update);
+    private final void initializeSyncQueue() {
+        Node h;
+        if (U.compareAndSwapObject(this, HEAD, null, (h = new Node())))
+            tail = h;
     }
 
     /**
-     * CAS tail field. Used only by enq.
+     * CASes tail field.
      */
     private final boolean compareAndSetTail(Node expect, Node update) {
-        return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
-    }
-
-    /**
-     * CAS waitStatus field of a node.
-     */
-    private static final boolean compareAndSetWaitStatus(Node node,
-                                                         int expect,
-                                                         int update) {
-        return unsafe.compareAndSwapInt(node, waitStatusOffset,
-                                        expect, update);
-    }
-
-    /**
-     * CAS next field of a node.
-     */
-    private static final boolean compareAndSetNext(Node node,
-                                                   Node expect,
-                                                   Node update) {
-        return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
+        return U.compareAndSwapObject(this, TAIL, expect, update);
     }
 }
diff --git a/luni/src/main/java/java/util/concurrent/locks/Condition.java b/luni/src/main/java/java/util/concurrent/locks/Condition.java
index 11a7090..b3132e7 100644
--- a/luni/src/main/java/java/util/concurrent/locks/Condition.java
+++ b/luni/src/main/java/java/util/concurrent/locks/Condition.java
@@ -6,8 +6,8 @@
 
 package java.util.concurrent.locks;
 
-import java.util.concurrent.TimeUnit;
 import java.util.Date;
+import java.util.concurrent.TimeUnit;
 
 /**
  * {@code Condition} factors out the {@code Object} monitor
@@ -98,7 +98,7 @@
  * <p>Note that {@code Condition} instances are just normal objects and can
  * themselves be used as the target in a {@code synchronized} statement,
  * and can have their own monitor {@link Object#wait wait} and
- * {@link Object#notify notification} methods invoked.
+ * {@link Object#notify notify} methods invoked.
  * Acquiring the monitor lock of a {@code Condition} instance, or using its
  * monitor methods, has no specified relationship with acquiring the
  * {@link Lock} associated with that {@code Condition} or the use of its
@@ -280,7 +280,7 @@
      * condition still does not hold. Typical uses of this method take
      * the following form:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * boolean aMethod(long timeout, TimeUnit unit) {
      *   long nanos = unit.toNanos(timeout);
      *   lock.lock();
@@ -333,7 +333,7 @@
      * Causes the current thread to wait until it is signalled or interrupted,
      * or the specified waiting time elapses. This method is behaviorally
      * equivalent to:
-     *  <pre> {@code awaitNanos(unit.toNanos(time)) > 0}</pre>
+     * <pre> {@code awaitNanos(unit.toNanos(time)) > 0}</pre>
      *
      * @param time the maximum time to wait
      * @param unit the time unit of the {@code time} argument
@@ -382,7 +382,7 @@
      *
      * <p>The return value indicates whether the deadline has elapsed,
      * which can be used as follows:
-     *  <pre> {@code
+     * <pre> {@code
      * boolean aMethod(Date deadline) {
      *   boolean stillWaiting = true;
      *   lock.lock();
diff --git a/luni/src/main/java/java/util/concurrent/locks/Lock.java b/luni/src/main/java/java/util/concurrent/locks/Lock.java
index a7ca001..a2d7b48 100644
--- a/luni/src/main/java/java/util/concurrent/locks/Lock.java
+++ b/luni/src/main/java/java/util/concurrent/locks/Lock.java
@@ -49,7 +49,7 @@
  * methods and statements. In most cases, the following idiom
  * should be used:
  *
- *  <pre> {@code
+ * <pre> {@code
  * Lock l = ...;
  * l.lock();
  * try {
@@ -93,8 +93,9 @@
  * <p>All {@code Lock} implementations <em>must</em> enforce the same
  * memory synchronization semantics as provided by the built-in monitor
  * lock, as described in
- * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4">
- * The Java Language Specification (17.4 Memory Model)</a>:
+ * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
+ * Chapter 17 of
+ * <cite>The Java&trade; Language Specification</cite></a>:
  * <ul>
  * <li>A successful {@code lock} operation has the same memory
  * synchronization effects as a successful <em>Lock</em> action.
@@ -212,7 +213,7 @@
      * immediately with the value {@code false}.
      *
      * <p>A typical usage idiom for this method would be:
-     *  <pre> {@code
+     * <pre> {@code
      * Lock lock = ...;
      * if (lock.tryLock()) {
      *   try {
diff --git a/luni/src/main/java/java/util/concurrent/locks/LockSupport.java b/luni/src/main/java/java/util/concurrent/locks/LockSupport.java
index 089d818..694f4ca 100644
--- a/luni/src/main/java/java/util/concurrent/locks/LockSupport.java
+++ b/luni/src/main/java/java/util/concurrent/locks/LockSupport.java
@@ -6,8 +6,6 @@
 
 package java.util.concurrent.locks;
 
-import sun.misc.Unsafe;
-
 /**
  * Basic thread blocking primitives for creating locks and other
  * synchronization classes.
@@ -19,6 +17,10 @@
  * it <em>may</em> block.  A call to {@code unpark} makes the permit
  * available, if it was not already available. (Unlike with Semaphores
  * though, permits do not accumulate. There is at most one.)
+ * Reliable usage requires the use of volatile (or atomic) variables
+ * to control when to park or unpark.  Orderings of calls to these
+ * methods are maintained with respect to volatile variable accesses,
+ * but not necessarily non-volatile variable accesses.
  *
  * <p>Methods {@code park} and {@code unpark} provide efficient
  * means of blocking and unblocking threads that do not encounter the
@@ -39,73 +41,74 @@
  * {@code blocker} object parameter. This object is recorded while
  * the thread is blocked to permit monitoring and diagnostic tools to
  * identify the reasons that threads are blocked. (Such tools may
- * access blockers using method {@link #getBlocker}.) The use of these
- * forms rather than the original forms without this parameter is
- * strongly encouraged. The normal argument to supply as a
- * {@code blocker} within a lock implementation is {@code this}.
+ * access blockers using method {@link #getBlocker(Thread)}.)
+ * The use of these forms rather than the original forms without this
+ * parameter is strongly encouraged. The normal argument to supply as
+ * a {@code blocker} within a lock implementation is {@code this}.
  *
  * <p>These methods are designed to be used as tools for creating
  * higher-level synchronization utilities, and are not in themselves
  * useful for most concurrency control applications.  The {@code park}
  * method is designed for use only in constructions of the form:
  *
- *  <pre> {@code
- * while (!canProceed()) { ... LockSupport.park(this); }}</pre>
+ * <pre> {@code
+ * while (!canProceed()) {
+ *   // ensure request to unpark is visible to other threads
+ *   ...
+ *   LockSupport.park(this);
+ * }}</pre>
  *
- * where neither {@code canProceed} nor any other actions prior to the
- * call to {@code park} entail locking or blocking.  Because only one
- * permit is associated with each thread, any intermediary uses of
- * {@code park} could interfere with its intended effects.
+ * where no actions by the thread publishing a request to unpark,
+ * prior to the call to {@code park}, entail locking or blocking.
+ * Because only one permit is associated with each thread, any
+ * intermediary uses of {@code park}, including implicitly via class
+ * loading, could lead to an unresponsive thread (a "lost unpark").
  *
  * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
  * non-reentrant lock class:
- *  <pre> {@code
+ * <pre> {@code
  * class FIFOMutex {
  *   private final AtomicBoolean locked = new AtomicBoolean(false);
  *   private final Queue<Thread> waiters
- *     = new ConcurrentLinkedQueue<Thread>();
+ *     = new ConcurrentLinkedQueue<>();
  *
  *   public void lock() {
  *     boolean wasInterrupted = false;
- *     Thread current = Thread.currentThread();
- *     waiters.add(current);
+ *     // publish current thread for unparkers
+ *     waiters.add(Thread.currentThread());
  *
  *     // Block while not first in queue or cannot acquire lock
- *     while (waiters.peek() != current ||
+ *     while (waiters.peek() != Thread.currentThread() ||
  *            !locked.compareAndSet(false, true)) {
  *       LockSupport.park(this);
- *       if (Thread.interrupted()) // ignore interrupts while waiting
+ *       // ignore interrupts while waiting
+ *       if (Thread.interrupted())
  *         wasInterrupted = true;
  *     }
  *
  *     waiters.remove();
- *     if (wasInterrupted)          // reassert interrupt status on exit
- *       current.interrupt();
+ *     // ensure correct interrupt status on return
+ *     if (wasInterrupted)
+ *       Thread.currentThread().interrupt();
  *   }
  *
  *   public void unlock() {
  *     locked.set(false);
  *     LockSupport.unpark(waiters.peek());
  *   }
+ *
+ *   static {
+ *     // Reduce the risk of "lost unpark" due to classloading
+ *     Class<?> ensureLoaded = LockSupport.class;
+ *   }
  * }}</pre>
  */
 public class LockSupport {
     private LockSupport() {} // Cannot be instantiated.
 
-    // Hotspot implementation via intrinsics API
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final long parkBlockerOffset;
-
-    static {
-        try {
-            parkBlockerOffset = unsafe.objectFieldOffset
-                (java.lang.Thread.class.getDeclaredField("parkBlocker"));
-        } catch (Exception ex) { throw new Error(ex); }
-    }
-
     private static void setBlocker(Thread t, Object arg) {
         // Even though volatile, hotspot doesn't need a write barrier here.
-        unsafe.putObject(t, parkBlockerOffset, arg);
+        U.putObject(t, PARKBLOCKER, arg);
     }
 
     /**
@@ -121,7 +124,7 @@
      */
     public static void unpark(Thread thread) {
         if (thread != null)
-            unsafe.unpark(thread);
+            U.unpark(thread);
     }
 
     /**
@@ -155,7 +158,7 @@
     public static void park(Object blocker) {
         Thread t = Thread.currentThread();
         setBlocker(t, blocker);
-        unsafe.park(false, 0L);
+        U.park(false, 0L);
         setBlocker(t, null);
     }
 
@@ -195,7 +198,7 @@
         if (nanos > 0) {
             Thread t = Thread.currentThread();
             setBlocker(t, blocker);
-            unsafe.park(false, nanos);
+            U.park(false, nanos);
             setBlocker(t, null);
         }
     }
@@ -236,7 +239,7 @@
     public static void parkUntil(Object blocker, long deadline) {
         Thread t = Thread.currentThread();
         setBlocker(t, blocker);
-        unsafe.park(true, deadline);
+        U.park(true, deadline);
         setBlocker(t, null);
     }
 
@@ -255,7 +258,7 @@
     public static Object getBlocker(Thread t) {
         if (t == null)
             throw new NullPointerException();
-        return unsafe.getObjectVolatile(t, parkBlockerOffset);
+        return U.getObjectVolatile(t, PARKBLOCKER);
     }
 
     /**
@@ -284,7 +287,7 @@
      * for example, the interrupt status of the thread upon return.
      */
     public static void park() {
-        unsafe.park(false, 0L);
+        U.park(false, 0L);
     }
 
     /**
@@ -318,7 +321,7 @@
      */
     public static void parkNanos(long nanos) {
         if (nanos > 0)
-            unsafe.park(false, nanos);
+            U.park(false, nanos);
     }
 
     /**
@@ -352,6 +355,40 @@
      *        to wait until
      */
     public static void parkUntil(long deadline) {
-        unsafe.park(true, deadline);
+        U.park(true, deadline);
     }
+
+    /**
+     * Returns the pseudo-randomly initialized or updated secondary seed.
+     * Copied from ThreadLocalRandom due to package access restrictions.
+     */
+    static final int nextSecondarySeed() {
+        int r;
+        Thread t = Thread.currentThread();
+        if ((r = U.getInt(t, SECONDARY)) != 0) {
+            r ^= r << 13;   // xorshift
+            r ^= r >>> 17;
+            r ^= r << 5;
+        }
+        else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)
+            r = 1; // avoid zero
+        U.putInt(t, SECONDARY, r);
+        return r;
+    }
+
+    // Hotspot implementation via intrinsics API
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long PARKBLOCKER;
+    private static final long SECONDARY;
+    static {
+        try {
+            PARKBLOCKER = U.objectFieldOffset
+                (Thread.class.getDeclaredField("parkBlocker"));
+            SECONDARY = U.objectFieldOffset
+                (Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+
 }
diff --git a/luni/src/main/java/java/util/concurrent/locks/ReadWriteLock.java b/luni/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
index 8690355..a1a211a 100644
--- a/luni/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
+++ b/luni/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
@@ -9,9 +9,9 @@
 /**
  * A {@code ReadWriteLock} maintains a pair of associated {@link
  * Lock locks}, one for read-only operations and one for writing.
- * The {@link #readLock read lock} may be held simultaneously by
- * multiple reader threads, so long as there are no writers.  The
- * {@link #writeLock write lock} is exclusive.
+ * The {@linkplain #readLock read lock} may be held simultaneously
+ * by multiple reader threads, so long as there are no writers.
+ * The {@linkplain #writeLock write lock} is exclusive.
  *
  * <p>All {@code ReadWriteLock} implementations must guarantee that
  * the memory synchronization effects of {@code writeLock} operations
diff --git a/luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java b/luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java
index 3654248..5fedcaa 100644
--- a/luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java
+++ b/luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java
@@ -6,8 +6,9 @@
 
 package java.util.concurrent.locks;
 
-import java.util.concurrent.TimeUnit;
 import java.util.Collection;
+import java.util.concurrent.TimeUnit;
+/// OPENJDK-9 import jdk.internal.vm.annotation.ReservedStackAccess;
 
 /**
  * A reentrant mutual exclusion {@link Lock} with the same basic
@@ -44,7 +45,7 @@
  * follow a call to {@code lock} with a {@code try} block, most
  * typically in a before/after construction such as:
  *
- *  <pre> {@code
+ * <pre> {@code
  * class X {
  *   private final ReentrantLock lock = new ReentrantLock();
  *   // ...
@@ -98,6 +99,7 @@
          * Performs non-fair tryLock.  tryAcquire is implemented in
          * subclasses, but both need nonfair try for trylock method.
          */
+/// OPENJDK-9         @ReservedStackAccess
         final boolean nonfairTryAcquire(int acquires) {
             final Thread current = Thread.currentThread();
             int c = getState();
@@ -117,6 +119,7 @@
             return false;
         }
 
+/// OPENJDK-9         @ReservedStackAccess
         protected final boolean tryRelease(int releases) {
             int c = getState() - releases;
             if (Thread.currentThread() != getExclusiveOwnerThread())
@@ -174,6 +177,7 @@
          * Performs lock.  Try immediate barge, backing up to normal
          * acquire on failure.
          */
+/// OPENJDK-9         @ReservedStackAccess
         final void lock() {
             if (compareAndSetState(0, 1))
                 setExclusiveOwnerThread(Thread.currentThread());
@@ -200,6 +204,7 @@
          * Fair version of tryAcquire.  Don't grant access unless
          * recursive call or no waiters or is first.
          */
+/// OPENJDK-9         @ReservedStackAccess
         protected final boolean tryAcquire(int acquires) {
             final Thread current = Thread.currentThread();
             int c = getState();
@@ -350,7 +355,7 @@
      * method. If you want a timed {@code tryLock} that does permit barging on
      * a fair lock then combine the timed and un-timed forms together:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * if (lock.tryLock() ||
      *     lock.tryLock(timeout, unit)) {
      *   ...
@@ -456,7 +461,7 @@
      * InterruptedException} will be thrown, and the thread's
      * interrupted status will be cleared.
      *
-     * <li> Waiting threads are signalled in FIFO order.
+     * <li>Waiting threads are signalled in FIFO order.
      *
      * <li>The ordering of lock reacquisition for threads returning
      * from waiting methods is the same as for threads initially
@@ -483,7 +488,7 @@
      * not be entered with the lock already held then we can assert that
      * fact:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * class X {
      *   ReentrantLock lock = new ReentrantLock();
      *   // ...
@@ -508,12 +513,12 @@
     /**
      * Queries if this lock is held by the current thread.
      *
-     * <p>Analogous to the {@link Thread#holdsLock} method for built-in
-     * monitor locks, this method is typically used for debugging and
-     * testing. For example, a method that should only be called while
-     * a lock is held can assert that this is the case:
+     * <p>Analogous to the {@link Thread#holdsLock(Object)} method for
+     * built-in monitor locks, this method is typically used for
+     * debugging and testing. For example, a method that should only be
+     * called while a lock is held can assert that this is the case:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * class X {
      *   ReentrantLock lock = new ReentrantLock();
      *   // ...
@@ -527,7 +532,7 @@
      * <p>It can also be used to ensure that a reentrant lock is used
      * in a non-reentrant manner, for example:
      *
-     *  <pre> {@code
+     * <pre> {@code
      * class X {
      *   ReentrantLock lock = new ReentrantLock();
      *   // ...
@@ -618,12 +623,11 @@
     }
 
     /**
-     * Returns an estimate of the number of threads waiting to
-     * acquire this lock.  The value is only an estimate because the number of
+     * Returns an estimate of the number of threads waiting to acquire
+     * this lock.  The value is only an estimate because the number of
      * threads may change dynamically while this method traverses
      * internal data structures.  This method is designed for use in
-     * monitoring of the system state, not for synchronization
-     * control.
+     * monitoring system state, not for synchronization control.
      *
      * @return the estimated number of threads waiting for this lock
      */
diff --git a/luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java b/luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
index cc7ba4c..8969a54 100644
--- a/luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
+++ b/luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
@@ -6,8 +6,8 @@
 
 package java.util.concurrent.locks;
 
-import java.util.concurrent.TimeUnit;
 import java.util.Collection;
+import java.util.concurrent.TimeUnit;
 
 /**
  * An implementation of {@link ReadWriteLock} supporting similar
@@ -23,15 +23,16 @@
  *
  * <dl>
  * <dt><b><i>Non-fair mode (default)</i></b>
- * <dd>When constructed as non-fair (the default), the order of entry
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * When constructed as non-fair (the default), the order of entry
  * to the read and write lock is unspecified, subject to reentrancy
  * constraints.  A nonfair lock that is continuously contended may
  * indefinitely postpone one or more reader or writer threads, but
  * will normally have higher throughput than a fair lock.
- * <p>
  *
  * <dt><b><i>Fair mode</i></b>
- * <dd>When constructed as fair, threads contend for entry using an
+ * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif">
+ * When constructed as fair, threads contend for entry using an
  * approximately arrival-order policy. When the currently held lock
  * is released, either the longest-waiting single writer thread will
  * be assigned the write lock, or if there is a group of reader threads
@@ -53,7 +54,6 @@
  * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
  * do not honor this fair setting and will immediately acquire the lock
  * if it is possible, regardless of waiting threads.)
- * <p>
  * </dl>
  *
  * <li><b>Reentrancy</b>
@@ -147,9 +147,9 @@
  * is a class using a TreeMap that is expected to be large and
  * concurrently accessed.
  *
- *  <pre> {@code
+ * <pre> {@code
  * class RWDictionary {
- *   private final Map<String, Data> m = new TreeMap<String, Data>();
+ *   private final Map<String, Data> m = new TreeMap<>();
  *   private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  *   private final Lock r = rwl.readLock();
  *   private final Lock w = rwl.writeLock();
@@ -159,9 +159,9 @@
  *     try { return m.get(key); }
  *     finally { r.unlock(); }
  *   }
- *   public String[] allKeys() {
+ *   public List<String> allKeys() {
  *     r.lock();
- *     try { return m.keySet().toArray(); }
+ *     try { return new ArrayList<>(m.keySet()); }
  *     finally { r.unlock(); }
  *   }
  *   public Data put(String key, Data value) {
@@ -247,9 +247,9 @@
          * Maintained as a ThreadLocal; cached in cachedHoldCounter.
          */
         static final class HoldCounter {
-            int count = 0;
+            int count;          // initially 0
             // Use id, not reference, to avoid garbage retention
-            final long tid = Thread.currentThread().getId();
+            final long tid = getThreadId(Thread.currentThread());
         }
 
         /**
@@ -392,7 +392,7 @@
                     firstReaderHoldCount--;
             } else {
                 HoldCounter rh = cachedHoldCounter;
-                if (rh == null || rh.tid != current.getId())
+                if (rh == null || rh.tid != getThreadId(current))
                     rh = readHolds.get();
                 int count = rh.count;
                 if (count <= 1) {
@@ -450,7 +450,7 @@
                     firstReaderHoldCount++;
                 } else {
                     HoldCounter rh = cachedHoldCounter;
-                    if (rh == null || rh.tid != current.getId())
+                    if (rh == null || rh.tid != getThreadId(current))
                         cachedHoldCounter = rh = readHolds.get();
                     else if (rh.count == 0)
                         readHolds.set(rh);
@@ -487,7 +487,7 @@
                     } else {
                         if (rh == null) {
                             rh = cachedHoldCounter;
-                            if (rh == null || rh.tid != current.getId()) {
+                            if (rh == null || rh.tid != getThreadId(current)) {
                                 rh = readHolds.get();
                                 if (rh.count == 0)
                                     readHolds.remove();
@@ -508,7 +508,7 @@
                     } else {
                         if (rh == null)
                             rh = cachedHoldCounter;
-                        if (rh == null || rh.tid != current.getId())
+                        if (rh == null || rh.tid != getThreadId(current))
                             rh = readHolds.get();
                         else if (rh.count == 0)
                             readHolds.set(rh);
@@ -564,7 +564,7 @@
                         firstReaderHoldCount++;
                     } else {
                         HoldCounter rh = cachedHoldCounter;
-                        if (rh == null || rh.tid != current.getId())
+                        if (rh == null || rh.tid != getThreadId(current))
                             cachedHoldCounter = rh = readHolds.get();
                         else if (rh.count == 0)
                             readHolds.set(rh);
@@ -615,7 +615,7 @@
                 return firstReaderHoldCount;
 
             HoldCounter rh = cachedHoldCounter;
-            if (rh != null && rh.tid == current.getId())
+            if (rh != null && rh.tid == getThreadId(current))
                 return rh.count;
 
             int count = readHolds.get().count;
@@ -677,7 +677,7 @@
         private final Sync sync;
 
         /**
-         * Constructor for use by subclasses
+         * Constructor for use by subclasses.
          *
          * @param lock the outer lock object
          * @throws NullPointerException if the lock is null
@@ -788,7 +788,7 @@
          * permit barging on a fair lock then combine the timed and
          * un-timed forms together:
          *
-         *  <pre> {@code
+         * <pre> {@code
          * if (lock.tryLock() ||
          *     lock.tryLock(timeout, unit)) {
          *   ...
@@ -848,7 +848,12 @@
          * Attempts to release this lock.
          *
          * <p>If the number of readers is now zero then the lock
-         * is made available for write lock attempts.
+         * is made available for write lock attempts. If the current
+         * thread does not hold this lock then {@link
+         * IllegalMonitorStateException} is thrown.
+         *
+         * @throws IllegalMonitorStateException if the current thread
+         * does not hold this lock
          */
         public void unlock() {
             sync.releaseShared(1);
@@ -886,7 +891,7 @@
         private final Sync sync;
 
         /**
-         * Constructor for use by subclasses
+         * Constructor for use by subclasses.
          *
          * @param lock the outer lock object
          * @throws NullPointerException if the lock is null
@@ -1000,7 +1005,7 @@
          * by the current thread, or the write lock was already held
          * by the current thread; and {@code false} otherwise.
          */
-        public boolean tryLock( ) {
+        public boolean tryLock() {
             return sync.tryWriteLock();
         }
 
@@ -1020,7 +1025,7 @@
          * that does permit barging on a fair lock then combine the
          * timed and un-timed forms together:
          *
-         *  <pre> {@code
+         * <pre> {@code
          * if (lock.tryLock() ||
          *     lock.tryLock(timeout, unit)) {
          *   ...
@@ -1135,7 +1140,7 @@
          * InterruptedException} will be thrown, and the thread's
          * interrupted status will be cleared.
          *
-         * <li> Waiting threads are signalled in FIFO order.
+         * <li>Waiting threads are signalled in FIFO order.
          *
          * <li>The ordering of lock reacquisition for threads returning
          * from waiting methods is the same as for threads initially
@@ -1343,7 +1348,7 @@
      * either the read or write lock.  The value is only an estimate
      * because the number of threads may change dynamically while this
      * method traverses internal data structures.  This method is
-     * designed for use in monitoring of the system state, not for
+     * designed for use in monitoring system state, not for
      * synchronization control.
      *
      * @return the estimated number of threads waiting for this lock
@@ -1456,4 +1461,26 @@
             "[Write locks = " + w + ", Read locks = " + r + "]";
     }
 
+    /**
+     * Returns the thread id for the given thread.  We must access
+     * this directly rather than via method Thread.getId() because
+     * getId() is not final, and has been known to be overridden in
+     * ways that do not preserve unique mappings.
+     */
+    static final long getThreadId(Thread thread) {
+        return U.getLongVolatile(thread, TID);
+    }
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long TID;
+    static {
+        try {
+            TID = U.objectFieldOffset
+                (Thread.class.getDeclaredField("tid"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+
 }
diff --git a/luni/src/main/java/java/util/concurrent/locks/StampedLock.java b/luni/src/main/java/java/util/concurrent/locks/StampedLock.java
new file mode 100644
index 0000000..1f4d54f
--- /dev/null
+++ b/luni/src/main/java/java/util/concurrent/locks/StampedLock.java
@@ -0,0 +1,1403 @@
+/*
+ * 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.locks;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A capability-based lock with three modes for controlling read/write
+ * access.  The state of a StampedLock consists of a version and mode.
+ * Lock acquisition methods return a stamp that represents and
+ * controls access with respect to a lock state; "try" versions of
+ * these methods may instead return the special value zero to
+ * represent failure to acquire access. Lock release and conversion
+ * methods require stamps as arguments, and fail if they do not match
+ * the state of the lock. The three modes are:
+ *
+ * <ul>
+ *
+ *  <li><b>Writing.</b> Method {@link #writeLock} possibly blocks
+ *   waiting for exclusive access, returning a stamp that can be used
+ *   in method {@link #unlockWrite} to release the lock. Untimed and
+ *   timed versions of {@code tryWriteLock} are also provided. When
+ *   the lock is held in write mode, no read locks may be obtained,
+ *   and all optimistic read validations will fail.
+ *
+ *  <li><b>Reading.</b> Method {@link #readLock} possibly blocks
+ *   waiting for non-exclusive access, returning a stamp that can be
+ *   used in method {@link #unlockRead} to release the lock. Untimed
+ *   and timed versions of {@code tryReadLock} are also provided.
+ *
+ *  <li><b>Optimistic Reading.</b> Method {@link #tryOptimisticRead}
+ *   returns a non-zero stamp only if the lock is not currently held
+ *   in write mode. Method {@link #validate} returns true if the lock
+ *   has not been acquired in write mode since obtaining a given
+ *   stamp.  This mode can be thought of as an extremely weak version
+ *   of a read-lock, that can be broken by a writer at any time.  The
+ *   use of optimistic mode for short read-only code segments often
+ *   reduces contention and improves throughput.  However, its use is
+ *   inherently fragile.  Optimistic read sections should only read
+ *   fields and hold them in local variables for later use after
+ *   validation. Fields read while in optimistic mode may be wildly
+ *   inconsistent, so usage applies only when you are familiar enough
+ *   with data representations to check consistency and/or repeatedly
+ *   invoke method {@code validate()}.  For example, such steps are
+ *   typically required when first reading an object or array
+ *   reference, and then accessing one of its fields, elements or
+ *   methods.
+ *
+ * </ul>
+ *
+ * <p>This class also supports methods that conditionally provide
+ * conversions across the three modes. For example, method {@link
+ * #tryConvertToWriteLock} attempts to "upgrade" a mode, returning
+ * a valid write stamp if (1) already in writing mode (2) in reading
+ * mode and there are no other readers or (3) in optimistic mode and
+ * the lock is available. The forms of these methods are designed to
+ * help reduce some of the code bloat that otherwise occurs in
+ * retry-based designs.
+ *
+ * <p>StampedLocks are designed for use as internal utilities in the
+ * development of thread-safe components. Their use relies on
+ * knowledge of the internal properties of the data, objects, and
+ * methods they are protecting.  They are not reentrant, so locked
+ * bodies should not call other unknown methods that may try to
+ * re-acquire locks (although you may pass a stamp to other methods
+ * that can use or convert it).  The use of read lock modes relies on
+ * the associated code sections being side-effect-free.  Unvalidated
+ * optimistic read sections cannot call methods that are not known to
+ * tolerate potential inconsistencies.  Stamps use finite
+ * representations, and are not cryptographically secure (i.e., a
+ * valid stamp may be guessable). Stamp values may recycle after (no
+ * sooner than) one year of continuous operation. A stamp held without
+ * use or validation for longer than this period may fail to validate
+ * correctly.  StampedLocks are serializable, but always deserialize
+ * into initial unlocked state, so they are not useful for remote
+ * locking.
+ *
+ * <p>The scheduling policy of StampedLock does not consistently
+ * prefer readers over writers or vice versa.  All "try" methods are
+ * best-effort and do not necessarily conform to any scheduling or
+ * fairness policy. A zero return from any "try" method for acquiring
+ * or converting locks does not carry any information about the state
+ * of the lock; a subsequent invocation may succeed.
+ *
+ * <p>Because it supports coordinated usage across multiple lock
+ * modes, this class does not directly implement the {@link Lock} or
+ * {@link ReadWriteLock} interfaces. However, a StampedLock may be
+ * viewed {@link #asReadLock()}, {@link #asWriteLock()}, or {@link
+ * #asReadWriteLock()} in applications requiring only the associated
+ * set of functionality.
+ *
+ * <p><b>Sample Usage.</b> The following illustrates some usage idioms
+ * in a class that maintains simple two-dimensional points. The sample
+ * code illustrates some try/catch conventions even though they are
+ * not strictly needed here because no exceptions can occur in their
+ * bodies.<br>
+ *
+ * <pre> {@code
+ * class Point {
+ *   private double x, y;
+ *   private final StampedLock sl = new StampedLock();
+ *
+ *   void move(double deltaX, double deltaY) { // an exclusively locked method
+ *     long stamp = sl.writeLock();
+ *     try {
+ *       x += deltaX;
+ *       y += deltaY;
+ *     } finally {
+ *       sl.unlockWrite(stamp);
+ *     }
+ *   }
+ *
+ *   double distanceFromOrigin() { // A read-only method
+ *     long stamp = sl.tryOptimisticRead();
+ *     double currentX = x, currentY = y;
+ *     if (!sl.validate(stamp)) {
+ *        stamp = sl.readLock();
+ *        try {
+ *          currentX = x;
+ *          currentY = y;
+ *        } finally {
+ *           sl.unlockRead(stamp);
+ *        }
+ *     }
+ *     return Math.sqrt(currentX * currentX + currentY * currentY);
+ *   }
+ *
+ *   void moveIfAtOrigin(double newX, double newY) { // upgrade
+ *     // Could instead start with optimistic, not read mode
+ *     long stamp = sl.readLock();
+ *     try {
+ *       while (x == 0.0 && y == 0.0) {
+ *         long ws = sl.tryConvertToWriteLock(stamp);
+ *         if (ws != 0L) {
+ *           stamp = ws;
+ *           x = newX;
+ *           y = newY;
+ *           break;
+ *         }
+ *         else {
+ *           sl.unlockRead(stamp);
+ *           stamp = sl.writeLock();
+ *         }
+ *       }
+ *     } finally {
+ *       sl.unlock(stamp);
+ *     }
+ *   }
+ * }}</pre>
+ *
+ * @since 1.8
+ * @author Doug Lea
+ */
+public class StampedLock implements java.io.Serializable {
+    /*
+     * Algorithmic notes:
+     *
+     * The design employs elements of Sequence locks
+     * (as used in linux kernels; see Lameter's
+     * http://www.lameter.com/gelato2005.pdf
+     * and elsewhere; see
+     * Boehm's http://www.hpl.hp.com/techreports/2012/HPL-2012-68.html)
+     * and Ordered RW locks (see Shirako et al
+     * http://dl.acm.org/citation.cfm?id=2312015)
+     *
+     * Conceptually, the primary state of the lock includes a sequence
+     * number that is odd when write-locked and even otherwise.
+     * However, this is offset by a reader count that is non-zero when
+     * read-locked.  The read count is ignored when validating
+     * "optimistic" seqlock-reader-style stamps.  Because we must use
+     * a small finite number of bits (currently 7) for readers, a
+     * supplementary reader overflow word is used when the number of
+     * readers exceeds the count field. We do this by treating the max
+     * reader count value (RBITS) as a spinlock protecting overflow
+     * updates.
+     *
+     * Waiters use a modified form of CLH lock used in
+     * AbstractQueuedSynchronizer (see its internal documentation for
+     * a fuller account), where each node is tagged (field mode) as
+     * either a reader or writer. Sets of waiting readers are grouped
+     * (linked) under a common node (field cowait) so act as a single
+     * node with respect to most CLH mechanics.  By virtue of the
+     * queue structure, wait nodes need not actually carry sequence
+     * numbers; we know each is greater than its predecessor.  This
+     * simplifies the scheduling policy to a mainly-FIFO scheme that
+     * incorporates elements of Phase-Fair locks (see Brandenburg &
+     * Anderson, especially http://www.cs.unc.edu/~bbb/diss/).  In
+     * particular, we use the phase-fair anti-barging rule: If an
+     * incoming reader arrives while read lock is held but there is a
+     * queued writer, this incoming reader is queued.  (This rule is
+     * responsible for some of the complexity of method acquireRead,
+     * but without it, the lock becomes highly unfair.) Method release
+     * does not (and sometimes cannot) itself wake up cowaiters. This
+     * is done by the primary thread, but helped by any other threads
+     * with nothing better to do in methods acquireRead and
+     * acquireWrite.
+     *
+     * These rules apply to threads actually queued. All tryLock forms
+     * opportunistically try to acquire locks regardless of preference
+     * rules, and so may "barge" their way in.  Randomized spinning is
+     * used in the acquire methods to reduce (increasingly expensive)
+     * context switching while also avoiding sustained memory
+     * thrashing among many threads.  We limit spins to the head of
+     * queue. A thread spin-waits up to SPINS times (where each
+     * iteration decreases spin count with 50% probability) before
+     * blocking. If, upon wakening it fails to obtain lock, and is
+     * still (or becomes) the first waiting thread (which indicates
+     * that some other thread barged and obtained lock), it escalates
+     * spins (up to MAX_HEAD_SPINS) to reduce the likelihood of
+     * continually losing to barging threads.
+     *
+     * Nearly all of these mechanics are carried out in methods
+     * acquireWrite and acquireRead, that, as typical of such code,
+     * sprawl out because actions and retries rely on consistent sets
+     * of locally cached reads.
+     *
+     * As noted in Boehm's paper (above), sequence validation (mainly
+     * method validate()) requires stricter ordering rules than apply
+     * to normal volatile reads (of "state").  To force orderings of
+     * reads before a validation and the validation itself in those
+     * cases where this is not already forced, we use
+     * Unsafe.loadFence.
+     *
+     * The memory layout keeps lock state and queue pointers together
+     * (normally on the same cache line). This usually works well for
+     * read-mostly loads. In most other cases, the natural tendency of
+     * adaptive-spin CLH locks to reduce memory contention lessens
+     * motivation to further spread out contended locations, but might
+     * be subject to future improvements.
+     */
+
+    private static final long serialVersionUID = -6001602636862214147L;
+
+    /** Number of processors, for spin control */
+    private static final int NCPU = Runtime.getRuntime().availableProcessors();
+
+    /** Maximum number of retries before enqueuing on acquisition */
+    private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0;
+
+    /** Maximum number of retries before blocking at head on acquisition */
+    private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 0;
+
+    /** Maximum number of retries before re-blocking */
+    private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 16 : 0;
+
+    /** The period for yielding when waiting for overflow spinlock */
+    private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1
+
+    /** The number of bits to use for reader count before overflowing */
+    private static final int LG_READERS = 7;
+
+    // Values for lock state and stamp operations
+    private static final long RUNIT = 1L;
+    private static final long WBIT  = 1L << LG_READERS;
+    private static final long RBITS = WBIT - 1L;
+    private static final long RFULL = RBITS - 1L;
+    private static final long ABITS = RBITS | WBIT;
+    private static final long SBITS = ~RBITS; // note overlap with ABITS
+
+    // Initial value for lock state; avoid failure value zero
+    private static final long ORIGIN = WBIT << 1;
+
+    // Special value from cancelled acquire methods so caller can throw IE
+    private static final long INTERRUPTED = 1L;
+
+    // Values for node status; order matters
+    private static final int WAITING   = -1;
+    private static final int CANCELLED =  1;
+
+    // Modes for nodes (int not boolean to allow arithmetic)
+    private static final int RMODE = 0;
+    private static final int WMODE = 1;
+
+    /** Wait nodes */
+    static final class WNode {
+        volatile WNode prev;
+        volatile WNode next;
+        volatile WNode cowait;    // list of linked readers
+        volatile Thread thread;   // non-null while possibly parked
+        volatile int status;      // 0, WAITING, or CANCELLED
+        final int mode;           // RMODE or WMODE
+        WNode(int m, WNode p) { mode = m; prev = p; }
+    }
+
+    /** Head of CLH queue */
+    private transient volatile WNode whead;
+    /** Tail (last) of CLH queue */
+    private transient volatile WNode wtail;
+
+    // views
+    transient ReadLockView readLockView;
+    transient WriteLockView writeLockView;
+    transient ReadWriteLockView readWriteLockView;
+
+    /** Lock sequence/state */
+    private transient volatile long state;
+    /** extra reader count when state read count saturated */
+    private transient int readerOverflow;
+
+    /**
+     * Creates a new lock, initially in unlocked state.
+     */
+    public StampedLock() {
+        state = ORIGIN;
+    }
+
+    /**
+     * Exclusively acquires the lock, blocking if necessary
+     * until available.
+     *
+     * @return a stamp that can be used to unlock or convert mode
+     */
+    public long writeLock() {
+        long s, next;  // bypass acquireWrite in fully unlocked case only
+        return ((((s = state) & ABITS) == 0L &&
+                 U.compareAndSwapLong(this, STATE, s, next = s + WBIT)) ?
+                next : acquireWrite(false, 0L));
+    }
+
+    /**
+     * Exclusively acquires the lock if it is immediately available.
+     *
+     * @return a stamp that can be used to unlock or convert mode,
+     * or zero if the lock is not available
+     */
+    public long tryWriteLock() {
+        long s, next;
+        return ((((s = state) & ABITS) == 0L &&
+                 U.compareAndSwapLong(this, STATE, s, next = s + WBIT)) ?
+                next : 0L);
+    }
+
+    /**
+     * Exclusively acquires the lock if it is available within the
+     * given time and the current thread has not been interrupted.
+     * Behavior under timeout and interruption matches that specified
+     * for method {@link Lock#tryLock(long,TimeUnit)}.
+     *
+     * @param time the maximum time to wait for the lock
+     * @param unit the time unit of the {@code time} argument
+     * @return a stamp that can be used to unlock or convert mode,
+     * or zero if the lock is not available
+     * @throws InterruptedException if the current thread is interrupted
+     * before acquiring the lock
+     */
+    public long tryWriteLock(long time, TimeUnit unit)
+        throws InterruptedException {
+        long nanos = unit.toNanos(time);
+        if (!Thread.interrupted()) {
+            long next, deadline;
+            if ((next = tryWriteLock()) != 0L)
+                return next;
+            if (nanos <= 0L)
+                return 0L;
+            if ((deadline = System.nanoTime() + nanos) == 0L)
+                deadline = 1L;
+            if ((next = acquireWrite(true, deadline)) != INTERRUPTED)
+                return next;
+        }
+        throw new InterruptedException();
+    }
+
+    /**
+     * Exclusively acquires the lock, blocking if necessary
+     * until available or the current thread is interrupted.
+     * Behavior under interruption matches that specified
+     * for method {@link Lock#lockInterruptibly()}.
+     *
+     * @return a stamp that can be used to unlock or convert mode
+     * @throws InterruptedException if the current thread is interrupted
+     * before acquiring the lock
+     */
+    public long writeLockInterruptibly() throws InterruptedException {
+        long next;
+        if (!Thread.interrupted() &&
+            (next = acquireWrite(true, 0L)) != INTERRUPTED)
+            return next;
+        throw new InterruptedException();
+    }
+
+    /**
+     * Non-exclusively acquires the lock, blocking if necessary
+     * until available.
+     *
+     * @return a stamp that can be used to unlock or convert mode
+     */
+    public long readLock() {
+        long s = state, next;  // bypass acquireRead on common uncontended case
+        return ((whead == wtail && (s & ABITS) < RFULL &&
+                 U.compareAndSwapLong(this, STATE, s, next = s + RUNIT)) ?
+                next : acquireRead(false, 0L));
+    }
+
+    /**
+     * Non-exclusively acquires the lock if it is immediately available.
+     *
+     * @return a stamp that can be used to unlock or convert mode,
+     * or zero if the lock is not available
+     */
+    public long tryReadLock() {
+        for (;;) {
+            long s, m, next;
+            if ((m = (s = state) & ABITS) == WBIT)
+                return 0L;
+            else if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, next = s + RUNIT))
+                    return next;
+            }
+            else if ((next = tryIncReaderOverflow(s)) != 0L)
+                return next;
+        }
+    }
+
+    /**
+     * Non-exclusively acquires the lock if it is available within the
+     * given time and the current thread has not been interrupted.
+     * Behavior under timeout and interruption matches that specified
+     * for method {@link Lock#tryLock(long,TimeUnit)}.
+     *
+     * @param time the maximum time to wait for the lock
+     * @param unit the time unit of the {@code time} argument
+     * @return a stamp that can be used to unlock or convert mode,
+     * or zero if the lock is not available
+     * @throws InterruptedException if the current thread is interrupted
+     * before acquiring the lock
+     */
+    public long tryReadLock(long time, TimeUnit unit)
+        throws InterruptedException {
+        long s, m, next, deadline;
+        long nanos = unit.toNanos(time);
+        if (!Thread.interrupted()) {
+            if ((m = (s = state) & ABITS) != WBIT) {
+                if (m < RFULL) {
+                    if (U.compareAndSwapLong(this, STATE, s, next = s + RUNIT))
+                        return next;
+                }
+                else if ((next = tryIncReaderOverflow(s)) != 0L)
+                    return next;
+            }
+            if (nanos <= 0L)
+                return 0L;
+            if ((deadline = System.nanoTime() + nanos) == 0L)
+                deadline = 1L;
+            if ((next = acquireRead(true, deadline)) != INTERRUPTED)
+                return next;
+        }
+        throw new InterruptedException();
+    }
+
+    /**
+     * Non-exclusively acquires the lock, blocking if necessary
+     * until available or the current thread is interrupted.
+     * Behavior under interruption matches that specified
+     * for method {@link Lock#lockInterruptibly()}.
+     *
+     * @return a stamp that can be used to unlock or convert mode
+     * @throws InterruptedException if the current thread is interrupted
+     * before acquiring the lock
+     */
+    public long readLockInterruptibly() throws InterruptedException {
+        long next;
+        if (!Thread.interrupted() &&
+            (next = acquireRead(true, 0L)) != INTERRUPTED)
+            return next;
+        throw new InterruptedException();
+    }
+
+    /**
+     * Returns a stamp that can later be validated, or zero
+     * if exclusively locked.
+     *
+     * @return a stamp, or zero if exclusively locked
+     */
+    public long tryOptimisticRead() {
+        long s;
+        return (((s = state) & WBIT) == 0L) ? (s & SBITS) : 0L;
+    }
+
+    /**
+     * Returns true if the lock has not been exclusively acquired
+     * since issuance of the given stamp. Always returns false if the
+     * stamp is zero. Always returns true if the stamp represents a
+     * currently held lock. Invoking this method with a value not
+     * obtained from {@link #tryOptimisticRead} or a locking method
+     * for this lock has no defined effect or result.
+     *
+     * @param stamp a stamp
+     * @return {@code true} if the lock has not been exclusively acquired
+     * since issuance of the given stamp; else false
+     */
+    public boolean validate(long stamp) {
+        U.loadFence();
+        return (stamp & SBITS) == (state & SBITS);
+    }
+
+    /**
+     * If the lock state matches the given stamp, releases the
+     * exclusive lock.
+     *
+     * @param stamp a stamp returned by a write-lock operation
+     * @throws IllegalMonitorStateException if the stamp does
+     * not match the current state of this lock
+     */
+    public void unlockWrite(long stamp) {
+        WNode h;
+        if (state != stamp || (stamp & WBIT) == 0L)
+            throw new IllegalMonitorStateException();
+        U.putLongVolatile(this, STATE, (stamp += WBIT) == 0L ? ORIGIN : stamp);
+        if ((h = whead) != null && h.status != 0)
+            release(h);
+    }
+
+    /**
+     * If the lock state matches the given stamp, releases the
+     * non-exclusive lock.
+     *
+     * @param stamp a stamp returned by a read-lock operation
+     * @throws IllegalMonitorStateException if the stamp does
+     * not match the current state of this lock
+     */
+    public void unlockRead(long stamp) {
+        long s, m; WNode h;
+        for (;;) {
+            if (((s = state) & SBITS) != (stamp & SBITS) ||
+                (stamp & ABITS) == 0L || (m = s & ABITS) == 0L || m == WBIT)
+                throw new IllegalMonitorStateException();
+            if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    break;
+                }
+            }
+            else if (tryDecReaderOverflow(s) != 0L)
+                break;
+        }
+    }
+
+    /**
+     * If the lock state matches the given stamp, releases the
+     * corresponding mode of the lock.
+     *
+     * @param stamp a stamp returned by a lock operation
+     * @throws IllegalMonitorStateException if the stamp does
+     * not match the current state of this lock
+     */
+    public void unlock(long stamp) {
+        long a = stamp & ABITS, m, s; WNode h;
+        while (((s = state) & SBITS) == (stamp & SBITS)) {
+            if ((m = s & ABITS) == 0L)
+                break;
+            else if (m == WBIT) {
+                if (a != m)
+                    break;
+                U.putLongVolatile(this, STATE, (s += WBIT) == 0L ? ORIGIN : s);
+                if ((h = whead) != null && h.status != 0)
+                    release(h);
+                return;
+            }
+            else if (a == 0L || a >= WBIT)
+                break;
+            else if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    return;
+                }
+            }
+            else if (tryDecReaderOverflow(s) != 0L)
+                return;
+        }
+        throw new IllegalMonitorStateException();
+    }
+
+    /**
+     * If the lock state matches the given stamp, atomically performs one of
+     * the following actions. If the stamp represents holding a write
+     * lock, returns it.  Or, if a read lock, if the write lock is
+     * available, releases the read lock and returns a write stamp.
+     * Or, if an optimistic read, returns a write stamp only if
+     * immediately available. This method returns zero in all other
+     * cases.
+     *
+     * @param stamp a stamp
+     * @return a valid write stamp, or zero on failure
+     */
+    public long tryConvertToWriteLock(long stamp) {
+        long a = stamp & ABITS, m, s, next;
+        while (((s = state) & SBITS) == (stamp & SBITS)) {
+            if ((m = s & ABITS) == 0L) {
+                if (a != 0L)
+                    break;
+                if (U.compareAndSwapLong(this, STATE, s, next = s + WBIT))
+                    return next;
+            }
+            else if (m == WBIT) {
+                if (a != m)
+                    break;
+                return stamp;
+            }
+            else if (m == RUNIT && a != 0L) {
+                if (U.compareAndSwapLong(this, STATE, s,
+                                         next = s - RUNIT + WBIT))
+                    return next;
+            }
+            else
+                break;
+        }
+        return 0L;
+    }
+
+    /**
+     * If the lock state matches the given stamp, atomically performs one of
+     * the following actions. If the stamp represents holding a write
+     * lock, releases it and obtains a read lock.  Or, if a read lock,
+     * returns it. Or, if an optimistic read, acquires a read lock and
+     * returns a read stamp only if immediately available. This method
+     * returns zero in all other cases.
+     *
+     * @param stamp a stamp
+     * @return a valid read stamp, or zero on failure
+     */
+    public long tryConvertToReadLock(long stamp) {
+        long a = stamp & ABITS, m, s, next; WNode h;
+        while (((s = state) & SBITS) == (stamp & SBITS)) {
+            if ((m = s & ABITS) == 0L) {
+                if (a != 0L)
+                    break;
+                else if (m < RFULL) {
+                    if (U.compareAndSwapLong(this, STATE, s, next = s + RUNIT))
+                        return next;
+                }
+                else if ((next = tryIncReaderOverflow(s)) != 0L)
+                    return next;
+            }
+            else if (m == WBIT) {
+                if (a != m)
+                    break;
+                U.putLongVolatile(this, STATE, next = s + (WBIT + RUNIT));
+                if ((h = whead) != null && h.status != 0)
+                    release(h);
+                return next;
+            }
+            else if (a != 0L && a < WBIT)
+                return stamp;
+            else
+                break;
+        }
+        return 0L;
+    }
+
+    /**
+     * If the lock state matches the given stamp then, atomically, if the stamp
+     * represents holding a lock, releases it and returns an
+     * observation stamp.  Or, if an optimistic read, returns it if
+     * validated. This method returns zero in all other cases, and so
+     * may be useful as a form of "tryUnlock".
+     *
+     * @param stamp a stamp
+     * @return a valid optimistic read stamp, or zero on failure
+     */
+    public long tryConvertToOptimisticRead(long stamp) {
+        long a = stamp & ABITS, m, s, next; WNode h;
+        U.loadFence();
+        for (;;) {
+            if (((s = state) & SBITS) != (stamp & SBITS))
+                break;
+            if ((m = s & ABITS) == 0L) {
+                if (a != 0L)
+                    break;
+                return s;
+            }
+            else if (m == WBIT) {
+                if (a != m)
+                    break;
+                U.putLongVolatile(this, STATE,
+                                  next = (s += WBIT) == 0L ? ORIGIN : s);
+                if ((h = whead) != null && h.status != 0)
+                    release(h);
+                return next;
+            }
+            else if (a == 0L || a >= WBIT)
+                break;
+            else if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, next = s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    return next & SBITS;
+                }
+            }
+            else if ((next = tryDecReaderOverflow(s)) != 0L)
+                return next & SBITS;
+        }
+        return 0L;
+    }
+
+    /**
+     * Releases the write lock if it is held, without requiring a
+     * stamp value. This method may be useful for recovery after
+     * errors.
+     *
+     * @return {@code true} if the lock was held, else false
+     */
+    public boolean tryUnlockWrite() {
+        long s; WNode h;
+        if (((s = state) & WBIT) != 0L) {
+            U.putLongVolatile(this, STATE, (s += WBIT) == 0L ? ORIGIN : s);
+            if ((h = whead) != null && h.status != 0)
+                release(h);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Releases one hold of the read lock if it is held, without
+     * requiring a stamp value. This method may be useful for recovery
+     * after errors.
+     *
+     * @return {@code true} if the read lock was held, else false
+     */
+    public boolean tryUnlockRead() {
+        long s, m; WNode h;
+        while ((m = (s = state) & ABITS) != 0L && m < WBIT) {
+            if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    return true;
+                }
+            }
+            else if (tryDecReaderOverflow(s) != 0L)
+                return true;
+        }
+        return false;
+    }
+
+    // status monitoring methods
+
+    /**
+     * Returns combined state-held and overflow read count for given
+     * state s.
+     */
+    private int getReadLockCount(long s) {
+        long readers;
+        if ((readers = s & RBITS) >= RFULL)
+            readers = RFULL + readerOverflow;
+        return (int) readers;
+    }
+
+    /**
+     * Returns {@code true} if the lock is currently held exclusively.
+     *
+     * @return {@code true} if the lock is currently held exclusively
+     */
+    public boolean isWriteLocked() {
+        return (state & WBIT) != 0L;
+    }
+
+    /**
+     * Returns {@code true} if the lock is currently held non-exclusively.
+     *
+     * @return {@code true} if the lock is currently held non-exclusively
+     */
+    public boolean isReadLocked() {
+        return (state & RBITS) != 0L;
+    }
+
+    /**
+     * Queries the number of read locks held for this lock. This
+     * method is designed for use in monitoring system state, not for
+     * synchronization control.
+     * @return the number of read locks held
+     */
+    public int getReadLockCount() {
+        return getReadLockCount(state);
+    }
+
+    /**
+     * Returns a string identifying this lock, as well as its lock
+     * state.  The state, in brackets, includes the String {@code
+     * "Unlocked"} or the String {@code "Write-locked"} or the String
+     * {@code "Read-locks:"} followed by the current number of
+     * read-locks held.
+     *
+     * @return a string identifying this lock, as well as its lock state
+     */
+    public String toString() {
+        long s = state;
+        return super.toString() +
+            ((s & ABITS) == 0L ? "[Unlocked]" :
+             (s & WBIT) != 0L ? "[Write-locked]" :
+             "[Read-locks:" + getReadLockCount(s) + "]");
+    }
+
+    // views
+
+    /**
+     * Returns a plain {@link Lock} view of this StampedLock in which
+     * the {@link Lock#lock} method is mapped to {@link #readLock},
+     * and similarly for other methods. The returned Lock does not
+     * support a {@link Condition}; method {@link
+     * Lock#newCondition()} throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @return the lock
+     */
+    public Lock asReadLock() {
+        ReadLockView v;
+        return ((v = readLockView) != null ? v :
+                (readLockView = new ReadLockView()));
+    }
+
+    /**
+     * Returns a plain {@link Lock} view of this StampedLock in which
+     * the {@link Lock#lock} method is mapped to {@link #writeLock},
+     * and similarly for other methods. The returned Lock does not
+     * support a {@link Condition}; method {@link
+     * Lock#newCondition()} throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @return the lock
+     */
+    public Lock asWriteLock() {
+        WriteLockView v;
+        return ((v = writeLockView) != null ? v :
+                (writeLockView = new WriteLockView()));
+    }
+
+    /**
+     * Returns a {@link ReadWriteLock} view of this StampedLock in
+     * which the {@link ReadWriteLock#readLock()} method is mapped to
+     * {@link #asReadLock()}, and {@link ReadWriteLock#writeLock()} to
+     * {@link #asWriteLock()}.
+     *
+     * @return the lock
+     */
+    public ReadWriteLock asReadWriteLock() {
+        ReadWriteLockView v;
+        return ((v = readWriteLockView) != null ? v :
+                (readWriteLockView = new ReadWriteLockView()));
+    }
+
+    // view classes
+
+    final class ReadLockView implements Lock {
+        public void lock() { readLock(); }
+        public void lockInterruptibly() throws InterruptedException {
+            readLockInterruptibly();
+        }
+        public boolean tryLock() { return tryReadLock() != 0L; }
+        public boolean tryLock(long time, TimeUnit unit)
+            throws InterruptedException {
+            return tryReadLock(time, unit) != 0L;
+        }
+        public void unlock() { unstampedUnlockRead(); }
+        public Condition newCondition() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    final class WriteLockView implements Lock {
+        public void lock() { writeLock(); }
+        public void lockInterruptibly() throws InterruptedException {
+            writeLockInterruptibly();
+        }
+        public boolean tryLock() { return tryWriteLock() != 0L; }
+        public boolean tryLock(long time, TimeUnit unit)
+            throws InterruptedException {
+            return tryWriteLock(time, unit) != 0L;
+        }
+        public void unlock() { unstampedUnlockWrite(); }
+        public Condition newCondition() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    final class ReadWriteLockView implements ReadWriteLock {
+        public Lock readLock() { return asReadLock(); }
+        public Lock writeLock() { return asWriteLock(); }
+    }
+
+    // Unlock methods without stamp argument checks for view classes.
+    // Needed because view-class lock methods throw away stamps.
+
+    final void unstampedUnlockWrite() {
+        WNode h; long s;
+        if (((s = state) & WBIT) == 0L)
+            throw new IllegalMonitorStateException();
+        U.putLongVolatile(this, STATE, (s += WBIT) == 0L ? ORIGIN : s);
+        if ((h = whead) != null && h.status != 0)
+            release(h);
+    }
+
+    final void unstampedUnlockRead() {
+        for (;;) {
+            long s, m; WNode h;
+            if ((m = (s = state) & ABITS) == 0L || m >= WBIT)
+                throw new IllegalMonitorStateException();
+            else if (m < RFULL) {
+                if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
+                    if (m == RUNIT && (h = whead) != null && h.status != 0)
+                        release(h);
+                    break;
+                }
+            }
+            else if (tryDecReaderOverflow(s) != 0L)
+                break;
+        }
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        U.putLongVolatile(this, STATE, ORIGIN); // reset to unlocked state
+    }
+
+    // internals
+
+    /**
+     * Tries to increment readerOverflow by first setting state
+     * access bits value to RBITS, indicating hold of spinlock,
+     * then updating, then releasing.
+     *
+     * @param s a reader overflow stamp: (s & ABITS) >= RFULL
+     * @return new stamp on success, else zero
+     */
+    private long tryIncReaderOverflow(long s) {
+        // assert (s & ABITS) >= RFULL;
+        if ((s & ABITS) == RFULL) {
+            if (U.compareAndSwapLong(this, STATE, s, s | RBITS)) {
+                ++readerOverflow;
+                U.putLongVolatile(this, STATE, s);
+                return s;
+            }
+        }
+        else if ((LockSupport.nextSecondarySeed() &
+                  OVERFLOW_YIELD_RATE) == 0)
+            Thread.yield();
+        return 0L;
+    }
+
+    /**
+     * Tries to decrement readerOverflow.
+     *
+     * @param s a reader overflow stamp: (s & ABITS) >= RFULL
+     * @return new stamp on success, else zero
+     */
+    private long tryDecReaderOverflow(long s) {
+        // assert (s & ABITS) >= RFULL;
+        if ((s & ABITS) == RFULL) {
+            if (U.compareAndSwapLong(this, STATE, s, s | RBITS)) {
+                int r; long next;
+                if ((r = readerOverflow) > 0) {
+                    readerOverflow = r - 1;
+                    next = s;
+                }
+                else
+                    next = s - RUNIT;
+                U.putLongVolatile(this, STATE, next);
+                return next;
+            }
+        }
+        else if ((LockSupport.nextSecondarySeed() &
+                  OVERFLOW_YIELD_RATE) == 0)
+            Thread.yield();
+        return 0L;
+    }
+
+    /**
+     * Wakes up the successor of h (normally whead). This is normally
+     * just h.next, but may require traversal from wtail if next
+     * pointers are lagging. This may fail to wake up an acquiring
+     * thread when one or more have been cancelled, but the cancel
+     * methods themselves provide extra safeguards to ensure liveness.
+     */
+    private void release(WNode h) {
+        if (h != null) {
+            WNode q; Thread w;
+            U.compareAndSwapInt(h, WSTATUS, WAITING, 0);
+            if ((q = h.next) == null || q.status == CANCELLED) {
+                for (WNode t = wtail; t != null && t != h; t = t.prev)
+                    if (t.status <= 0)
+                        q = t;
+            }
+            if (q != null && (w = q.thread) != null)
+                U.unpark(w);
+        }
+    }
+
+    /**
+     * See above for explanation.
+     *
+     * @param interruptible true if should check interrupts and if so
+     * return INTERRUPTED
+     * @param deadline if nonzero, the System.nanoTime value to timeout
+     * at (and return zero)
+     * @return next state, or INTERRUPTED
+     */
+    private long acquireWrite(boolean interruptible, long deadline) {
+        WNode node = null, p;
+        for (int spins = -1;;) { // spin while enqueuing
+            long m, s, ns;
+            if ((m = (s = state) & ABITS) == 0L) {
+                if (U.compareAndSwapLong(this, STATE, s, ns = s + WBIT))
+                    return ns;
+            }
+            else if (spins < 0)
+                spins = (m == WBIT && wtail == whead) ? SPINS : 0;
+            else if (spins > 0) {
+                if (LockSupport.nextSecondarySeed() >= 0)
+                    --spins;
+            }
+            else if ((p = wtail) == null) { // initialize queue
+                WNode hd = new WNode(WMODE, null);
+                if (U.compareAndSwapObject(this, WHEAD, null, hd))
+                    wtail = hd;
+            }
+            else if (node == null)
+                node = new WNode(WMODE, p);
+            else if (node.prev != p)
+                node.prev = p;
+            else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
+                p.next = node;
+                break;
+            }
+        }
+
+        boolean wasInterrupted = false;
+        for (int spins = -1;;) {
+            WNode h, np, pp; int ps;
+            if ((h = whead) == p) {
+                if (spins < 0)
+                    spins = HEAD_SPINS;
+                else if (spins < MAX_HEAD_SPINS)
+                    spins <<= 1;
+                for (int k = spins;;) { // spin at head
+                    long s, ns;
+                    if (((s = state) & ABITS) == 0L) {
+                        if (U.compareAndSwapLong(this, STATE, s,
+                                                 ns = s + WBIT)) {
+                            whead = node;
+                            node.prev = null;
+                            if (wasInterrupted)
+                                Thread.currentThread().interrupt();
+                            return ns;
+                        }
+                    }
+                    else if (LockSupport.nextSecondarySeed() >= 0 &&
+                             --k <= 0)
+                        break;
+                }
+            }
+            else if (h != null) { // help release stale waiters
+                WNode c; Thread w;
+                while ((c = h.cowait) != null) {
+                    if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) &&
+                        (w = c.thread) != null)
+                        U.unpark(w);
+                }
+            }
+            if (whead == h) {
+                if ((np = node.prev) != p) {
+                    if (np != null)
+                        (p = np).next = node;   // stale
+                }
+                else if ((ps = p.status) == 0)
+                    U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
+                else if (ps == CANCELLED) {
+                    if ((pp = p.prev) != null) {
+                        node.prev = pp;
+                        pp.next = node;
+                    }
+                }
+                else {
+                    long time; // 0 argument to park means no timeout
+                    if (deadline == 0L)
+                        time = 0L;
+                    else if ((time = deadline - System.nanoTime()) <= 0L)
+                        return cancelWaiter(node, node, false);
+                    Thread wt = Thread.currentThread();
+                    U.putObject(wt, PARKBLOCKER, this);
+                    node.thread = wt;
+                    if (p.status < 0 && (p != h || (state & ABITS) != 0L) &&
+                        whead == h && node.prev == p)
+                        U.park(false, time);  // emulate LockSupport.park
+                    node.thread = null;
+                    U.putObject(wt, PARKBLOCKER, null);
+                    if (Thread.interrupted()) {
+                        if (interruptible)
+                            return cancelWaiter(node, node, true);
+                        wasInterrupted = true;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * See above for explanation.
+     *
+     * @param interruptible true if should check interrupts and if so
+     * return INTERRUPTED
+     * @param deadline if nonzero, the System.nanoTime value to timeout
+     * at (and return zero)
+     * @return next state, or INTERRUPTED
+     */
+    private long acquireRead(boolean interruptible, long deadline) {
+        boolean wasInterrupted = false;
+        WNode node = null, p;
+        for (int spins = -1;;) {
+            WNode h;
+            if ((h = whead) == (p = wtail)) {
+                for (long m, s, ns;;) {
+                    if ((m = (s = state) & ABITS) < RFULL ?
+                        U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
+                        (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
+                        if (wasInterrupted)
+                            Thread.currentThread().interrupt();
+                        return ns;
+                    }
+                    else if (m >= WBIT) {
+                        if (spins > 0) {
+                            if (LockSupport.nextSecondarySeed() >= 0)
+                                --spins;
+                        }
+                        else {
+                            if (spins == 0) {
+                                WNode nh = whead, np = wtail;
+                                if ((nh == h && np == p) || (h = nh) != (p = np))
+                                    break;
+                            }
+                            spins = SPINS;
+                        }
+                    }
+                }
+            }
+            if (p == null) { // initialize queue
+                WNode hd = new WNode(WMODE, null);
+                if (U.compareAndSwapObject(this, WHEAD, null, hd))
+                    wtail = hd;
+            }
+            else if (node == null)
+                node = new WNode(RMODE, p);
+            else if (h == p || p.mode != RMODE) {
+                if (node.prev != p)
+                    node.prev = p;
+                else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
+                    p.next = node;
+                    break;
+                }
+            }
+            else if (!U.compareAndSwapObject(p, WCOWAIT,
+                                             node.cowait = p.cowait, node))
+                node.cowait = null;
+            else {
+                for (;;) {
+                    WNode pp, c; Thread w;
+                    if ((h = whead) != null && (c = h.cowait) != null &&
+                        U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) &&
+                        (w = c.thread) != null) // help release
+                        U.unpark(w);
+                    if (h == (pp = p.prev) || h == p || pp == null) {
+                        long m, s, ns;
+                        do {
+                            if ((m = (s = state) & ABITS) < RFULL ?
+                                U.compareAndSwapLong(this, STATE, s,
+                                                     ns = s + RUNIT) :
+                                (m < WBIT &&
+                                 (ns = tryIncReaderOverflow(s)) != 0L)) {
+                                if (wasInterrupted)
+                                    Thread.currentThread().interrupt();
+                                return ns;
+                            }
+                        } while (m < WBIT);
+                    }
+                    if (whead == h && p.prev == pp) {
+                        long time;
+                        if (pp == null || h == p || p.status > 0) {
+                            node = null; // throw away
+                            break;
+                        }
+                        if (deadline == 0L)
+                            time = 0L;
+                        else if ((time = deadline - System.nanoTime()) <= 0L) {
+                            if (wasInterrupted)
+                                Thread.currentThread().interrupt();
+                            return cancelWaiter(node, p, false);
+                        }
+                        Thread wt = Thread.currentThread();
+                        U.putObject(wt, PARKBLOCKER, this);
+                        node.thread = wt;
+                        if ((h != pp || (state & ABITS) == WBIT) &&
+                            whead == h && p.prev == pp)
+                            U.park(false, time);
+                        node.thread = null;
+                        U.putObject(wt, PARKBLOCKER, null);
+                        if (Thread.interrupted()) {
+                            if (interruptible)
+                                return cancelWaiter(node, p, true);
+                            wasInterrupted = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        for (int spins = -1;;) {
+            WNode h, np, pp; int ps;
+            if ((h = whead) == p) {
+                if (spins < 0)
+                    spins = HEAD_SPINS;
+                else if (spins < MAX_HEAD_SPINS)
+                    spins <<= 1;
+                for (int k = spins;;) { // spin at head
+                    long m, s, ns;
+                    if ((m = (s = state) & ABITS) < RFULL ?
+                        U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
+                        (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
+                        WNode c; Thread w;
+                        whead = node;
+                        node.prev = null;
+                        while ((c = node.cowait) != null) {
+                            if (U.compareAndSwapObject(node, WCOWAIT,
+                                                       c, c.cowait) &&
+                                (w = c.thread) != null)
+                                U.unpark(w);
+                        }
+                        if (wasInterrupted)
+                            Thread.currentThread().interrupt();
+                        return ns;
+                    }
+                    else if (m >= WBIT &&
+                             LockSupport.nextSecondarySeed() >= 0 && --k <= 0)
+                        break;
+                }
+            }
+            else if (h != null) {
+                WNode c; Thread w;
+                while ((c = h.cowait) != null) {
+                    if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) &&
+                        (w = c.thread) != null)
+                        U.unpark(w);
+                }
+            }
+            if (whead == h) {
+                if ((np = node.prev) != p) {
+                    if (np != null)
+                        (p = np).next = node;   // stale
+                }
+                else if ((ps = p.status) == 0)
+                    U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
+                else if (ps == CANCELLED) {
+                    if ((pp = p.prev) != null) {
+                        node.prev = pp;
+                        pp.next = node;
+                    }
+                }
+                else {
+                    long time;
+                    if (deadline == 0L)
+                        time = 0L;
+                    else if ((time = deadline - System.nanoTime()) <= 0L)
+                        return cancelWaiter(node, node, false);
+                    Thread wt = Thread.currentThread();
+                    U.putObject(wt, PARKBLOCKER, this);
+                    node.thread = wt;
+                    if (p.status < 0 &&
+                        (p != h || (state & ABITS) == WBIT) &&
+                        whead == h && node.prev == p)
+                        U.park(false, time);
+                    node.thread = null;
+                    U.putObject(wt, PARKBLOCKER, null);
+                    if (Thread.interrupted()) {
+                        if (interruptible)
+                            return cancelWaiter(node, node, true);
+                        wasInterrupted = true;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * If node non-null, forces cancel status and unsplices it from
+     * queue if possible and wakes up any cowaiters (of the node, or
+     * group, as applicable), and in any case helps release current
+     * first waiter if lock is free. (Calling with null arguments
+     * serves as a conditional form of release, which is not currently
+     * needed but may be needed under possible future cancellation
+     * policies). This is a variant of cancellation methods in
+     * AbstractQueuedSynchronizer (see its detailed explanation in AQS
+     * internal documentation).
+     *
+     * @param node if nonnull, the waiter
+     * @param group either node or the group node is cowaiting with
+     * @param interrupted if already interrupted
+     * @return INTERRUPTED if interrupted or Thread.interrupted, else zero
+     */
+    private long cancelWaiter(WNode node, WNode group, boolean interrupted) {
+        if (node != null && group != null) {
+            Thread w;
+            node.status = CANCELLED;
+            // unsplice cancelled nodes from group
+            for (WNode p = group, q; (q = p.cowait) != null;) {
+                if (q.status == CANCELLED) {
+                    U.compareAndSwapObject(p, WCOWAIT, q, q.cowait);
+                    p = group; // restart
+                }
+                else
+                    p = q;
+            }
+            if (group == node) {
+                for (WNode r = group.cowait; r != null; r = r.cowait) {
+                    if ((w = r.thread) != null)
+                        U.unpark(w);       // wake up uncancelled co-waiters
+                }
+                for (WNode pred = node.prev; pred != null; ) { // unsplice
+                    WNode succ, pp;        // find valid successor
+                    while ((succ = node.next) == null ||
+                           succ.status == CANCELLED) {
+                        WNode q = null;    // find successor the slow way
+                        for (WNode t = wtail; t != null && t != node; t = t.prev)
+                            if (t.status != CANCELLED)
+                                q = t;     // don't link if succ cancelled
+                        if (succ == q ||   // ensure accurate successor
+                            U.compareAndSwapObject(node, WNEXT,
+                                                   succ, succ = q)) {
+                            if (succ == null && node == wtail)
+                                U.compareAndSwapObject(this, WTAIL, node, pred);
+                            break;
+                        }
+                    }
+                    if (pred.next == node) // unsplice pred link
+                        U.compareAndSwapObject(pred, WNEXT, node, succ);
+                    if (succ != null && (w = succ.thread) != null) {
+                        succ.thread = null;
+                        U.unpark(w);       // wake up succ to observe new pred
+                    }
+                    if (pred.status != CANCELLED || (pp = pred.prev) == null)
+                        break;
+                    node.prev = pp;        // repeat if new pred wrong/cancelled
+                    U.compareAndSwapObject(pp, WNEXT, pred, succ);
+                    pred = pp;
+                }
+            }
+        }
+        WNode h; // Possibly release first waiter
+        while ((h = whead) != null) {
+            long s; WNode q; // similar to release() but check eligibility
+            if ((q = h.next) == null || q.status == CANCELLED) {
+                for (WNode t = wtail; t != null && t != h; t = t.prev)
+                    if (t.status <= 0)
+                        q = t;
+            }
+            if (h == whead) {
+                if (q != null && h.status == 0 &&
+                    ((s = state) & ABITS) != WBIT && // waiter is eligible
+                    (s == 0L || q.mode == RMODE))
+                    release(h);
+                break;
+            }
+        }
+        return (interrupted || Thread.interrupted()) ? INTERRUPTED : 0L;
+    }
+
+    // Unsafe mechanics
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long STATE;
+    private static final long WHEAD;
+    private static final long WTAIL;
+    private static final long WNEXT;
+    private static final long WSTATUS;
+    private static final long WCOWAIT;
+    private static final long PARKBLOCKER;
+
+    static {
+        try {
+            STATE = U.objectFieldOffset
+                (StampedLock.class.getDeclaredField("state"));
+            WHEAD = U.objectFieldOffset
+                (StampedLock.class.getDeclaredField("whead"));
+            WTAIL = U.objectFieldOffset
+                (StampedLock.class.getDeclaredField("wtail"));
+
+            WSTATUS = U.objectFieldOffset
+                (WNode.class.getDeclaredField("status"));
+            WNEXT = U.objectFieldOffset
+                (WNode.class.getDeclaredField("next"));
+            WCOWAIT = U.objectFieldOffset
+                (WNode.class.getDeclaredField("cowait"));
+
+            PARKBLOCKER = U.objectFieldOffset
+                (Thread.class.getDeclaredField("parkBlocker"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+}
diff --git a/luni/src/main/java/java/util/concurrent/package-info.java b/luni/src/main/java/java/util/concurrent/package-info.java
index afc8ca4..5dc1228 100644
--- a/luni/src/main/java/java/util/concurrent/package-info.java
+++ b/luni/src/main/java/java/util/concurrent/package-info.java
@@ -181,18 +181,25 @@
  * collections are unshared, or are accessible only when
  * holding other locks.
  *
- * <p>Most concurrent Collection implementations (including most
- * Queues) also differ from the usual java.util conventions in that
- * their Iterators provide <em>weakly consistent</em> rather than
- * fast-fail traversal.  A weakly consistent iterator is thread-safe,
- * but does not necessarily freeze the collection while iterating, so
- * it may (or may not) reflect any updates since the iterator was
- * created.
+ * <p id="Weakly">Most concurrent Collection implementations
+ * (including most Queues) also differ from the usual {@code java.util}
+ * conventions in that their {@linkplain java.util.Iterator Iterators}
+ * and {@linkplain java.util.Spliterator Spliterators} provide
+ * <em>weakly consistent</em> rather than fast-fail traversal:
+ * <ul>
+ * <li>they may proceed concurrently with other operations
+ * <li>they will never throw {@link java.util.ConcurrentModificationException
+ * ConcurrentModificationException}
+ * <li>they are guaranteed to traverse elements as they existed upon
+ * construction exactly once, and may (but are not guaranteed to)
+ * reflect any modifications subsequent to construction.
+ * </ul>
  *
  * <h2 id="MemoryVisibility">Memory Consistency Properties</h2>
  *
- * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5">
- * Chapter 17 of the Java Language Specification</a> defines the
+ * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.5">
+ * Chapter 17 of
+ * <cite>The Java&trade; Language Specification</cite></a> defines the
  * <i>happens-before</i> relation on memory operations such as reads and
  * writes of shared variables.  The results of a write by one thread are
  * guaranteed to be visible to a read by another thread only if the write
diff --git a/non_openjdk_java_files.mk b/non_openjdk_java_files.mk
index 0c5502b..104a6f3 100644
--- a/non_openjdk_java_files.mk
+++ b/non_openjdk_java_files.mk
@@ -88,7 +88,10 @@
   luni/src/main/java/java/util/concurrent/BrokenBarrierException.java \
   luni/src/main/java/java/util/concurrent/Callable.java \
   luni/src/main/java/java/util/concurrent/CancellationException.java \
+  luni/src/main/java/java/util/concurrent/CompletableFuture.java \
+  luni/src/main/java/java/util/concurrent/CompletionException.java \
   luni/src/main/java/java/util/concurrent/CompletionService.java \
+  luni/src/main/java/java/util/concurrent/CompletionStage.java \
   luni/src/main/java/java/util/concurrent/ConcurrentHashMap.java \
   luni/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java \
   luni/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java \
@@ -114,6 +117,7 @@
   luni/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java \
   luni/src/main/java/java/util/concurrent/Future.java \
   luni/src/main/java/java/util/concurrent/FutureTask.java \
+  luni/src/main/java/java/util/concurrent/Helpers.java \
   luni/src/main/java/java/util/concurrent/LinkedBlockingDeque.java \
   luni/src/main/java/java/util/concurrent/LinkedBlockingQueue.java \
   luni/src/main/java/java/util/concurrent/LinkedTransferQueue.java \
@@ -148,7 +152,11 @@
   luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java \
   luni/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java \
   luni/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java \
-  luni/src/main/java/java/util/concurrent/atomic/Fences.java \
+  luni/src/main/java/java/util/concurrent/atomic/DoubleAccumulator.java \
+  luni/src/main/java/java/util/concurrent/atomic/DoubleAdder.java \
+  luni/src/main/java/java/util/concurrent/atomic/LongAccumulator.java \
+  luni/src/main/java/java/util/concurrent/atomic/LongAdder.java \
+  luni/src/main/java/java/util/concurrent/atomic/Striped64.java \
   luni/src/main/java/java/util/concurrent/atomic/package-info.java \
   luni/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java \
   luni/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java \
@@ -159,6 +167,7 @@
   luni/src/main/java/java/util/concurrent/locks/ReadWriteLock.java \
   luni/src/main/java/java/util/concurrent/locks/ReentrantLock.java \
   luni/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java \
+  luni/src/main/java/java/util/concurrent/locks/StampedLock.java \
   luni/src/main/java/java/util/concurrent/locks/package-info.java \
   luni/src/main/java/java/util/concurrent/package-info.java \
   luni/src/main/java/javax/xml/XMLConstants.java \
diff --git a/ojluni/src/main/java/java/lang/Thread.java b/ojluni/src/main/java/java/lang/Thread.java
index 2afeccf..c14022b 100755
--- a/ojluni/src/main/java/java/lang/Thread.java
+++ b/ojluni/src/main/java/java/lang/Thread.java
@@ -2050,6 +2050,25 @@
         }
     }
 
+
+    // The following three initially uninitialized fields are exclusively
+    // managed by class java.util.concurrent.ThreadLocalRandom. These
+    // fields are used to build the high-performance PRNGs in the
+    // concurrent code, and we can not risk accidental false sharing.
+    // Hence, the fields are isolated with @Contended.
+
+    /** The current seed for a ThreadLocalRandom */
+    // @sun.misc.Contended("tlr")
+    long threadLocalRandomSeed;
+
+    /** Probe hash value; nonzero if threadLocalRandomSeed initialized */
+    // @sun.misc.Contended("tlr")
+    int threadLocalRandomProbe;
+
+    /** Secondary seed isolated from public ThreadLocalRandom sequence */
+    //  @sun.misc.Contended("tlr")
+    int threadLocalRandomSecondarySeed;
+
     /* Some private helper methods */
     private native void nativeSetName(String newName);
 
diff --git a/ojluni/src/main/java/java/util/AbstractQueue.java b/ojluni/src/main/java/java/util/AbstractQueue.java
index ebe2700..44e11f7 100644
--- a/ojluni/src/main/java/java/util/AbstractQueue.java
+++ b/ojluni/src/main/java/java/util/AbstractQueue.java
@@ -58,7 +58,7 @@
  *
  * @since 1.5
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public abstract class AbstractQueue<E>
     extends AbstractCollection<E>
diff --git a/ojluni/src/main/java/java/util/ArrayDeque.java b/ojluni/src/main/java/java/util/ArrayDeque.java
index eb31bcc..83ae076 100644
--- a/ojluni/src/main/java/java/util/ArrayDeque.java
+++ b/ojluni/src/main/java/java/util/ArrayDeque.java
@@ -33,7 +33,7 @@
 
 package java.util;
 
-import java.io.*;
+import java.io.Serializable;
 import java.util.function.Consumer;
 
 // BEGIN android-note
@@ -81,10 +81,10 @@
  *
  * @author  Josh Bloch and Doug Lea
  * @since   1.6
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this deque
  */
 public class ArrayDeque<E> extends AbstractCollection<E>
-                           implements Deque<E>, Cloneable, java.io.Serializable
+                           implements Deque<E>, Cloneable, Serializable
 {
     /**
      * The array in which the elements of the deque are stored.
@@ -96,20 +96,20 @@
      * other.  We also guarantee that all array cells not holding
      * deque elements are always null.
      */
-    private transient Object[] elements;
+    transient Object[] elements; // non-private to simplify nested class access
 
     /**
      * The index of the element at the head of the deque (which is the
      * element that would be removed by remove() or pop()); or an
      * arbitrary number equal to tail if the deque is empty.
      */
-    private transient int head;
+    transient int head;
 
     /**
      * The index at which the next element would be added to the tail
      * of the deque (via addLast(E), add(E), or push(E)).
      */
-    private transient int tail;
+    transient int tail;
 
     /**
      * The minimum capacity that we'll use for a newly created deque.
@@ -137,8 +137,8 @@
             initialCapacity |= (initialCapacity >>> 16);
             initialCapacity++;
 
-            if (initialCapacity < 0)   // Too many elements, must back off
-                initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
+            if (initialCapacity < 0)    // Too many elements, must back off
+                initialCapacity >>>= 1; // Good luck allocating 2^30 elements
         }
         elements = new Object[initialCapacity];
     }
@@ -275,25 +275,27 @@
     }
 
     public E pollFirst() {
-        int h = head;
+        final Object[] elements = this.elements;
+        final int h = head;
         @SuppressWarnings("unchecked")
         E result = (E) elements[h];
         // Element is null if deque empty
-        if (result == null)
-            return null;
-        elements[h] = null;     // Must null out slot
-        head = (h + 1) & (elements.length - 1);
+        if (result != null) {
+            elements[h] = null; // Must null out slot
+            head = (h + 1) & (elements.length - 1);
+        }
         return result;
     }
 
     public E pollLast() {
-        int t = (tail - 1) & (elements.length - 1);
+        final Object[] elements = this.elements;
+        final int t = (tail - 1) & (elements.length - 1);
         @SuppressWarnings("unchecked")
         E result = (E) elements[t];
-        if (result == null)
-            return null;
-        elements[t] = null;
-        tail = t;
+        if (result != null) {
+            elements[t] = null;
+            tail = t;
+        }
         return result;
     }
 
@@ -343,17 +345,15 @@
      * @return {@code true} if the deque contained the specified element
      */
     public boolean removeFirstOccurrence(Object o) {
-        if (o == null)
-            return false;
-        int mask = elements.length - 1;
-        int i = head;
-        Object x;
-        while ( (x = elements[i]) != null) {
-            if (o.equals(x)) {
-                delete(i);
-                return true;
+        if (o != null) {
+            int mask = elements.length - 1;
+            int i = head;
+            for (Object x; (x = elements[i]) != null; i = (i + 1) & mask) {
+                if (o.equals(x)) {
+                    delete(i);
+                    return true;
+                }
             }
-            i = (i + 1) & mask;
         }
         return false;
     }
@@ -371,17 +371,15 @@
      * @return {@code true} if the deque contained the specified element
      */
     public boolean removeLastOccurrence(Object o) {
-        if (o == null)
-            return false;
-        int mask = elements.length - 1;
-        int i = (tail - 1) & mask;
-        Object x;
-        while ( (x = elements[i]) != null) {
-            if (o.equals(x)) {
-                delete(i);
-                return true;
+        if (o != null) {
+            int mask = elements.length - 1;
+            int i = (tail - 1) & mask;
+            for (Object x; (x = elements[i]) != null; i = (i - 1) & mask) {
+                if (o.equals(x)) {
+                    delete(i);
+                    return true;
+                }
             }
-            i = (i - 1) & mask;
         }
         return false;
     }
@@ -501,11 +499,11 @@
     }
 
     private void checkInvariants() {
-        // assert elements[tail] == null;
-        // assert head == tail ? elements[head] == null :
-        //     (elements[head] != null &&
-        //      elements[(tail - 1) & (elements.length - 1)] != null);
-        // assert elements[(head - 1) & (elements.length - 1)] == null;
+        assert elements[tail] == null;
+        assert head == tail ? elements[head] == null :
+            (elements[head] != null &&
+             elements[(tail - 1) & (elements.length - 1)] != null);
+        assert elements[(head - 1) & (elements.length - 1)] == null;
     }
 
     /**
@@ -518,8 +516,8 @@
      *
      * @return true if elements moved backwards
      */
-    private boolean delete(int i) {
-        //checkInvariants();
+    boolean delete(int i) {
+        checkInvariants();
         final Object[] elements = this.elements;
         final int mask = elements.length - 1;
         final int h = head;
@@ -704,15 +702,13 @@
      * @return {@code true} if this deque contains the specified element
      */
     public boolean contains(Object o) {
-        if (o == null)
-            return false;
-        int mask = elements.length - 1;
-        int i = head;
-        Object x;
-        while ( (x = elements[i]) != null) {
-            if (o.equals(x))
-                return true;
-            i = (i + 1) & mask;
+        if (o != null) {
+            int mask = elements.length - 1;
+            int i = head;
+            for (Object x; (x = elements[i]) != null; i = (i + 1) & mask) {
+                if (o.equals(x))
+                    return true;
+            }
         }
         return false;
     }
@@ -725,7 +721,7 @@
      * 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 {@code true} if this deque contained the specified element
@@ -798,7 +794,7 @@
      * The following code can be used to dump the deque into a newly
      * allocated array of {@code String}:
      *
-     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -856,6 +852,8 @@
     /**
      * Saves this deque to a stream (that is, serializes it).
      *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData The current size ({@code int}) of the deque,
      * followed by all of its elements (each an object reference) in
      * first-to-last order.
@@ -875,6 +873,10 @@
 
     /**
      * Reconstitutes this deque from a stream (that is, deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
             throws java.io.IOException, ClassNotFoundException {
@@ -913,7 +915,7 @@
         private int fence;  // -1 until first use
         private int index;  // current index, modified on traverse/split
 
-        /** Creates new spliterator covering the given array and range */
+        /** Creates new spliterator covering the given array and range. */
         DeqSpliterator(ArrayDeque<E> deq, int origin, int fence) {
             this.deq = deq;
             this.index = origin;
@@ -935,7 +937,7 @@
                 if (h > t)
                     t += n;
                 int m = ((h + t) >>> 1) & (n - 1);
-                return new DeqSpliterator<>(deq, h, index = m);
+                return new DeqSpliterator<E>(deq, h, index = m);
             }
             return null;
         }
@@ -960,7 +962,7 @@
                 throw new NullPointerException();
             Object[] a = deq.elements;
             int m = a.length - 1, f = getFence(), i = index;
-            if (i != fence) {
+            if (i != f) {
                 @SuppressWarnings("unchecked") E e = (E)a[i];
                 index = (i + 1) & m;
                 if (e == null)
diff --git a/ojluni/src/main/java/java/util/ArrayPrefixHelpers.java b/ojluni/src/main/java/java/util/ArrayPrefixHelpers.java
new file mode 100644
index 0000000..d3b5614
--- /dev/null
+++ b/ojluni/src/main/java/java/util/ArrayPrefixHelpers.java
@@ -0,0 +1,677 @@
+/*
+ * 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;
+
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.ForkJoinPool;
+import java.util.function.BinaryOperator;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.IntBinaryOperator;
+import java.util.function.LongBinaryOperator;
+
+/**
+ * ForkJoin tasks to perform Arrays.parallelPrefix operations.
+ *
+ * @author Doug Lea
+ * @since 1.8
+ */
+class ArrayPrefixHelpers {
+    private ArrayPrefixHelpers() {} // non-instantiable
+
+    /*
+     * Parallel prefix (aka cumulate, scan) task classes
+     * are based loosely on Guy Blelloch's original
+     * algorithm (http://www.cs.cmu.edu/~scandal/alg/scan.html):
+     *  Keep dividing by two to threshold segment size, and then:
+     *   Pass 1: Create tree of partial sums for each segment
+     *   Pass 2: For each segment, cumulate with offset of left sibling
+     *
+     * This version improves performance within FJ framework mainly by
+     * allowing the second pass of ready left-hand sides to proceed
+     * even if some right-hand side first passes are still executing.
+     * It also combines first and second pass for leftmost segment,
+     * and skips the first pass for rightmost segment (whose result is
+     * not needed for second pass).  It similarly manages to avoid
+     * requiring that users supply an identity basis for accumulations
+     * by tracking those segments/subtasks for which the first
+     * existing element is used as base.
+     *
+     * Managing this relies on ORing some bits in the pendingCount for
+     * phases/states: CUMULATE, SUMMED, and FINISHED. CUMULATE is the
+     * main phase bit. When false, segments compute only their sum.
+     * When true, they cumulate array elements. CUMULATE is set at
+     * root at beginning of second pass and then propagated down. But
+     * it may also be set earlier for subtrees with lo==0 (the left
+     * spine of tree). SUMMED is a one bit join count. For leafs, it
+     * is set when summed. For internal nodes, it becomes true when
+     * one child is summed.  When the second child finishes summing,
+     * we then moves up tree to trigger the cumulate phase. FINISHED
+     * is also a one bit join count. For leafs, it is set when
+     * cumulated. For internal nodes, it becomes true when one child
+     * is cumulated.  When the second child finishes cumulating, it
+     * then moves up tree, completing at the root.
+     *
+     * To better exploit locality and reduce overhead, the compute
+     * method loops starting with the current task, moving if possible
+     * to one of its subtasks rather than forking.
+     *
+     * As usual for this sort of utility, there are 4 versions, that
+     * are simple copy/paste/adapt variants of each other.  (The
+     * double and int versions differ from long version solely by
+     * replacing "long" (with case-matching)).
+     */
+
+    // see above
+    static final int CUMULATE = 1;
+    static final int SUMMED   = 2;
+    static final int FINISHED = 4;
+
+    /** The smallest subtask array partition size to use as threshold */
+    static final int MIN_PARTITION = 16;
+
+    static final class CumulateTask<T> extends CountedCompleter<Void> {
+        final T[] array;
+        final BinaryOperator<T> function;
+        CumulateTask<T> left, right;
+        T in, out;
+        final int lo, hi, origin, fence, threshold;
+
+        /** Root task constructor */
+        public CumulateTask(CumulateTask<T> parent,
+                            BinaryOperator<T> function,
+                            T[] array, int lo, int hi) {
+            super(parent);
+            this.function = function; this.array = array;
+            this.lo = this.origin = lo; this.hi = this.fence = hi;
+            int p;
+            this.threshold =
+                (p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
+                <= MIN_PARTITION ? MIN_PARTITION : p;
+        }
+
+        /** Subtask constructor */
+        CumulateTask(CumulateTask<T> parent, BinaryOperator<T> function,
+                     T[] array, int origin, int fence, int threshold,
+                     int lo, int hi) {
+            super(parent);
+            this.function = function; this.array = array;
+            this.origin = origin; this.fence = fence;
+            this.threshold = threshold;
+            this.lo = lo; this.hi = hi;
+        }
+
+        public final void compute() {
+            final BinaryOperator<T> fn;
+            final T[] a;
+            if ((fn = this.function) == null || (a = this.array) == null)
+                throw new NullPointerException();    // hoist checks
+            int th = threshold, org = origin, fnc = fence, l, h;
+            CumulateTask<T> t = this;
+            outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length) {
+                if (h - l > th) {
+                    CumulateTask<T> lt = t.left, rt = t.right, f;
+                    if (lt == null) {                // first pass
+                        int mid = (l + h) >>> 1;
+                        f = rt = t.right =
+                            new CumulateTask<T>(t, fn, a, org, fnc, th, mid, h);
+                        t = lt = t.left =
+                            new CumulateTask<T>(t, fn, a, org, fnc, th, l, mid);
+                    }
+                    else {                           // possibly refork
+                        T pin = t.in;
+                        lt.in = pin;
+                        f = t = null;
+                        if (rt != null) {
+                            T lout = lt.out;
+                            rt.in = (l == org ? lout :
+                                     fn.apply(pin, lout));
+                            for (int c;;) {
+                                if (((c = rt.getPendingCount()) & CUMULATE) != 0)
+                                    break;
+                                if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
+                                    t = rt;
+                                    break;
+                                }
+                            }
+                        }
+                        for (int c;;) {
+                            if (((c = lt.getPendingCount()) & CUMULATE) != 0)
+                                break;
+                            if (lt.compareAndSetPendingCount(c, c|CUMULATE)) {
+                                if (t != null)
+                                    f = t;
+                                t = lt;
+                                break;
+                            }
+                        }
+                        if (t == null)
+                            break;
+                    }
+                    if (f != null)
+                        f.fork();
+                }
+                else {
+                    int state; // Transition to sum, cumulate, or both
+                    for (int b;;) {
+                        if (((b = t.getPendingCount()) & FINISHED) != 0)
+                            break outer;                      // already done
+                        state = ((b & CUMULATE) != 0 ? FINISHED :
+                                 (l > org) ? SUMMED : (SUMMED|FINISHED));
+                        if (t.compareAndSetPendingCount(b, b|state))
+                            break;
+                    }
+
+                    T sum;
+                    if (state != SUMMED) {
+                        int first;
+                        if (l == org) {                       // leftmost; no in
+                            sum = a[org];
+                            first = org + 1;
+                        }
+                        else {
+                            sum = t.in;
+                            first = l;
+                        }
+                        for (int i = first; i < h; ++i)       // cumulate
+                            a[i] = sum = fn.apply(sum, a[i]);
+                    }
+                    else if (h < fnc) {                       // skip rightmost
+                        sum = a[l];
+                        for (int i = l + 1; i < h; ++i)       // sum only
+                            sum = fn.apply(sum, a[i]);
+                    }
+                    else
+                        sum = t.in;
+                    t.out = sum;
+                    for (CumulateTask<T> par;;) {             // propagate
+                        @SuppressWarnings("unchecked") CumulateTask<T> partmp
+                            = (CumulateTask<T>)t.getCompleter();
+                        if ((par = partmp) == null) {
+                            if ((state & FINISHED) != 0)      // enable join
+                                t.quietlyComplete();
+                            break outer;
+                        }
+                        int b = par.getPendingCount();
+                        if ((b & state & FINISHED) != 0)
+                            t = par;                          // both done
+                        else if ((b & state & SUMMED) != 0) { // both summed
+                            int nextState; CumulateTask<T> lt, rt;
+                            if ((lt = par.left) != null &&
+                                (rt = par.right) != null) {
+                                T lout = lt.out;
+                                par.out = (rt.hi == fnc ? lout :
+                                           fn.apply(lout, rt.out));
+                            }
+                            int refork = (((b & CUMULATE) == 0 &&
+                                           par.lo == org) ? CUMULATE : 0);
+                            if ((nextState = b|state|refork) == b ||
+                                par.compareAndSetPendingCount(b, nextState)) {
+                                state = SUMMED;               // drop finished
+                                t = par;
+                                if (refork != 0)
+                                    par.fork();
+                            }
+                        }
+                        else if (par.compareAndSetPendingCount(b, b|state))
+                            break outer;                      // sib not ready
+                    }
+                }
+            }
+        }
+        private static final long serialVersionUID = 5293554502939613543L;
+    }
+
+    static final class LongCumulateTask extends CountedCompleter<Void> {
+        final long[] array;
+        final LongBinaryOperator function;
+        LongCumulateTask left, right;
+        long in, out;
+        final int lo, hi, origin, fence, threshold;
+
+        /** Root task constructor */
+        public LongCumulateTask(LongCumulateTask parent,
+                                LongBinaryOperator function,
+                                long[] array, int lo, int hi) {
+            super(parent);
+            this.function = function; this.array = array;
+            this.lo = this.origin = lo; this.hi = this.fence = hi;
+            int p;
+            this.threshold =
+                (p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
+                <= MIN_PARTITION ? MIN_PARTITION : p;
+        }
+
+        /** Subtask constructor */
+        LongCumulateTask(LongCumulateTask parent, LongBinaryOperator function,
+                         long[] array, int origin, int fence, int threshold,
+                         int lo, int hi) {
+            super(parent);
+            this.function = function; this.array = array;
+            this.origin = origin; this.fence = fence;
+            this.threshold = threshold;
+            this.lo = lo; this.hi = hi;
+        }
+
+        public final void compute() {
+            final LongBinaryOperator fn;
+            final long[] a;
+            if ((fn = this.function) == null || (a = this.array) == null)
+                throw new NullPointerException();    // hoist checks
+            int th = threshold, org = origin, fnc = fence, l, h;
+            LongCumulateTask t = this;
+            outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length) {
+                if (h - l > th) {
+                    LongCumulateTask lt = t.left, rt = t.right, f;
+                    if (lt == null) {                // first pass
+                        int mid = (l + h) >>> 1;
+                        f = rt = t.right =
+                            new LongCumulateTask(t, fn, a, org, fnc, th, mid, h);
+                        t = lt = t.left =
+                            new LongCumulateTask(t, fn, a, org, fnc, th, l, mid);
+                    }
+                    else {                           // possibly refork
+                        long pin = t.in;
+                        lt.in = pin;
+                        f = t = null;
+                        if (rt != null) {
+                            long lout = lt.out;
+                            rt.in = (l == org ? lout :
+                                     fn.applyAsLong(pin, lout));
+                            for (int c;;) {
+                                if (((c = rt.getPendingCount()) & CUMULATE) != 0)
+                                    break;
+                                if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
+                                    t = rt;
+                                    break;
+                                }
+                            }
+                        }
+                        for (int c;;) {
+                            if (((c = lt.getPendingCount()) & CUMULATE) != 0)
+                                break;
+                            if (lt.compareAndSetPendingCount(c, c|CUMULATE)) {
+                                if (t != null)
+                                    f = t;
+                                t = lt;
+                                break;
+                            }
+                        }
+                        if (t == null)
+                            break;
+                    }
+                    if (f != null)
+                        f.fork();
+                }
+                else {
+                    int state; // Transition to sum, cumulate, or both
+                    for (int b;;) {
+                        if (((b = t.getPendingCount()) & FINISHED) != 0)
+                            break outer;                      // already done
+                        state = ((b & CUMULATE) != 0 ? FINISHED :
+                                 (l > org) ? SUMMED : (SUMMED|FINISHED));
+                        if (t.compareAndSetPendingCount(b, b|state))
+                            break;
+                    }
+
+                    long sum;
+                    if (state != SUMMED) {
+                        int first;
+                        if (l == org) {                       // leftmost; no in
+                            sum = a[org];
+                            first = org + 1;
+                        }
+                        else {
+                            sum = t.in;
+                            first = l;
+                        }
+                        for (int i = first; i < h; ++i)       // cumulate
+                            a[i] = sum = fn.applyAsLong(sum, a[i]);
+                    }
+                    else if (h < fnc) {                       // skip rightmost
+                        sum = a[l];
+                        for (int i = l + 1; i < h; ++i)       // sum only
+                            sum = fn.applyAsLong(sum, a[i]);
+                    }
+                    else
+                        sum = t.in;
+                    t.out = sum;
+                    for (LongCumulateTask par;;) {            // propagate
+                        if ((par = (LongCumulateTask)t.getCompleter()) == null) {
+                            if ((state & FINISHED) != 0)      // enable join
+                                t.quietlyComplete();
+                            break outer;
+                        }
+                        int b = par.getPendingCount();
+                        if ((b & state & FINISHED) != 0)
+                            t = par;                          // both done
+                        else if ((b & state & SUMMED) != 0) { // both summed
+                            int nextState; LongCumulateTask lt, rt;
+                            if ((lt = par.left) != null &&
+                                (rt = par.right) != null) {
+                                long lout = lt.out;
+                                par.out = (rt.hi == fnc ? lout :
+                                           fn.applyAsLong(lout, rt.out));
+                            }
+                            int refork = (((b & CUMULATE) == 0 &&
+                                           par.lo == org) ? CUMULATE : 0);
+                            if ((nextState = b|state|refork) == b ||
+                                par.compareAndSetPendingCount(b, nextState)) {
+                                state = SUMMED;               // drop finished
+                                t = par;
+                                if (refork != 0)
+                                    par.fork();
+                            }
+                        }
+                        else if (par.compareAndSetPendingCount(b, b|state))
+                            break outer;                      // sib not ready
+                    }
+                }
+            }
+        }
+        private static final long serialVersionUID = -5074099945909284273L;
+    }
+
+    static final class DoubleCumulateTask extends CountedCompleter<Void> {
+        final double[] array;
+        final DoubleBinaryOperator function;
+        DoubleCumulateTask left, right;
+        double in, out;
+        final int lo, hi, origin, fence, threshold;
+
+        /** Root task constructor */
+        public DoubleCumulateTask(DoubleCumulateTask parent,
+                                  DoubleBinaryOperator function,
+                                  double[] array, int lo, int hi) {
+            super(parent);
+            this.function = function; this.array = array;
+            this.lo = this.origin = lo; this.hi = this.fence = hi;
+            int p;
+            this.threshold =
+                (p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
+                <= MIN_PARTITION ? MIN_PARTITION : p;
+        }
+
+        /** Subtask constructor */
+        DoubleCumulateTask(DoubleCumulateTask parent, DoubleBinaryOperator function,
+                           double[] array, int origin, int fence, int threshold,
+                           int lo, int hi) {
+            super(parent);
+            this.function = function; this.array = array;
+            this.origin = origin; this.fence = fence;
+            this.threshold = threshold;
+            this.lo = lo; this.hi = hi;
+        }
+
+        public final void compute() {
+            final DoubleBinaryOperator fn;
+            final double[] a;
+            if ((fn = this.function) == null || (a = this.array) == null)
+                throw new NullPointerException();    // hoist checks
+            int th = threshold, org = origin, fnc = fence, l, h;
+            DoubleCumulateTask t = this;
+            outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length) {
+                if (h - l > th) {
+                    DoubleCumulateTask lt = t.left, rt = t.right, f;
+                    if (lt == null) {                // first pass
+                        int mid = (l + h) >>> 1;
+                        f = rt = t.right =
+                            new DoubleCumulateTask(t, fn, a, org, fnc, th, mid, h);
+                        t = lt = t.left =
+                            new DoubleCumulateTask(t, fn, a, org, fnc, th, l, mid);
+                    }
+                    else {                           // possibly refork
+                        double pin = t.in;
+                        lt.in = pin;
+                        f = t = null;
+                        if (rt != null) {
+                            double lout = lt.out;
+                            rt.in = (l == org ? lout :
+                                     fn.applyAsDouble(pin, lout));
+                            for (int c;;) {
+                                if (((c = rt.getPendingCount()) & CUMULATE) != 0)
+                                    break;
+                                if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
+                                    t = rt;
+                                    break;
+                                }
+                            }
+                        }
+                        for (int c;;) {
+                            if (((c = lt.getPendingCount()) & CUMULATE) != 0)
+                                break;
+                            if (lt.compareAndSetPendingCount(c, c|CUMULATE)) {
+                                if (t != null)
+                                    f = t;
+                                t = lt;
+                                break;
+                            }
+                        }
+                        if (t == null)
+                            break;
+                    }
+                    if (f != null)
+                        f.fork();
+                }
+                else {
+                    int state; // Transition to sum, cumulate, or both
+                    for (int b;;) {
+                        if (((b = t.getPendingCount()) & FINISHED) != 0)
+                            break outer;                      // already done
+                        state = ((b & CUMULATE) != 0 ? FINISHED :
+                                 (l > org) ? SUMMED : (SUMMED|FINISHED));
+                        if (t.compareAndSetPendingCount(b, b|state))
+                            break;
+                    }
+
+                    double sum;
+                    if (state != SUMMED) {
+                        int first;
+                        if (l == org) {                       // leftmost; no in
+                            sum = a[org];
+                            first = org + 1;
+                        }
+                        else {
+                            sum = t.in;
+                            first = l;
+                        }
+                        for (int i = first; i < h; ++i)       // cumulate
+                            a[i] = sum = fn.applyAsDouble(sum, a[i]);
+                    }
+                    else if (h < fnc) {                       // skip rightmost
+                        sum = a[l];
+                        for (int i = l + 1; i < h; ++i)       // sum only
+                            sum = fn.applyAsDouble(sum, a[i]);
+                    }
+                    else
+                        sum = t.in;
+                    t.out = sum;
+                    for (DoubleCumulateTask par;;) {            // propagate
+                        if ((par = (DoubleCumulateTask)t.getCompleter()) == null) {
+                            if ((state & FINISHED) != 0)      // enable join
+                                t.quietlyComplete();
+                            break outer;
+                        }
+                        int b = par.getPendingCount();
+                        if ((b & state & FINISHED) != 0)
+                            t = par;                          // both done
+                        else if ((b & state & SUMMED) != 0) { // both summed
+                            int nextState; DoubleCumulateTask lt, rt;
+                            if ((lt = par.left) != null &&
+                                (rt = par.right) != null) {
+                                double lout = lt.out;
+                                par.out = (rt.hi == fnc ? lout :
+                                           fn.applyAsDouble(lout, rt.out));
+                            }
+                            int refork = (((b & CUMULATE) == 0 &&
+                                           par.lo == org) ? CUMULATE : 0);
+                            if ((nextState = b|state|refork) == b ||
+                                par.compareAndSetPendingCount(b, nextState)) {
+                                state = SUMMED;               // drop finished
+                                t = par;
+                                if (refork != 0)
+                                    par.fork();
+                            }
+                        }
+                        else if (par.compareAndSetPendingCount(b, b|state))
+                            break outer;                      // sib not ready
+                    }
+                }
+            }
+        }
+        private static final long serialVersionUID = -586947823794232033L;
+    }
+
+    static final class IntCumulateTask extends CountedCompleter<Void> {
+        final int[] array;
+        final IntBinaryOperator function;
+        IntCumulateTask left, right;
+        int in, out;
+        final int lo, hi, origin, fence, threshold;
+
+        /** Root task constructor */
+        public IntCumulateTask(IntCumulateTask parent,
+                               IntBinaryOperator function,
+                               int[] array, int lo, int hi) {
+            super(parent);
+            this.function = function; this.array = array;
+            this.lo = this.origin = lo; this.hi = this.fence = hi;
+            int p;
+            this.threshold =
+                (p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
+                <= MIN_PARTITION ? MIN_PARTITION : p;
+        }
+
+        /** Subtask constructor */
+        IntCumulateTask(IntCumulateTask parent, IntBinaryOperator function,
+                        int[] array, int origin, int fence, int threshold,
+                        int lo, int hi) {
+            super(parent);
+            this.function = function; this.array = array;
+            this.origin = origin; this.fence = fence;
+            this.threshold = threshold;
+            this.lo = lo; this.hi = hi;
+        }
+
+        public final void compute() {
+            final IntBinaryOperator fn;
+            final int[] a;
+            if ((fn = this.function) == null || (a = this.array) == null)
+                throw new NullPointerException();    // hoist checks
+            int th = threshold, org = origin, fnc = fence, l, h;
+            IntCumulateTask t = this;
+            outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length) {
+                if (h - l > th) {
+                    IntCumulateTask lt = t.left, rt = t.right, f;
+                    if (lt == null) {                // first pass
+                        int mid = (l + h) >>> 1;
+                        f = rt = t.right =
+                            new IntCumulateTask(t, fn, a, org, fnc, th, mid, h);
+                        t = lt = t.left =
+                            new IntCumulateTask(t, fn, a, org, fnc, th, l, mid);
+                    }
+                    else {                           // possibly refork
+                        int pin = t.in;
+                        lt.in = pin;
+                        f = t = null;
+                        if (rt != null) {
+                            int lout = lt.out;
+                            rt.in = (l == org ? lout :
+                                     fn.applyAsInt(pin, lout));
+                            for (int c;;) {
+                                if (((c = rt.getPendingCount()) & CUMULATE) != 0)
+                                    break;
+                                if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
+                                    t = rt;
+                                    break;
+                                }
+                            }
+                        }
+                        for (int c;;) {
+                            if (((c = lt.getPendingCount()) & CUMULATE) != 0)
+                                break;
+                            if (lt.compareAndSetPendingCount(c, c|CUMULATE)) {
+                                if (t != null)
+                                    f = t;
+                                t = lt;
+                                break;
+                            }
+                        }
+                        if (t == null)
+                            break;
+                    }
+                    if (f != null)
+                        f.fork();
+                }
+                else {
+                    int state; // Transition to sum, cumulate, or both
+                    for (int b;;) {
+                        if (((b = t.getPendingCount()) & FINISHED) != 0)
+                            break outer;                      // already done
+                        state = ((b & CUMULATE) != 0 ? FINISHED :
+                                 (l > org) ? SUMMED : (SUMMED|FINISHED));
+                        if (t.compareAndSetPendingCount(b, b|state))
+                            break;
+                    }
+
+                    int sum;
+                    if (state != SUMMED) {
+                        int first;
+                        if (l == org) {                       // leftmost; no in
+                            sum = a[org];
+                            first = org + 1;
+                        }
+                        else {
+                            sum = t.in;
+                            first = l;
+                        }
+                        for (int i = first; i < h; ++i)       // cumulate
+                            a[i] = sum = fn.applyAsInt(sum, a[i]);
+                    }
+                    else if (h < fnc) {                       // skip rightmost
+                        sum = a[l];
+                        for (int i = l + 1; i < h; ++i)       // sum only
+                            sum = fn.applyAsInt(sum, a[i]);
+                    }
+                    else
+                        sum = t.in;
+                    t.out = sum;
+                    for (IntCumulateTask par;;) {            // propagate
+                        if ((par = (IntCumulateTask)t.getCompleter()) == null) {
+                            if ((state & FINISHED) != 0)      // enable join
+                                t.quietlyComplete();
+                            break outer;
+                        }
+                        int b = par.getPendingCount();
+                        if ((b & state & FINISHED) != 0)
+                            t = par;                          // both done
+                        else if ((b & state & SUMMED) != 0) { // both summed
+                            int nextState; IntCumulateTask lt, rt;
+                            if ((lt = par.left) != null &&
+                                (rt = par.right) != null) {
+                                int lout = lt.out;
+                                par.out = (rt.hi == fnc ? lout :
+                                           fn.applyAsInt(lout, rt.out));
+                            }
+                            int refork = (((b & CUMULATE) == 0 &&
+                                           par.lo == org) ? CUMULATE : 0);
+                            if ((nextState = b|state|refork) == b ||
+                                par.compareAndSetPendingCount(b, nextState)) {
+                                state = SUMMED;               // drop finished
+                                t = par;
+                                if (refork != 0)
+                                    par.fork();
+                            }
+                        }
+                        else if (par.compareAndSetPendingCount(b, b|state))
+                            break outer;                      // sib not ready
+                    }
+                }
+            }
+        }
+        private static final long serialVersionUID = 3731755594596840961L;
+    }
+}
diff --git a/ojluni/src/main/java/java/util/Deque.java b/ojluni/src/main/java/java/util/Deque.java
index f230677..9fec73b 100644
--- a/ojluni/src/main/java/java/util/Deque.java
+++ b/ojluni/src/main/java/java/util/Deque.java
@@ -59,7 +59,6 @@
  * <p>The twelve methods described above are summarized in the
  * following table:
  *
- * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
  * <caption>Summary of Deque methods</caption>
  *  <tr>
@@ -103,7 +102,6 @@
  * 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>
@@ -142,7 +140,6 @@
  * beginning of the deque.  Stack methods are precisely equivalent to
  * {@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>
@@ -190,7 +187,7 @@
  * @author Doug Lea
  * @author Josh Bloch
  * @since  1.6
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this deque
  */
 public interface Deque<E> extends Queue<E> {
     /**
@@ -346,17 +343,18 @@
      * 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 {@code e} such that
-     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
-     * (if such an element exists).
+     * {@code Objects.equals(o, e)} (if such an element exists).
      * Returns {@code true} if this deque contained the specified element
      * (or equivalently, if this deque changed as a result of the call).
      *
      * @param o element to be removed from this deque, if present
      * @return {@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 (optional)
+     *         is incompatible with this deque
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null and this
-     *         deque does not permit null elements (optional)
+     *         deque does not permit null elements
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
      */
     boolean removeFirstOccurrence(Object o);
 
@@ -364,17 +362,18 @@
      * 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 {@code e} such that
-     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
-     * (if such an element exists).
+     * {@code Objects.equals(o, e)} (if such an element exists).
      * Returns {@code true} if this deque contained the specified element
      * (or equivalently, if this deque changed as a result of the call).
      *
      * @param o element to be removed from this deque, if present
      * @return {@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 (optional)
+     *         is incompatible with this deque
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null and this
-     *         deque does not permit null elements (optional)
+     *         deque does not permit null elements
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
      */
     boolean removeLastOccurrence(Object o);
 
@@ -519,8 +518,7 @@
      * 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 {@code e} such that
-     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
-     * (if such an element exists).
+     * {@code Objects.equals(o, e)} (if such an element exists).
      * Returns {@code true} if this deque contained the specified element
      * (or equivalently, if this deque changed as a result of the call).
      *
@@ -529,24 +527,27 @@
      * @param o element to be removed from this deque, if present
      * @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 (optional)
+     *         is incompatible with this deque
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null and this
-     *         deque does not permit null elements (optional)
+     *         deque does not permit null elements
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
      */
     boolean remove(Object o);
 
     /**
      * 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>.
+     * at least one element {@code e} such that {@code Objects.equals(o, e)}.
      *
      * @param o element whose presence in this deque is to be tested
      * @return {@code true} if this deque contains the specified element
-     * @throws ClassCastException if the type of the specified element
-     *         is incompatible with this deque (optional)
+     * @throws ClassCastException if the class of the specified element
+     *         is incompatible with this deque
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
      * @throws NullPointerException if the specified element is null and this
-     *         deque does not permit null elements (optional)
+     *         deque does not permit null elements
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
      */
     boolean contains(Object o);
 
@@ -555,7 +556,7 @@
      *
      * @return the number of elements in this deque
      */
-    public int size();
+    int size();
 
     /**
      * Returns an iterator over the elements in this deque in proper sequence.
diff --git a/ojluni/src/main/java/java/util/Map.java b/ojluni/src/main/java/java/util/Map.java
old mode 100755
new mode 100644
index f59b5a9..74ba701
--- a/ojluni/src/main/java/java/util/Map.java
+++ b/ojluni/src/main/java/java/util/Map.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,40 +25,43 @@
 
 package java.util;
 
-
-import java.io.Serializable;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.Function;
+import java.io.Serializable;
 
+// BEGIN android-note
+// removed link to collections framework docs
+// removed java 9 methods
+// END android-note
 
 /**
  * An object that maps keys to values.  A map cannot contain duplicate keys;
  * each key can map to at most one value.
  *
- * <p>This interface takes the place of the <tt>Dictionary</tt> class, which
+ * <p>This interface takes the place of the {@code Dictionary} class, which
  * was a totally abstract class rather than an interface.
  *
- * <p>The <tt>Map</tt> interface provides three <i>collection views</i>, which
+ * <p>The {@code Map} interface provides three <i>collection views</i>, which
  * allow a map's contents to be viewed as a set of keys, collection of values,
  * or set of key-value mappings.  The <i>order</i> of a map is defined as
  * the order in which the iterators on the map's collection views return their
- * elements.  Some map implementations, like the <tt>TreeMap</tt> class, make
- * specific guarantees as to their order; others, like the <tt>HashMap</tt>
+ * elements.  Some map implementations, like the {@code TreeMap} class, make
+ * specific guarantees as to their order; others, like the {@code HashMap}
  * class, do not.
  *
  * <p>Note: great care must be exercised if mutable objects are used as map
  * keys.  The behavior of a map is not specified if the value of an object is
- * changed in a manner that affects <tt>equals</tt> comparisons while the
+ * changed in a manner that affects {@code equals} comparisons while the
  * object is a key in the map.  A special case of this prohibition is that it
  * is not permissible for a map to contain itself as a key.  While it is
  * permissible for a map to contain itself as a value, extreme caution is
- * advised: the <tt>equals</tt> and <tt>hashCode</tt> methods are no longer
+ * advised: the {@code equals} and {@code hashCode} methods are no longer
  * well defined on such a map.
  *
  * <p>All general-purpose map implementation classes should provide two
  * "standard" constructors: a void (no arguments) constructor which creates an
- * empty map, and a constructor with a single argument of type <tt>Map</tt>,
+ * empty map, and a constructor with a single argument of type {@code Map},
  * which creates a new map with the same key-value mappings as its argument.
  * In effect, the latter constructor allows the user to copy any map,
  * producing an equivalent map of the desired class.  There is no way to
@@ -67,9 +70,9 @@
  *
  * <p>The "destructive" methods contained in this interface, that is, the
  * methods that modify the map on which they operate, are specified to throw
- * <tt>UnsupportedOperationException</tt> if this map does not support the
+ * {@code UnsupportedOperationException} if this map does not support the
  * operation.  If this is the case, these methods may, but are not required
- * to, throw an <tt>UnsupportedOperationException</tt> if the invocation would
+ * to, throw an {@code UnsupportedOperationException} if the invocation would
  * have no effect on the map.  For example, invoking the {@link #putAll(Map)}
  * method on an unmodifiable map may, but is not required to, throw the
  * exception if the map whose mappings are to be "superimposed" is empty.
@@ -78,7 +81,7 @@
  * may contain.  For example, some implementations prohibit null keys and
  * values, and some have restrictions on the types of their keys.  Attempting
  * to insert an ineligible key or value throws an unchecked exception,
- * typically <tt>NullPointerException</tt> or <tt>ClassCastException</tt>.
+ * typically {@code NullPointerException} or {@code ClassCastException}.
  * Attempting to query the presence of an ineligible key or value may throw an
  * exception, or it may simply return false; some implementations will exhibit
  * the former behavior and some will exhibit the latter.  More generally,
@@ -88,20 +91,16 @@
  * Such exceptions are marked as "optional" in the specification for this
  * interface.
  *
- * <p>This interface is a member of the
- * <a href="{@docRoot}/../technotes/guides/collections/index.html">
- * Java Collections Framework</a>.
- *
  * <p>Many methods in Collections Framework interfaces are defined
  * in terms of the {@link Object#equals(Object) equals} method.  For
  * example, the specification for the {@link #containsKey(Object)
- * containsKey(Object key)} method says: "returns <tt>true</tt> if and
- * only if this map contains a mapping for a key <tt>k</tt> such that
- * <tt>(key==null ? k==null : key.equals(k))</tt>." This specification should
- * <i>not</i> be construed to imply that invoking <tt>Map.containsKey</tt>
- * with a non-null argument <tt>key</tt> will cause <tt>key.equals(k)</tt> to
- * be invoked for any key <tt>k</tt>.  Implementations are free to
- * implement optimizations whereby the <tt>equals</tt> invocation is avoided,
+ * containsKey(Object key)} method says: "returns {@code true} if and
+ * only if this map contains a mapping for a key {@code k} such that
+ * {@code (key==null ? k==null : key.equals(k))}." This specification should
+ * <i>not</i> be construed to imply that invoking {@code Map.containsKey}
+ * with a non-null argument {@code key} will cause {@code key.equals(k)} to
+ * be invoked for any key {@code k}.  Implementations are free to
+ * implement optimizations whereby the {@code equals} invocation is avoided,
  * for example, by first comparing the hash codes of the two keys.  (The
  * {@link Object#hashCode()} specification guarantees that two objects with
  * unequal hash codes cannot be equal.)  More generally, implementations of
@@ -109,6 +108,13 @@
  * the specified behavior of underlying {@link Object} methods wherever the
  * implementor deems it appropriate.
  *
+ * <p>Some map operations which perform recursive traversal of the map may fail
+ * with an exception for self-referential instances where the map directly or
+ * indirectly contains itself. This includes the {@code clone()},
+ * {@code equals()}, {@code hashCode()} and {@code toString()} methods.
+ * Implementations may optionally handle the self-referential scenario, however
+ * most current implementations do not do so.
+ *
  * @param <K> the type of keys maintained by this map
  * @param <V> the type of mapped values
  *
@@ -121,34 +127,34 @@
  * @see Set
  * @since 1.2
  */
-public interface Map<K,V> {
+public interface Map<K, V> {
     // Query Operations
 
     /**
      * Returns the number of key-value mappings in this map.  If the
-     * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
-     * <tt>Integer.MAX_VALUE</tt>.
+     * map contains more than {@code Integer.MAX_VALUE} elements, returns
+     * {@code Integer.MAX_VALUE}.
      *
      * @return the number of key-value mappings in this map
      */
     int size();
 
     /**
-     * Returns <tt>true</tt> if this map contains no key-value mappings.
+     * Returns {@code true} if this map contains no key-value mappings.
      *
-     * @return <tt>true</tt> if this map contains no key-value mappings
+     * @return {@code true} if this map contains no key-value mappings
      */
     boolean isEmpty();
 
     /**
-     * Returns <tt>true</tt> if this map contains a mapping for the specified
-     * key.  More formally, returns <tt>true</tt> if and only if
-     * this map contains a mapping for a key <tt>k</tt> such that
-     * <tt>(key==null ? k==null : key.equals(k))</tt>.  (There can be
+     * Returns {@code true} if this map contains a mapping for the specified
+     * key.  More formally, returns {@code true} if and only if
+     * this map contains a mapping for a key {@code k} such that
+     * {@code Objects.equals(key, k)}.  (There can be
      * at most one such mapping.)
      *
      * @param key key whose presence in this map is to be tested
-     * @return <tt>true</tt> if this map contains a mapping for the specified
+     * @return {@code true} if this map contains a mapping for the specified
      *         key
      * @throws ClassCastException if the key is of an inappropriate type for
      *         this map
@@ -160,15 +166,15 @@
     boolean containsKey(Object key);
 
     /**
-     * Returns <tt>true</tt> if this map maps one or more keys to the
-     * specified value.  More formally, returns <tt>true</tt> if and only if
-     * this map contains at least one mapping to a value <tt>v</tt> such that
-     * <tt>(value==null ? v==null : value.equals(v))</tt>.  This operation
+     * Returns {@code true} if this map maps one or more keys to the
+     * specified value.  More formally, returns {@code true} if and only if
+     * this map contains at least one mapping to a value {@code v} such that
+     * {@code Objects.equals(value, v)}.  This operation
      * will probably require time linear in the map size for most
-     * implementations of the <tt>Map</tt> interface.
+     * implementations of the {@code Map} interface.
      *
      * @param value value whose presence in this map is to be tested
-     * @return <tt>true</tt> if this map maps one or more keys to the
+     * @return {@code true} if this map maps one or more keys to the
      *         specified value
      * @throws ClassCastException if the value is of an inappropriate type for
      *         this map
@@ -184,8 +190,9 @@
      * or {@code null} if this map contains no mapping for the key.
      *
      * <p>More formally, if this map contains a mapping from a key
-     * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
-     * key.equals(k))}, then this method returns {@code v}; otherwise
+     * {@code k} to a value {@code v} such that
+     * {@code Objects.equals(key, k)},
+     * then this method returns {@code v}; otherwise
      * it returns {@code null}.  (There can be at most one such mapping.)
      *
      * <p>If this map permits null values, then a return value of
@@ -212,18 +219,18 @@
      * Associates the specified value with the specified key in this map
      * (optional operation).  If the map previously contained a mapping for
      * the key, the old value is replaced by the specified value.  (A map
-     * <tt>m</tt> is said to contain a mapping for a key <tt>k</tt> if and only
+     * {@code m} is said to contain a mapping for a key {@code k} if and only
      * if {@link #containsKey(Object) m.containsKey(k)} would return
-     * <tt>true</tt>.)
+     * {@code true}.)
      *
      * @param key key with which the specified value is to be associated
      * @param value value to be associated with the specified key
-     * @return the previous value associated with <tt>key</tt>, or
-     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
-     *         (A <tt>null</tt> return can also indicate that the map
-     *         previously associated <tt>null</tt> with <tt>key</tt>,
-     *         if the implementation supports <tt>null</tt> values.)
-     * @throws UnsupportedOperationException if the <tt>put</tt> operation
+     * @return the previous value associated with {@code key}, or
+     *         {@code null} if there was no mapping for {@code key}.
+     *         (A {@code null} return can also indicate that the map
+     *         previously associated {@code null} with {@code key},
+     *         if the implementation supports {@code null} values.)
+     * @throws UnsupportedOperationException if the {@code put} operation
      *         is not supported by this map
      * @throws ClassCastException if the class of the specified key or value
      *         prevents it from being stored in this map
@@ -237,25 +244,25 @@
     /**
      * Removes the mapping for a key from this map if it is present
      * (optional operation).   More formally, if this map contains a mapping
-     * from key <tt>k</tt> to value <tt>v</tt> such that
-     * <code>(key==null ?  k==null : key.equals(k))</code>, that mapping
+     * from key {@code k} to value {@code v} such that
+     * {@code Objects.equals(key, k)}, that mapping
      * is removed.  (The map can contain at most one such mapping.)
      *
      * <p>Returns the value to which this map previously associated the key,
-     * or <tt>null</tt> if the map contained no mapping for the key.
+     * or {@code null} if the map contained no mapping for the key.
      *
      * <p>If this map permits null values, then a return value of
-     * <tt>null</tt> does not <i>necessarily</i> indicate that the map
+     * {@code null} does not <i>necessarily</i> indicate that the map
      * contained no mapping for the key; it's also possible that the map
-     * explicitly mapped the key to <tt>null</tt>.
+     * explicitly mapped the key to {@code null}.
      *
      * <p>The map will not contain a mapping for the specified key once the
      * call returns.
      *
      * @param key key whose mapping is to be removed from the map
-     * @return the previous value associated with <tt>key</tt>, or
-     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
-     * @throws UnsupportedOperationException if the <tt>remove</tt> operation
+     * @return the previous value associated with {@code key}, or
+     *         {@code null} if there was no mapping for {@code key}.
+     * @throws UnsupportedOperationException if the {@code remove} operation
      *         is not supported by this map
      * @throws ClassCastException if the key is of an inappropriate type for
      *         this map
@@ -273,12 +280,12 @@
      * Copies all of the mappings from the specified map to this map
      * (optional operation).  The effect of this call is equivalent to that
      * of calling {@link #put(Object,Object) put(k, v)} on this map once
-     * for each mapping from key <tt>k</tt> to value <tt>v</tt> in the
+     * for each mapping from key {@code k} to value {@code v} in the
      * specified map.  The behavior of this operation is undefined if the
      * specified map is modified while the operation is in progress.
      *
      * @param m mappings to be stored in this map
-     * @throws UnsupportedOperationException if the <tt>putAll</tt> operation
+     * @throws UnsupportedOperationException if the {@code putAll} operation
      *         is not supported by this map
      * @throws ClassCastException if the class of a key or value in the
      *         specified map prevents it from being stored in this map
@@ -294,7 +301,7 @@
      * Removes all of the mappings from this map (optional operation).
      * The map will be empty after this call returns.
      *
-     * @throws UnsupportedOperationException if the <tt>clear</tt> operation
+     * @throws UnsupportedOperationException if the {@code clear} operation
      *         is not supported by this map
      */
     void clear();
@@ -307,12 +314,12 @@
      * The set is backed by the map, so changes to the map are
      * reflected in the set, and vice-versa.  If the map is modified
      * while an iteration over the set is in progress (except through
-     * the iterator's own <tt>remove</tt> operation), the results of
+     * the iterator's own {@code remove} operation), the results of
      * the iteration are undefined.  The set supports element removal,
      * which removes the corresponding mapping from the map, via the
-     * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
-     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
-     * operations.  It does not support the <tt>add</tt> or <tt>addAll</tt>
+     * {@code Iterator.remove}, {@code Set.remove},
+     * {@code removeAll}, {@code retainAll}, and {@code clear}
+     * operations.  It does not support the {@code add} or {@code addAll}
      * operations.
      *
      * @return a set view of the keys contained in this map
@@ -324,13 +331,13 @@
      * The collection is backed by the map, so changes to the map are
      * reflected in the collection, and vice-versa.  If the map is
      * modified while an iteration over the collection is in progress
-     * (except through the iterator's own <tt>remove</tt> operation),
+     * (except through the iterator's own {@code remove} operation),
      * the results of the iteration are undefined.  The collection
      * supports element removal, which removes the corresponding
-     * mapping from the map, via the <tt>Iterator.remove</tt>,
-     * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
-     * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not
-     * support the <tt>add</tt> or <tt>addAll</tt> operations.
+     * mapping from the map, via the {@code Iterator.remove},
+     * {@code Collection.remove}, {@code removeAll},
+     * {@code retainAll} and {@code clear} operations.  It does not
+     * support the {@code add} or {@code addAll} operations.
      *
      * @return a collection view of the values contained in this map
      */
@@ -341,33 +348,33 @@
      * The set is backed by the map, so changes to the map are
      * reflected in the set, and vice-versa.  If the map is modified
      * while an iteration over the set is in progress (except through
-     * the iterator's own <tt>remove</tt> operation, or through the
-     * <tt>setValue</tt> operation on a map entry returned by the
+     * the iterator's own {@code remove} operation, or through the
+     * {@code setValue} operation on a map entry returned by the
      * iterator) the results of the iteration are undefined.  The set
      * supports element removal, which removes the corresponding
-     * mapping from the map, via the <tt>Iterator.remove</tt>,
-     * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
-     * <tt>clear</tt> operations.  It does not support the
-     * <tt>add</tt> or <tt>addAll</tt> operations.
+     * mapping from the map, via the {@code Iterator.remove},
+     * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
+     * {@code clear} operations.  It does not support the
+     * {@code add} or {@code addAll} operations.
      *
      * @return a set view of the mappings contained in this map
      */
     Set<Map.Entry<K, V>> entrySet();
 
     /**
-     * A map entry (key-value pair).  The <tt>Map.entrySet</tt> method returns
+     * A map entry (key-value pair).  The {@code Map.entrySet} method returns
      * a collection-view of the map, whose elements are of this class.  The
      * <i>only</i> way to obtain a reference to a map entry is from the
-     * iterator of this collection-view.  These <tt>Map.Entry</tt> objects are
+     * iterator of this collection-view.  These {@code Map.Entry} objects are
      * valid <i>only</i> for the duration of the iteration; more formally,
      * the behavior of a map entry is undefined if the backing map has been
      * modified after the entry was returned by the iterator, except through
-     * the <tt>setValue</tt> operation on the map entry.
+     * the {@code setValue} operation on the map entry.
      *
      * @see Map#entrySet()
      * @since 1.2
      */
-    interface Entry<K,V> {
+    interface Entry<K, V> {
         /**
          * Returns the key corresponding to this entry.
          *
@@ -381,7 +388,7 @@
         /**
          * Returns the value corresponding to this entry.  If the mapping
          * has been removed from the backing map (by the iterator's
-         * <tt>remove</tt> operation), the results of this call are undefined.
+         * {@code remove} operation), the results of this call are undefined.
          *
          * @return the value corresponding to this entry
          * @throws IllegalStateException implementations may, but are not
@@ -394,11 +401,11 @@
          * Replaces the value corresponding to this entry with the specified
          * value (optional operation).  (Writes through to the map.)  The
          * behavior of this call is undefined if the mapping has already been
-         * removed from the map (by the iterator's <tt>remove</tt> operation).
+         * removed from the map (by the iterator's {@code remove} operation).
          *
          * @param value new value to be stored in this entry
          * @return old value corresponding to the entry
-         * @throws UnsupportedOperationException if the <tt>put</tt> operation
+         * @throws UnsupportedOperationException if the {@code put} operation
          *         is not supported by the backing map
          * @throws ClassCastException if the class of the specified value
          *         prevents it from being stored in the backing map
@@ -414,34 +421,34 @@
 
         /**
          * Compares the specified object with this entry for equality.
-         * Returns <tt>true</tt> if the given object is also a map entry and
+         * Returns {@code true} if the given object is also a map entry and
          * the two entries represent the same mapping.  More formally, two
-         * entries <tt>e1</tt> and <tt>e2</tt> represent the same mapping
+         * entries {@code e1} and {@code e2} represent the same mapping
          * if<pre>
          *     (e1.getKey()==null ?
          *      e2.getKey()==null : e1.getKey().equals(e2.getKey()))  &amp;&amp;
          *     (e1.getValue()==null ?
          *      e2.getValue()==null : e1.getValue().equals(e2.getValue()))
          * </pre>
-         * This ensures that the <tt>equals</tt> method works properly across
-         * different implementations of the <tt>Map.Entry</tt> interface.
+         * This ensures that the {@code equals} method works properly across
+         * different implementations of the {@code Map.Entry} interface.
          *
          * @param o object to be compared for equality with this map entry
-         * @return <tt>true</tt> if the specified object is equal to this map
+         * @return {@code true} if the specified object is equal to this map
          *         entry
          */
         boolean equals(Object o);
 
         /**
          * Returns the hash code value for this map entry.  The hash code
-         * of a map entry <tt>e</tt> is defined to be: <pre>
+         * of a map entry {@code e} is defined to be: <pre>
          *     (e.getKey()==null   ? 0 : e.getKey().hashCode()) ^
          *     (e.getValue()==null ? 0 : e.getValue().hashCode())
          * </pre>
-         * This ensures that <tt>e1.equals(e2)</tt> implies that
-         * <tt>e1.hashCode()==e2.hashCode()</tt> for any two Entries
-         * <tt>e1</tt> and <tt>e2</tt>, as required by the general
-         * contract of <tt>Object.hashCode</tt>.
+         * This ensures that {@code e1.equals(e2)} implies that
+         * {@code e1.hashCode()==e2.hashCode()} for any two Entries
+         * {@code e1} and {@code e2}, as required by the general
+         * contract of {@code Object.hashCode}.
          *
          * @return the hash code value for this map entry
          * @see Object#hashCode()
@@ -462,12 +469,29 @@
          * @see Comparable
          * @since 1.8
          */
-        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
+        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
             return (Comparator<Map.Entry<K, V>> & Serializable)
                 (c1, c2) -> c1.getKey().compareTo(c2.getKey());
         }
 
         /**
+         * Returns a comparator that compares {@link Map.Entry} in natural order on value.
+         *
+         * <p>The returned comparator is serializable and throws {@link
+         * NullPointerException} when comparing an entry with null values.
+         *
+         * @param <K> the type of the map keys
+         * @param <V> the {@link Comparable} type of the map values
+         * @return a comparator that compares {@link Map.Entry} in natural order on value.
+         * @see Comparable
+         * @since 1.8
+         */
+        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
+            return (Comparator<Map.Entry<K, V>> & Serializable)
+                (c1, c2) -> c1.getValue().compareTo(c2.getValue());
+        }
+
+        /**
          * Returns a comparator that compares {@link Map.Entry} by key using the given
          * {@link Comparator}.
          *
@@ -485,30 +509,49 @@
             return (Comparator<Map.Entry<K, V>> & Serializable)
                 (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
         }
+
+        /**
+         * Returns a comparator that compares {@link Map.Entry} by value using the given
+         * {@link Comparator}.
+         *
+         * <p>The returned comparator is serializable if the specified comparator
+         * is also serializable.
+         *
+         * @param  <K> the type of the map keys
+         * @param  <V> the type of the map values
+         * @param  cmp the value {@link Comparator}
+         * @return a comparator that compares {@link Map.Entry} by the value.
+         * @since 1.8
+         */
+        public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
+            Objects.requireNonNull(cmp);
+            return (Comparator<Map.Entry<K, V>> & Serializable)
+                (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
+        }
     }
 
     // Comparison and hashing
 
     /**
      * Compares the specified object with this map for equality.  Returns
-     * <tt>true</tt> if the given object is also a map and the two maps
-     * represent the same mappings.  More formally, two maps <tt>m1</tt> and
-     * <tt>m2</tt> represent the same mappings if
-     * <tt>m1.entrySet().equals(m2.entrySet())</tt>.  This ensures that the
-     * <tt>equals</tt> method works properly across different implementations
-     * of the <tt>Map</tt> interface.
+     * {@code true} if the given object is also a map and the two maps
+     * represent the same mappings.  More formally, two maps {@code m1} and
+     * {@code m2} represent the same mappings if
+     * {@code m1.entrySet().equals(m2.entrySet())}.  This ensures that the
+     * {@code equals} method works properly across different implementations
+     * of the {@code Map} interface.
      *
      * @param o object to be compared for equality with this map
-     * @return <tt>true</tt> if the specified object is equal to this map
+     * @return {@code true} if the specified object is equal to this map
      */
     boolean equals(Object o);
 
     /**
      * Returns the hash code value for this map.  The hash code of a map is
      * defined to be the sum of the hash codes of each entry in the map's
-     * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>
-     * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps
-     * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of
+     * {@code entrySet()} view.  This ensures that {@code m1.equals(m2)}
+     * implies that {@code m1.hashCode()==m2.hashCode()} for any two maps
+     * {@code m1} and {@code m2}, as required by the general contract of
      * {@link Object#hashCode}.
      *
      * @return the hash code value for this map
@@ -518,6 +561,37 @@
      */
     int hashCode();
 
+    // Defaultable methods
+
+    /**
+     * Returns the value to which the specified key is mapped, or
+     * {@code defaultValue} if this map contains no mapping for the key.
+     *
+     * @implSpec
+     * The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties.
+     *
+     * @param key the key whose associated value is to be returned
+     * @param defaultValue the default mapping of the key
+     * @return the value to which the specified key is mapped, or
+     * {@code defaultValue} if this map contains no mapping for the key
+     * @throws ClassCastException if the key is of an inappropriate type for
+     * this map
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified key is null and this map
+     * does not permit null keys
+     * (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @since 1.8
+     */
+    default V getOrDefault(Object key, V defaultValue) {
+        V v;
+        return (((v = get(key)) != null) || containsKey(key))
+            ? v
+            : defaultValue;
+    }
+
     /**
      * Performs the given action for each entry in this map until all entries
      * have been processed or the action throws an exception.   Unless
@@ -551,11 +625,625 @@
             try {
                 k = entry.getKey();
                 v = entry.getValue();
-            } catch(IllegalStateException ise) {
+            } catch (IllegalStateException ise) {
                 // this usually means the entry is no longer in the map.
                 throw new ConcurrentModificationException(ise);
             }
             action.accept(k, v);
         }
     }
+
+    /**
+     * Replaces each entry's value with the result of invoking the given
+     * function on that entry until all entries have been processed or the
+     * function throws an exception.  Exceptions thrown by the function are
+     * relayed to the caller.
+     *
+     * @implSpec
+     * <p>The default implementation is equivalent to, for this {@code map}:
+     * <pre> {@code
+     * for (Map.Entry<K, V> entry : map.entrySet())
+     *     entry.setValue(function.apply(entry.getKey(), entry.getValue()));
+     * }</pre>
+     *
+     * <p>The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties.
+     *
+     * @param function the function to apply to each entry
+     * @throws UnsupportedOperationException if the {@code set} operation
+     * is not supported by this map's entry set iterator.
+     * @throws ClassCastException if the class of a replacement value
+     * prevents it from being stored in this map
+     * @throws NullPointerException if the specified function is null, or the
+     * specified replacement value is null, and this map does not permit null
+     * values
+     * @throws ClassCastException if a replacement value is of an inappropriate
+     *         type for this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if function or a replacement value is null,
+     *         and this map does not permit null keys or values
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws IllegalArgumentException if some property of a replacement value
+     *         prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws ConcurrentModificationException if an entry is found to be
+     * removed during iteration
+     * @since 1.8
+     */
+    default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
+        Objects.requireNonNull(function);
+        for (Map.Entry<K, V> entry : entrySet()) {
+            K k;
+            V v;
+            try {
+                k = entry.getKey();
+                v = entry.getValue();
+            } catch (IllegalStateException ise) {
+                // this usually means the entry is no longer in the map.
+                throw new ConcurrentModificationException(ise);
+            }
+
+            // ise thrown from function is not a cme.
+            v = function.apply(k, v);
+
+            try {
+                entry.setValue(v);
+            } catch (IllegalStateException ise) {
+                // this usually means the entry is no longer in the map.
+                throw new ConcurrentModificationException(ise);
+            }
+        }
+    }
+
+    /**
+     * If the specified key is not already associated with a value (or is mapped
+     * to {@code null}) associates it with the given value and returns
+     * {@code null}, else returns the current value.
+     *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code
+     * map}:
+     *
+     * <pre> {@code
+     * V v = map.get(key);
+     * if (v == null)
+     *     v = map.put(key, value);
+     *
+     * return v;
+     * }</pre>
+     *
+     * <p>The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param value value to be associated with the specified key
+     * @return the previous value associated with the specified key, or
+     *         {@code null} if there was no mapping for the key.
+     *         (A {@code null} return can also indicate that the map
+     *         previously associated {@code null} with the key,
+     *         if the implementation supports null values.)
+     * @throws UnsupportedOperationException if the {@code put} operation
+     *         is not supported by this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws ClassCastException if the key or value is of an inappropriate
+     *         type for this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified key or value is null,
+     *         and this map does not permit null keys or values
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @since 1.8
+     */
+    default V putIfAbsent(K key, V value) {
+        V v = get(key);
+        if (v == null) {
+            v = put(key, value);
+        }
+
+        return v;
+    }
+
+    /**
+     * Removes the entry for the specified key only if it is currently
+     * mapped to the specified value.
+     *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code map}:
+     *
+     * <pre> {@code
+     * if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
+     *     map.remove(key);
+     *     return true;
+     * } else
+     *     return false;
+     * }</pre>
+     *
+     * <p>The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties.
+     *
+     * @param key key with which the specified value is associated
+     * @param value value expected to be associated with the specified key
+     * @return {@code true} if the value was removed
+     * @throws UnsupportedOperationException if the {@code remove} operation
+     *         is not supported by this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws ClassCastException if the key or value is of an inappropriate
+     *         type for this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified key or value is null,
+     *         and this map does not permit null keys or values
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @since 1.8
+     */
+    default boolean remove(Object key, Object value) {
+        Object curValue = get(key);
+        if (!Objects.equals(curValue, value) ||
+            (curValue == null && !containsKey(key))) {
+            return false;
+        }
+        remove(key);
+        return true;
+    }
+
+    /**
+     * Replaces the entry for the specified key only if currently
+     * mapped to the specified value.
+     *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code map}:
+     *
+     * <pre> {@code
+     * if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
+     *     map.put(key, newValue);
+     *     return true;
+     * } else
+     *     return false;
+     * }</pre>
+     *
+     * The default implementation does not throw NullPointerException
+     * for maps that do not support null values if oldValue is null unless
+     * newValue is also null.
+     *
+     * <p>The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties.
+     *
+     * @param key key with which the specified value is associated
+     * @param oldValue value expected to be associated with the specified key
+     * @param newValue value to be associated with the specified key
+     * @return {@code true} if the value was replaced
+     * @throws UnsupportedOperationException if the {@code put} operation
+     *         is not supported by this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws ClassCastException if the class of a specified key or value
+     *         prevents it from being stored in this map
+     * @throws NullPointerException if a specified key or newValue is null,
+     *         and this map does not permit null keys or values
+     * @throws NullPointerException if oldValue is null and this map does not
+     *         permit null values
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws IllegalArgumentException if some property of a specified key
+     *         or value prevents it from being stored in this map
+     * @since 1.8
+     */
+    default boolean replace(K key, V oldValue, V newValue) {
+        Object curValue = get(key);
+        if (!Objects.equals(curValue, oldValue) ||
+            (curValue == null && !containsKey(key))) {
+            return false;
+        }
+        put(key, newValue);
+        return true;
+    }
+
+    /**
+     * Replaces the entry for the specified key only if it is
+     * currently mapped to some value.
+     *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code map}:
+     *
+     * <pre> {@code
+     * if (map.containsKey(key)) {
+     *     return map.put(key, value);
+     * } else
+     *     return null;
+     * }</pre>
+     *
+     * <p>The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties.
+     *
+     * @param key key with which the specified value is associated
+     * @param value value to be associated with the specified key
+     * @return the previous value associated with the specified key, or
+     *         {@code null} if there was no mapping for the key.
+     *         (A {@code null} return can also indicate that the map
+     *         previously associated {@code null} with the key,
+     *         if the implementation supports null values.)
+     * @throws UnsupportedOperationException if the {@code put} operation
+     *         is not supported by this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws ClassCastException if the class of the specified key or value
+     *         prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified key or value is null,
+     *         and this map does not permit null keys or values
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
+     * @since 1.8
+     */
+    default V replace(K key, V value) {
+        V curValue;
+        if (((curValue = get(key)) != null) || containsKey(key)) {
+            curValue = put(key, value);
+        }
+        return curValue;
+    }
+
+    /**
+     * If the specified key is not already associated with a value (or is mapped
+     * to {@code null}), attempts to compute its value using the given mapping
+     * function and enters it into this map unless {@code null}.
+     *
+     * <p>If the mapping function returns {@code null}, no mapping is recorded.
+     * If the mapping function itself throws an (unchecked) exception, the
+     * exception is rethrown, and no mapping is recorded.  The most
+     * common usage is to construct a new object serving as an initial
+     * mapped value or memoized result, as in:
+     *
+     * <pre> {@code
+     * map.computeIfAbsent(key, k -> new Value(f(k)));
+     * }</pre>
+     *
+     * <p>Or to implement a multi-value map, {@code Map<K,Collection<V>>},
+     * supporting multiple values per key:
+     *
+     * <pre> {@code
+     * map.computeIfAbsent(key, k -> new HashSet<V>()).add(v);
+     * }</pre>
+     *
+     * <p>The mapping function should not modify this map during computation.
+     *
+     * @implSpec
+     * The default implementation is equivalent to the following steps for this
+     * {@code map}, then returning the current value or {@code null} if now
+     * absent:
+     *
+     * <pre> {@code
+     * if (map.get(key) == null) {
+     *     V newValue = mappingFunction.apply(key);
+     *     if (newValue != null)
+     *         map.put(key, newValue);
+     * }
+     * }</pre>
+     *
+     * <p>The default implementation makes no guarantees about detecting if the
+     * mapping function modifies this map during computation and, if
+     * appropriate, reporting an error. Non-concurrent implementations should
+     * override this method and, on a best-effort basis, throw a
+     * {@code ConcurrentModificationException} if it is detected that the
+     * mapping function modifies this map during computation. Concurrent
+     * implementations should override this method and, on a best-effort basis,
+     * throw an {@code IllegalStateException} if it is detected that the
+     * mapping function modifies this map during computation and as a result
+     * computation would never complete.
+     *
+     * <p>The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties. In particular, all implementations of
+     * subinterface {@link java.util.concurrent.ConcurrentMap} must document
+     * whether the mapping function is applied once atomically only if the value
+     * is not present.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param mappingFunction the mapping function to compute a value
+     * @return the current (existing or computed) value associated with
+     *         the specified key, or null if the computed value is null
+     * @throws NullPointerException if the specified key is null and
+     *         this map does not support null keys, or the mappingFunction
+     *         is null
+     * @throws UnsupportedOperationException if the {@code put} operation
+     *         is not supported by this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws ClassCastException if the class of the specified key or value
+     *         prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @since 1.8
+     */
+    default V computeIfAbsent(K key,
+            Function<? super K, ? extends V> mappingFunction) {
+        Objects.requireNonNull(mappingFunction);
+        V v;
+        if ((v = get(key)) == null) {
+            V newValue;
+            if ((newValue = mappingFunction.apply(key)) != null) {
+                put(key, newValue);
+                return newValue;
+            }
+        }
+
+        return v;
+    }
+
+    /**
+     * If the value for the specified key is present and non-null, attempts to
+     * compute a new mapping given the key and its current mapped value.
+     *
+     * <p>If the remapping function returns {@code null}, the mapping is removed.
+     * If the remapping function itself throws an (unchecked) exception, the
+     * exception is rethrown, and the current mapping is left unchanged.
+     *
+     * <p>The remapping function should not modify this map during computation.
+     *
+     * @implSpec
+     * The default implementation is equivalent to performing the following
+     * steps for this {@code map}, then returning the current value or
+     * {@code null} if now absent:
+     *
+     * <pre> {@code
+     * if (map.get(key) != null) {
+     *     V oldValue = map.get(key);
+     *     V newValue = remappingFunction.apply(key, oldValue);
+     *     if (newValue != null)
+     *         map.put(key, newValue);
+     *     else
+     *         map.remove(key);
+     * }
+     * }</pre>
+     *
+     * <p>The default implementation makes no guarantees about detecting if the
+     * remapping function modifies this map during computation and, if
+     * appropriate, reporting an error. Non-concurrent implementations should
+     * override this method and, on a best-effort basis, throw a
+     * {@code ConcurrentModificationException} if it is detected that the
+     * remapping function modifies this map during computation. Concurrent
+     * implementations should override this method and, on a best-effort basis,
+     * throw an {@code IllegalStateException} if it is detected that the
+     * remapping function modifies this map during computation and as a result
+     * computation would never complete.
+     *
+     * <p>The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties. In particular, all implementations of
+     * subinterface {@link java.util.concurrent.ConcurrentMap} must document
+     * whether the remapping function is applied once atomically only if the
+     * value is not present.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param remappingFunction the remapping function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key is null and
+     *         this map does not support null keys, or the
+     *         remappingFunction is null
+     * @throws UnsupportedOperationException if the {@code put} operation
+     *         is not supported by this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws ClassCastException if the class of the specified key or value
+     *         prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @since 1.8
+     */
+    default V computeIfPresent(K key,
+            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        Objects.requireNonNull(remappingFunction);
+        V oldValue;
+        if ((oldValue = get(key)) != null) {
+            V newValue = remappingFunction.apply(key, oldValue);
+            if (newValue != null) {
+                put(key, newValue);
+                return newValue;
+            } else {
+                remove(key);
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Attempts to compute a mapping for the specified key and its current
+     * mapped value (or {@code null} if there is no current mapping). For
+     * example, to either create or append a {@code String} msg to a value
+     * mapping:
+     *
+     * <pre> {@code
+     * map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre>
+     * (Method {@link #merge merge()} is often simpler to use for such purposes.)
+     *
+     * <p>If the remapping function returns {@code null}, the mapping is removed
+     * (or remains absent if initially absent).  If the remapping function
+     * itself throws an (unchecked) exception, the exception is rethrown, and
+     * the current mapping is left unchanged.
+     *
+     * <p>The remapping function should not modify this map during computation.
+     *
+     * @implSpec
+     * The default implementation is equivalent to performing the following
+     * steps for this {@code map}, then returning the current value or
+     * {@code null} if absent:
+     *
+     * <pre> {@code
+     * V oldValue = map.get(key);
+     * V newValue = remappingFunction.apply(key, oldValue);
+     * if (oldValue != null) {
+     *    if (newValue != null)
+     *       map.put(key, newValue);
+     *    else
+     *       map.remove(key);
+     * } else {
+     *    if (newValue != null)
+     *       map.put(key, newValue);
+     *    else
+     *       return null;
+     * }
+     * }</pre>
+     *
+     * <p>The default implementation makes no guarantees about detecting if the
+     * remapping function modifies this map during computation and, if
+     * appropriate, reporting an error. Non-concurrent implementations should
+     * override this method and, on a best-effort basis, throw a
+     * {@code ConcurrentModificationException} if it is detected that the
+     * remapping function modifies this map during computation. Concurrent
+     * implementations should override this method and, on a best-effort basis,
+     * throw an {@code IllegalStateException} if it is detected that the
+     * remapping function modifies this map during computation and as a result
+     * computation would never complete.
+     *
+     * <p>The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties. In particular, all implementations of
+     * subinterface {@link java.util.concurrent.ConcurrentMap} must document
+     * whether the remapping function is applied once atomically only if the
+     * value is not present.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param remappingFunction the remapping function to compute a value
+     * @return the new value associated with the specified key, or null if none
+     * @throws NullPointerException if the specified key is null and
+     *         this map does not support null keys, or the
+     *         remappingFunction is null
+     * @throws UnsupportedOperationException if the {@code put} operation
+     *         is not supported by this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws ClassCastException if the class of the specified key or value
+     *         prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @since 1.8
+     */
+    default V compute(K key,
+            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+        Objects.requireNonNull(remappingFunction);
+        V oldValue = get(key);
+
+        V newValue = remappingFunction.apply(key, oldValue);
+        if (newValue == null) {
+            // delete mapping
+            if (oldValue != null || containsKey(key)) {
+                // something to remove
+                remove(key);
+                return null;
+            } else {
+                // nothing to do. Leave things as they were.
+                return null;
+            }
+        } else {
+            // add or replace old mapping
+            put(key, newValue);
+            return newValue;
+        }
+    }
+
+    /**
+     * If the specified key is not already associated with a value or is
+     * associated with null, associates it with the given non-null value.
+     * Otherwise, replaces the associated value with the results of the given
+     * remapping function, or removes if the result is {@code null}. This
+     * method may be of use when combining multiple mapped values for a key.
+     * For example, to either create or append a {@code String msg} to a
+     * value mapping:
+     *
+     * <pre> {@code
+     * map.merge(key, msg, String::concat)
+     * }</pre>
+     *
+     * <p>If the remapping function returns {@code null}, the mapping is removed.
+     * If the remapping function itself throws an (unchecked) exception, the
+     * exception is rethrown, and the current mapping is left unchanged.
+     *
+     * <p>The remapping function should not modify this map during computation.
+     *
+     * @implSpec
+     * The default implementation is equivalent to performing the following
+     * steps for this {@code map}, then returning the current value or
+     * {@code null} if absent:
+     *
+     * <pre> {@code
+     * V oldValue = map.get(key);
+     * V newValue = (oldValue == null) ? value :
+     *              remappingFunction.apply(oldValue, value);
+     * if (newValue == null)
+     *     map.remove(key);
+     * else
+     *     map.put(key, newValue);
+     * }</pre>
+     *
+     * <p>The default implementation makes no guarantees about detecting if the
+     * remapping function modifies this map during computation and, if
+     * appropriate, reporting an error. Non-concurrent implementations should
+     * override this method and, on a best-effort basis, throw a
+     * {@code ConcurrentModificationException} if it is detected that the
+     * remapping function modifies this map during computation. Concurrent
+     * implementations should override this method and, on a best-effort basis,
+     * throw an {@code IllegalStateException} if it is detected that the
+     * remapping function modifies this map during computation and as a result
+     * computation would never complete.
+     *
+     * <p>The default implementation makes no guarantees about synchronization
+     * or atomicity properties of this method. Any implementation providing
+     * atomicity guarantees must override this method and document its
+     * concurrency properties. In particular, all implementations of
+     * subinterface {@link java.util.concurrent.ConcurrentMap} must document
+     * whether the remapping function is applied once atomically only if the
+     * value is not present.
+     *
+     * @param key key with which the resulting value is to be associated
+     * @param value the non-null value to be merged with the existing value
+     *        associated with the key or, if no existing value or a null value
+     *        is associated with the key, to be associated with the key
+     * @param remappingFunction the remapping function to recompute a value if
+     *        present
+     * @return the new value associated with the specified key, or null if no
+     *         value is associated with the key
+     * @throws UnsupportedOperationException if the {@code put} operation
+     *         is not supported by this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws ClassCastException if the class of the specified key or value
+     *         prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @throws NullPointerException if the specified key is null and this map
+     *         does not support null keys or the value or remappingFunction is
+     *         null
+     * @since 1.8
+     */
+    default V merge(K key, V value,
+            BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+        Objects.requireNonNull(remappingFunction);
+        Objects.requireNonNull(value);
+        V oldValue = get(key);
+        V newValue = (oldValue == null) ? value :
+                   remappingFunction.apply(oldValue, value);
+        if (newValue == null) {
+            remove(key);
+        } else {
+            put(key, newValue);
+        }
+        return newValue;
+    }
 }
diff --git a/ojluni/src/main/java/java/util/NavigableMap.java b/ojluni/src/main/java/java/util/NavigableMap.java
index b0d9453..fdbc0b5 100644
--- a/ojluni/src/main/java/java/util/NavigableMap.java
+++ b/ojluni/src/main/java/java/util/NavigableMap.java
@@ -41,30 +41,32 @@
 /**
  * A {@link SortedMap} extended with navigation methods returning the
  * closest matches for given search targets. Methods
- * {@code lowerEntry}, {@code floorEntry}, {@code ceilingEntry},
- * and {@code higherEntry} return {@code Map.Entry} objects
+ * {@link #lowerEntry}, {@link #floorEntry}, {@link #ceilingEntry},
+ * and {@link #higherEntry} return {@code Map.Entry} objects
  * associated with keys respectively less than, less than or equal,
  * greater than or equal, and greater than a given key, returning
  * {@code null} if there is no such key.  Similarly, methods
- * {@code lowerKey}, {@code floorKey}, {@code ceilingKey}, and
- * {@code higherKey} return only the associated keys. All of these
+ * {@link #lowerKey}, {@link #floorKey}, {@link #ceilingKey}, and
+ * {@link #higherKey} return only the associated keys. All of these
  * methods are designed for locating, not traversing entries.
  *
  * <p>A {@code NavigableMap} may be accessed and traversed in either
- * ascending or descending key order.  The {@code descendingMap}
+ * ascending or descending key order.  The {@link #descendingMap}
  * method returns a view of the map with the senses of all relational
  * and directional methods inverted. The performance of ascending
  * operations and views is likely to be faster than that of descending
- * ones.  Methods {@code subMap}, {@code headMap},
- * and {@code tailMap} differ from the like-named {@code
- * SortedMap} methods in accepting additional arguments describing
- * whether lower and upper bounds are inclusive versus exclusive.
- * Submaps of any {@code NavigableMap} must implement the {@code
- * NavigableMap} interface.
+ * ones.  Methods
+ * {@link #subMap(Object, boolean, Object, boolean) subMap(K, boolean, K, boolean)},
+ * {@link #headMap(Object, boolean) headMap(K, boolean)}, and
+ * {@link #tailMap(Object, boolean) tailMap(K, boolean)}
+ * differ from the like-named {@code SortedMap} methods in accepting
+ * additional arguments describing whether lower and upper bounds are
+ * inclusive versus exclusive.  Submaps of any {@code NavigableMap}
+ * must implement the {@code NavigableMap} interface.
  *
- * <p>This interface additionally defines methods {@code firstEntry},
- * {@code pollFirstEntry}, {@code lastEntry}, and
- * {@code pollLastEntry} that return and/or remove the least and
+ * <p>This interface additionally defines methods {@link #firstEntry},
+ * {@link #pollFirstEntry}, {@link #lastEntry}, and
+ * {@link #pollLastEntry} that return and/or remove the least and
  * greatest mappings, if any exist, else returning {@code null}.
  *
  * <p>Implementations of entry-returning methods are expected to
@@ -83,7 +85,7 @@
  * implement {@code NavigableMap}, but extensions and implementations
  * of this interface are encouraged to override these methods to return
  * {@code NavigableMap}.  Similarly,
- * {@link #keySet()} can be overridden to return {@code NavigableSet}.
+ * {@link #keySet()} can be overridden to return {@link NavigableSet}.
  *
  * @author Doug Lea
  * @author Josh Bloch
@@ -297,7 +299,7 @@
      * Returns a view of the portion of this map whose keys range from
      * {@code fromKey} to {@code toKey}.  If {@code fromKey} and
      * {@code toKey} are equal, the returned map is empty unless
-     * {@code fromExclusive} and {@code toExclusive} are both true.  The
+     * {@code fromInclusive} and {@code toInclusive} are both true.  The
      * returned map is backed by this map, so changes in the returned map are
      * reflected in this map, and vice-versa.  The returned map supports all
      * optional map operations that this map supports.
diff --git a/ojluni/src/main/java/java/util/NavigableSet.java b/ojluni/src/main/java/java/util/NavigableSet.java
index 11a9bdb..412a07d 100644
--- a/ojluni/src/main/java/java/util/NavigableSet.java
+++ b/ojluni/src/main/java/java/util/NavigableSet.java
@@ -32,32 +32,36 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-package java.util;
-
 // BEGIN android-note
 // removed link to collections framework docs
 // END android-note
 
+package java.util;
+
 /**
  * A {@link SortedSet} extended with navigation methods reporting
- * closest matches for given search targets. Methods {@code lower},
- * {@code floor}, {@code ceiling}, and {@code higher} return elements
+ * closest matches for given search targets. Methods {@link #lower},
+ * {@link #floor}, {@link #ceiling}, and {@link #higher} return elements
  * respectively less than, less than or equal, greater than or equal,
  * and greater than a given element, returning {@code null} if there
- * is no such element.  A {@code NavigableSet} may be accessed and
- * traversed in either ascending or descending order.  The {@code
- * descendingSet} method returns a view of the set with the senses of
- * all relational and directional methods inverted. The performance of
- * ascending operations and views is likely to be faster than that of
- * descending ones.  This interface additionally defines methods
- * {@code pollFirst} and {@code pollLast} that return and remove the
- * lowest and highest element, if one exists, else returning {@code
- * null}.  Methods {@code subSet}, {@code headSet},
- * and {@code tailSet} differ from the like-named {@code
- * SortedSet} methods in accepting additional arguments describing
- * whether lower and upper bounds are inclusive versus exclusive.
- * Subsets of any {@code NavigableSet} must implement the {@code
- * NavigableSet} interface.
+ * is no such element.
+ *
+ * <p>A {@code NavigableSet} may be accessed and traversed in either
+ * ascending or descending order.  The {@link #descendingSet} method
+ * returns a view of the set with the senses of all relational and
+ * directional methods inverted. The performance of ascending
+ * operations and views is likely to be faster than that of descending
+ * ones.  This interface additionally defines methods {@link
+ * #pollFirst} and {@link #pollLast} that return and remove the lowest
+ * and highest element, if one exists, else returning {@code null}.
+ * Methods
+ * {@link #subSet(Object, boolean, Object, boolean) subSet(E, boolean, E, boolean)},
+ * {@link #headSet(Object, boolean) headSet(E, boolean)}, and
+ * {@link #tailSet(Object, boolean) tailSet(E, boolean)}
+ * differ from the like-named {@code SortedSet} methods in accepting
+ * additional arguments describing whether lower and upper bounds are
+ * inclusive versus exclusive.  Subsets of any {@code NavigableSet}
+ * must implement the {@code NavigableSet} interface.
  *
  * <p>The return values of navigation methods may be ambiguous in
  * implementations that permit {@code null} elements. However, even
@@ -191,7 +195,7 @@
      * Returns a view of the portion of this set whose elements range from
      * {@code fromElement} to {@code toElement}.  If {@code fromElement} and
      * {@code toElement} are equal, the returned set is empty unless {@code
-     * fromExclusive} and {@code toExclusive} are both true.  The returned set
+     * fromInclusive} and {@code toInclusive} are both true.  The returned set
      * is backed by this set, so changes in the returned set are reflected in
      * this set, and vice-versa.  The returned set supports all optional set
      * operations that this set supports.
diff --git a/ojluni/src/main/java/java/util/PriorityQueue.java b/ojluni/src/main/java/java/util/PriorityQueue.java
old mode 100755
new mode 100644
index b42647e..7c929bd
--- a/ojluni/src/main/java/java/util/PriorityQueue.java
+++ b/ojluni/src/main/java/java/util/PriorityQueue.java
@@ -77,7 +77,7 @@
  *
  * @since 1.5
  * @author Josh Bloch, Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public class PriorityQueue<E> extends AbstractQueue<E>
     implements java.io.Serializable {
@@ -99,7 +99,7 @@
     /**
      * The number of elements in the priority queue.
      */
-    private int size = 0;
+    int size;
 
     /**
      * The comparator, or null if priority queue uses elements'
@@ -111,7 +111,7 @@
      * The number of times this priority queue has been
      * <i>structurally modified</i>.  See AbstractList for gory details.
      */
-    transient int modCount = 0; // non-private to simplify nested class access
+    transient int modCount;     // non-private to simplify nested class access
 
     /**
      * Creates a {@code PriorityQueue} with the default initial
@@ -258,8 +258,8 @@
             a = Arrays.copyOf(a, a.length, Object[].class);
         int len = a.length;
         if (len == 1 || this.comparator != null)
-            for (int i = 0; i < len; i++)
-                if (a[i] == null)
+            for (Object e : a)
+                if (e == null)
                     throw new NullPointerException();
         this.queue = a;
         this.size = a.length;
@@ -406,7 +406,7 @@
      * @return {@code true} if this queue contains the specified element
      */
     public boolean contains(Object o) {
-        return indexOf(o) != -1;
+        return indexOf(o) >= 0;
     }
 
     /**
@@ -448,7 +448,7 @@
      * The following code can be used to dump the queue into a newly
      * allocated array of {@code String}:
      *
-     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
+     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -489,7 +489,7 @@
          * Index (into queue array) of element to be returned by
          * subsequent call to next.
          */
-        private int cursor = 0;
+        private int cursor;
 
         /**
          * Index of element returned by most recent call to next,
@@ -509,13 +509,13 @@
          * We expect that most iterations, even those involving removals,
          * will not need to store elements in this field.
          */
-        private ArrayDeque<E> forgetMeNot = null;
+        private ArrayDeque<E> forgetMeNot;
 
         /**
          * Element returned by the most recent call to next iff that
          * element was drawn from the forgetMeNot list.
          */
-        private E lastRetElt = null;
+        private E lastRetElt;
 
         /**
          * The modCount value that the iterator believes that the backing
@@ -609,8 +609,8 @@
      * avoid missing traversing elements.
      */
     @SuppressWarnings("unchecked")
-    private E removeAt(int i) {
-        assert i >= 0 && i < size;
+    E removeAt(int i) {
+        // assert i >= 0 && i < size;
         modCount++;
         int s = --size;
         if (s == i) // removed last element
@@ -756,6 +756,7 @@
      *             emitted (int), followed by all of its elements
      *             (each an {@code Object}) in the proper order.
      * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void writeObject(java.io.ObjectOutputStream s)
         throws java.io.IOException {
@@ -775,6 +776,9 @@
      * (that is, deserializes it).
      *
      * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
@@ -809,7 +813,7 @@
      * @since 1.8
      */
     public final Spliterator<E> spliterator() {
-        return new PriorityQueueSpliterator<E>(this, 0, -1, 0);
+        return new PriorityQueueSpliterator<>(this, 0, -1, 0);
     }
 
     static final class PriorityQueueSpliterator<E> implements Spliterator<E> {
@@ -822,9 +826,9 @@
         private int fence;            // -1 until first use
         private int expectedModCount; // initialized when fence set
 
-        /** Creates new spliterator covering the given range */
+        /** Creates new spliterator covering the given range. */
         PriorityQueueSpliterator(PriorityQueue<E> pq, int origin, int fence,
-                             int expectedModCount) {
+                                 int expectedModCount) {
             this.pq = pq;
             this.index = origin;
             this.fence = fence;
@@ -843,8 +847,8 @@
         public PriorityQueueSpliterator<E> trySplit() {
             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
             return (lo >= mid) ? null :
-                new PriorityQueueSpliterator<E>(pq, lo, index = mid,
-                                                expectedModCount);
+                new PriorityQueueSpliterator<>(pq, lo, index = mid,
+                                               expectedModCount);
         }
 
         @SuppressWarnings("unchecked")
diff --git a/ojluni/src/main/java/java/util/Queue.java b/ojluni/src/main/java/java/util/Queue.java
index b43c6c1..6520337 100644
--- a/ojluni/src/main/java/java/util/Queue.java
+++ b/ojluni/src/main/java/java/util/Queue.java
@@ -50,7 +50,6 @@
  * implementations; in most implementations, insert operations cannot
  * fail.
  *
- * <p>
  * <table BORDER CELLPADDING=3 CELLSPACING=1>
  * <caption>Summary of Queue methods</caption>
  *  <tr>
@@ -128,17 +127,9 @@
  * always well-defined for queues with the same elements but different
  * ordering properties.
  *
- * @see java.util.Collection
- * @see LinkedList
- * @see PriorityQueue
- * @see java.util.concurrent.LinkedBlockingQueue
- * @see java.util.concurrent.BlockingQueue
- * @see java.util.concurrent.ArrayBlockingQueue
- * @see java.util.concurrent.LinkedBlockingQueue
- * @see java.util.concurrent.PriorityBlockingQueue
  * @since 1.5
  * @author Doug Lea
- * @param <E> the type of elements held in this collection
+ * @param <E> the type of elements held in this queue
  */
 public interface Queue<E> extends Collection<E> {
     /**
diff --git a/ojluni/src/main/java/java/util/SplittableRandom.java b/ojluni/src/main/java/java/util/SplittableRandom.java
new file mode 100644
index 0000000..b2a07ec
--- /dev/null
+++ b/ojluni/src/main/java/java/util/SplittableRandom.java
@@ -0,0 +1,998 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.StreamSupport;
+
+
+// TODO(streams): Include in openjdk_java_files.mk
+/**
+ * A generator of uniform pseudorandom values applicable for use in
+ * (among other contexts) isolated parallel computations that may
+ * generate subtasks. Class {@code SplittableRandom} supports methods for
+ * producing pseudorandom numbers of type {@code int}, {@code long},
+ * and {@code double} with similar usages as for class
+ * {@link java.util.Random} but differs in the following ways:
+ *
+ * <ul>
+ *
+ * <li>Series of generated values pass the DieHarder suite testing
+ * independence and uniformity properties of random number generators.
+ * (Most recently validated with <a
+ * href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version
+ * 3.31.1</a>.) These tests validate only the methods for certain
+ * types and ranges, but similar properties are expected to hold, at
+ * least approximately, for others as well. The <em>period</em>
+ * (length of any series of generated values before it repeats) is at
+ * least 2<sup>64</sup>.
+ *
+ * <li>Method {@link #split} constructs and returns a new
+ * SplittableRandom instance that shares no mutable state with the
+ * current instance. However, with very high probability, the
+ * values collectively generated by the two objects have the same
+ * statistical properties as if the same quantity of values were
+ * generated by a single thread using a single {@code
+ * SplittableRandom} object.
+ *
+ * <li>Instances of SplittableRandom are <em>not</em> thread-safe.
+ * They are designed to be split, not shared, across threads. For
+ * example, a {@link java.util.concurrent.ForkJoinTask
+ * fork/join-style} computation using random numbers might include a
+ * construction of the form {@code new
+ * Subtask(aSplittableRandom.split()).fork()}.
+ *
+ * <li>This class provides additional methods for generating random
+ * streams, that employ the above techniques when used in {@code
+ * stream.parallel()} mode.
+ *
+ * </ul>
+ *
+ * <p>Instances of {@code SplittableRandom} are not cryptographically
+ * secure.  Consider instead using {@link java.security.SecureRandom}
+ * in security-sensitive applications. Additionally,
+ * default-constructed instances do not use a cryptographically random
+ * seed unless the {@linkplain System#getProperty system property}
+ * {@code java.util.secureRandomSeed} is set to {@code true}.
+ *
+ * @author  Guy Steele
+ * @author  Doug Lea
+ * @since   1.8
+ */
+public final class SplittableRandom {
+
+    /*
+     * Implementation Overview.
+     *
+     * This algorithm was inspired by the "DotMix" algorithm by
+     * Leiserson, Schardl, and Sukha "Deterministic Parallel
+     * Random-Number Generation for Dynamic-Multithreading Platforms",
+     * PPoPP 2012, as well as those in "Parallel random numbers: as
+     * easy as 1, 2, 3" by Salmon, Morae, Dror, and Shaw, SC 2011.  It
+     * differs mainly in simplifying and cheapening operations.
+     *
+     * The primary update step (method nextSeed()) is to add a
+     * constant ("gamma") to the current (64 bit) seed, forming a
+     * simple sequence.  The seed and the gamma values for any two
+     * SplittableRandom instances are highly likely to be different.
+     *
+     * Methods nextLong, nextInt, and derivatives do not return the
+     * sequence (seed) values, but instead a hash-like bit-mix of
+     * their bits, producing more independently distributed sequences.
+     * For nextLong, the mix64 function is based on David Stafford's
+     * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html)
+     * "Mix13" variant of the "64-bit finalizer" function in Austin
+     * Appleby's MurmurHash3 algorithm (see
+     * http://code.google.com/p/smhasher/wiki/MurmurHash3). The mix32
+     * function is based on Stafford's Mix04 mix function, but returns
+     * the upper 32 bits cast as int.
+     *
+     * The split operation uses the current generator to form the seed
+     * and gamma for another SplittableRandom.  To conservatively
+     * avoid potential correlations between seed and value generation,
+     * gamma selection (method mixGamma) uses different
+     * (Murmurhash3's) mix constants.  To avoid potential weaknesses
+     * in bit-mixing transformations, we restrict gammas to odd values
+     * with at least 24 0-1 or 1-0 bit transitions.  Rather than
+     * rejecting candidates with too few or too many bits set, method
+     * mixGamma flips some bits (which has the effect of mapping at
+     * most 4 to any given gamma value).  This reduces the effective
+     * set of 64bit odd gamma values by about 2%, and serves as an
+     * automated screening for sequence constant selection that is
+     * left as an empirical decision in some other hashing and crypto
+     * algorithms.
+     *
+     * The resulting generator thus transforms a sequence in which
+     * (typically) many bits change on each step, with an inexpensive
+     * mixer with good (but less than cryptographically secure)
+     * avalanching.
+     *
+     * The default (no-argument) constructor, in essence, invokes
+     * split() for a common "defaultGen" SplittableRandom.  Unlike
+     * other cases, this split must be performed in a thread-safe
+     * manner, so we use an AtomicLong to represent the seed rather
+     * than use an explicit SplittableRandom. To bootstrap the
+     * defaultGen, we start off using a seed based on current time
+     * unless the java.util.secureRandomSeed property is set. This
+     * serves as a slimmed-down (and insecure) variant of SecureRandom
+     * that also avoids stalls that may occur when using /dev/random.
+     *
+     * It is a relatively simple matter to apply the basic design here
+     * to use 128 bit seeds. However, emulating 128bit arithmetic and
+     * carrying around twice the state add more overhead than appears
+     * warranted for current usages.
+     *
+     * File organization: First the non-public methods that constitute
+     * the main algorithm, then the main public methods, followed by
+     * some custom spliterator classes needed for stream methods.
+     */
+
+    /**
+     * The golden ratio scaled to 64bits, used as the initial gamma
+     * value for (unsplit) SplittableRandoms.
+     */
+    private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
+
+    /**
+     * The least non-zero value returned by nextDouble(). This value
+     * is scaled by a random value of 53 bits to produce a result.
+     */
+    private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53);
+
+    /**
+     * The seed. Updated only via method nextSeed.
+     */
+    private long seed;
+
+    /**
+     * The step value.
+     */
+    private final long gamma;
+
+    /**
+     * Internal constructor used by all others except default constructor.
+     */
+    private SplittableRandom(long seed, long gamma) {
+        this.seed = seed;
+        this.gamma = gamma;
+    }
+
+    /**
+     * Computes Stafford variant 13 of 64bit mix function.
+     */
+    private static long mix64(long z) {
+        z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
+        z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
+        return z ^ (z >>> 31);
+    }
+
+    /**
+     * Returns the 32 high bits of Stafford variant 4 mix64 function as int.
+     */
+    private static int mix32(long z) {
+        z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L;
+        return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32);
+    }
+
+    /**
+     * Returns the gamma value to use for a new split instance.
+     */
+    private static long mixGamma(long z) {
+        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; // MurmurHash3 mix constants
+        z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
+        z = (z ^ (z >>> 33)) | 1L;                  // force to be odd
+        int n = Long.bitCount(z ^ (z >>> 1));       // ensure enough transitions
+        return (n < 24) ? z ^ 0xaaaaaaaaaaaaaaaaL : z;
+    }
+
+    /**
+     * Adds gamma to seed.
+     */
+    private long nextSeed() {
+        return seed += gamma;
+    }
+
+    // IllegalArgumentException messages
+    static final String BAD_BOUND = "bound must be positive";
+    static final String BAD_RANGE = "bound must be greater than origin";
+    static final String BAD_SIZE  = "size must be non-negative";
+
+    /**
+     * The seed generator for default constructors.
+     */
+    private static final AtomicLong defaultGen
+        = new AtomicLong(mix64(System.currentTimeMillis()) ^
+                         mix64(System.nanoTime()));
+
+    // at end of <clinit> to survive static initialization circularity
+    static {
+        if (java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Boolean>() {
+                public Boolean run() {
+                    return Boolean.getBoolean("java.util.secureRandomSeed");
+                }})) {
+            byte[] seedBytes = java.security.SecureRandom.getSeed(8);
+            long s = (long)seedBytes[0] & 0xffL;
+            for (int i = 1; i < 8; ++i)
+                s = (s << 8) | ((long)seedBytes[i] & 0xffL);
+            defaultGen.set(s);
+        }
+    }
+
+    /*
+     * Internal versions of nextX methods used by streams, as well as
+     * the public nextX(origin, bound) methods.  These exist mainly to
+     * avoid the need for multiple versions of stream spliterators
+     * across the different exported forms of streams.
+     */
+
+    /**
+     * The form of nextLong used by LongStream Spliterators.  If
+     * origin is greater than bound, acts as unbounded form of
+     * nextLong, else as bounded form.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final long internalNextLong(long origin, long bound) {
+        /*
+         * Four Cases:
+         *
+         * 1. If the arguments indicate unbounded form, act as
+         * nextLong().
+         *
+         * 2. If the range is an exact power of two, apply the
+         * associated bit mask.
+         *
+         * 3. If the range is positive, loop to avoid potential bias
+         * when the implicit nextLong() bound (2<sup>64</sup>) is not
+         * evenly divisible by the range. The loop rejects candidates
+         * computed from otherwise over-represented values.  The
+         * expected number of iterations under an ideal generator
+         * varies from 1 to 2, depending on the bound. The loop itself
+         * takes an unlovable form. Because the first candidate is
+         * already available, we need a break-in-the-middle
+         * construction, which is concisely but cryptically performed
+         * within the while-condition of a body-less for loop.
+         *
+         * 4. Otherwise, the range cannot be represented as a positive
+         * long.  The loop repeatedly generates unbounded longs until
+         * obtaining a candidate meeting constraints (with an expected
+         * number of iterations of less than two).
+         */
+
+        long r = mix64(nextSeed());
+        if (origin < bound) {
+            long n = bound - origin, m = n - 1;
+            if ((n & m) == 0L)  // power of two
+                r = (r & m) + origin;
+            else if (n > 0L) {  // reject over-represented candidates
+                for (long u = r >>> 1;            // ensure nonnegative
+                     u + m - (r = u % n) < 0L;    // rejection check
+                     u = mix64(nextSeed()) >>> 1) // retry
+                    ;
+                r += origin;
+            }
+            else {              // range not representable as long
+                while (r < origin || r >= bound)
+                    r = mix64(nextSeed());
+            }
+        }
+        return r;
+    }
+
+    /**
+     * The form of nextInt used by IntStream Spliterators.
+     * Exactly the same as long version, except for types.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final int internalNextInt(int origin, int bound) {
+        int r = mix32(nextSeed());
+        if (origin < bound) {
+            int n = bound - origin, m = n - 1;
+            if ((n & m) == 0)
+                r = (r & m) + origin;
+            else if (n > 0) {
+                for (int u = r >>> 1;
+                     u + m - (r = u % n) < 0;
+                     u = mix32(nextSeed()) >>> 1)
+                    ;
+                r += origin;
+            }
+            else {
+                while (r < origin || r >= bound)
+                    r = mix32(nextSeed());
+            }
+        }
+        return r;
+    }
+
+    /**
+     * The form of nextDouble used by DoubleStream Spliterators.
+     *
+     * @param origin the least value, unless greater than bound
+     * @param bound the upper bound (exclusive), must not equal origin
+     * @return a pseudorandom value
+     */
+    final double internalNextDouble(double origin, double bound) {
+        double r = (nextLong() >>> 11) * DOUBLE_UNIT;
+        if (origin < bound) {
+            r = r * (bound - origin) + origin;
+            if (r >= bound) // correct for rounding
+                r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+        }
+        return r;
+    }
+
+    /* ---------------- public methods ---------------- */
+
+    /**
+     * Creates a new SplittableRandom instance using the specified
+     * initial seed. SplittableRandom instances created with the same
+     * seed in the same program generate identical sequences of values.
+     *
+     * @param seed the initial seed
+     */
+    public SplittableRandom(long seed) {
+        this(seed, GOLDEN_GAMMA);
+    }
+
+    /**
+     * Creates a new SplittableRandom instance that is likely to
+     * generate sequences of values that are statistically independent
+     * of those of any other instances in the current program; and
+     * may, and typically does, vary across program invocations.
+     */
+    public SplittableRandom() { // emulate defaultGen.split()
+        long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
+        this.seed = mix64(s);
+        this.gamma = mixGamma(s + GOLDEN_GAMMA);
+    }
+
+    /**
+     * Constructs and returns a new SplittableRandom instance that
+     * shares no mutable state with this instance. However, with very
+     * high probability, the set of values collectively generated by
+     * the two objects has the same statistical properties as if the
+     * same quantity of values were generated by a single thread using
+     * a single SplittableRandom object.  Either or both of the two
+     * objects may be further split using the {@code split()} method,
+     * and the same expected statistical properties apply to the
+     * entire set of generators constructed by such recursive
+     * splitting.
+     *
+     * @return the new SplittableRandom instance
+     */
+    public SplittableRandom split() {
+        return new SplittableRandom(nextLong(), mixGamma(nextSeed()));
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value.
+     *
+     * @return a pseudorandom {@code int} value
+     */
+    public int nextInt() {
+        return mix32(nextSeed());
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value between zero (inclusive)
+     * and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code int} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public int nextInt(int bound) {
+        if (bound <= 0)
+            throw new IllegalArgumentException(BAD_BOUND);
+        // Specialize internalNextInt for origin 0
+        int r = mix32(nextSeed());
+        int m = bound - 1;
+        if ((bound & m) == 0) // power of two
+            r &= m;
+        else { // reject over-represented candidates
+            for (int u = r >>> 1;
+                 u + m - (r = u % bound) < 0;
+                 u = mix32(nextSeed()) >>> 1)
+                ;
+        }
+        return r;
+    }
+
+    /**
+     * Returns a pseudorandom {@code int} value between the specified
+     * origin (inclusive) and the specified bound (exclusive).
+     *
+     * @param origin the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return a pseudorandom {@code int} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
+     */
+    public int nextInt(int origin, int bound) {
+        if (origin >= bound)
+            throw new IllegalArgumentException(BAD_RANGE);
+        return internalNextInt(origin, bound);
+    }
+
+    /**
+     * Returns a pseudorandom {@code long} value.
+     *
+     * @return a pseudorandom {@code long} value
+     */
+    public long nextLong() {
+        return mix64(nextSeed());
+    }
+
+    /**
+     * Returns a pseudorandom {@code long} value between zero (inclusive)
+     * and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code long} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public long nextLong(long bound) {
+        if (bound <= 0)
+            throw new IllegalArgumentException(BAD_BOUND);
+        // Specialize internalNextLong for origin 0
+        long r = mix64(nextSeed());
+        long m = bound - 1;
+        if ((bound & m) == 0L) // power of two
+            r &= m;
+        else { // reject over-represented candidates
+            for (long u = r >>> 1;
+                 u + m - (r = u % bound) < 0L;
+                 u = mix64(nextSeed()) >>> 1)
+                ;
+        }
+        return r;
+    }
+
+    /**
+     * Returns a pseudorandom {@code long} value between the specified
+     * origin (inclusive) and the specified bound (exclusive).
+     *
+     * @param origin the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return a pseudorandom {@code long} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
+     */
+    public long nextLong(long origin, long bound) {
+        if (origin >= bound)
+            throw new IllegalArgumentException(BAD_RANGE);
+        return internalNextLong(origin, bound);
+    }
+
+    /**
+     * Returns a pseudorandom {@code double} value between zero
+     * (inclusive) and one (exclusive).
+     *
+     * @return a pseudorandom {@code double} value between zero
+     *         (inclusive) and one (exclusive)
+     */
+    public double nextDouble() {
+        return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
+    }
+
+    /**
+     * Returns a pseudorandom {@code double} value between 0.0
+     * (inclusive) and the specified bound (exclusive).
+     *
+     * @param bound the upper bound (exclusive).  Must be positive.
+     * @return a pseudorandom {@code double} value between zero
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code bound} is not positive
+     */
+    public double nextDouble(double bound) {
+        if (!(bound > 0.0))
+            throw new IllegalArgumentException(BAD_BOUND);
+        double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
+        return (result < bound) ?  result : // correct for rounding
+            Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+    }
+
+    /**
+     * Returns a pseudorandom {@code double} value between the specified
+     * origin (inclusive) and bound (exclusive).
+     *
+     * @param origin the least value returned
+     * @param bound the upper bound (exclusive)
+     * @return a pseudorandom {@code double} value between the origin
+     *         (inclusive) and the bound (exclusive)
+     * @throws IllegalArgumentException if {@code origin} is greater than
+     *         or equal to {@code bound}
+     */
+    public double nextDouble(double origin, double bound) {
+        if (!(origin < bound))
+            throw new IllegalArgumentException(BAD_RANGE);
+        return internalNextDouble(origin, bound);
+    }
+
+    /**
+     * Returns a pseudorandom {@code boolean} value.
+     *
+     * @return a pseudorandom {@code boolean} value
+     */
+    public boolean nextBoolean() {
+        return mix32(nextSeed()) < 0;
+    }
+
+    // stream methods, coded in a way intended to better isolate for
+    // maintenance purposes the small differences across forms.
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number
+     * of pseudorandom {@code int} values from this generator and/or
+     * one split from it.
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of pseudorandom {@code int} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     */
+    public IntStream ints(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BAD_SIZE);
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (this, 0L, streamSize, Integer.MAX_VALUE, 0),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code int}
+     * values from this generator and/or one split from it.
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * ints(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code int} values
+     */
+    public IntStream ints() {
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number
+     * of pseudorandom {@code int} values from this generator and/or one split
+     * from it; each value conforms to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code int} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero, or {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public IntStream ints(long streamSize, int randomNumberOrigin,
+                          int randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BAD_SIZE);
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BAD_RANGE);
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * int} values from this generator and/or one split from it; each value
+     * conforms to the given origin (inclusive) and bound (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code int} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BAD_RANGE);
+        return StreamSupport.intStream
+            (new RandomIntsSpliterator
+             (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number
+     * of pseudorandom {@code long} values from this generator and/or
+     * one split from it.
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of pseudorandom {@code long} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     */
+    public LongStream longs(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BAD_SIZE);
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (this, 0L, streamSize, Long.MAX_VALUE, 0L),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * long} values from this generator and/or one split from it.
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * longs(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code long} values
+     */
+    public LongStream longs() {
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code long} values from this generator and/or one split
+     * from it; each value conforms to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code long} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero, or {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public LongStream longs(long streamSize, long randomNumberOrigin,
+                            long randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BAD_SIZE);
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BAD_RANGE);
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * long} values from this generator and/or one split from it; each value
+     * conforms to the given origin (inclusive) and bound (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code long} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+        if (randomNumberOrigin >= randomNumberBound)
+            throw new IllegalArgumentException(BAD_RANGE);
+        return StreamSupport.longStream
+            (new RandomLongsSpliterator
+             (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code double} values from this generator and/or one split
+     * from it; each value is between zero (inclusive) and one (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @return a stream of {@code double} values
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     */
+    public DoubleStream doubles(long streamSize) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BAD_SIZE);
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * double} values from this generator and/or one split from it; each value
+     * is between zero (inclusive) and one (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * doubles(Long.MAX_VALUE)}.
+     *
+     * @return a stream of pseudorandom {@code double} values
+     */
+    public DoubleStream doubles() {
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
+             false);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of
+     * pseudorandom {@code double} values from this generator and/or one split
+     * from it; each value conforms to the given origin (inclusive) and bound
+     * (exclusive).
+     *
+     * @param streamSize the number of values to generate
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code double} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code streamSize} is
+     *         less than zero
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public DoubleStream doubles(long streamSize, double randomNumberOrigin,
+                                double randomNumberBound) {
+        if (streamSize < 0L)
+            throw new IllegalArgumentException(BAD_SIZE);
+        if (!(randomNumberOrigin < randomNumberBound))
+            throw new IllegalArgumentException(BAD_RANGE);
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of pseudorandom {@code
+     * double} values from this generator and/or one split from it; each value
+     * conforms to the given origin (inclusive) and bound (exclusive).
+     *
+     * @implNote This method is implemented to be equivalent to {@code
+     * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+     *
+     * @param randomNumberOrigin the origin (inclusive) of each random value
+     * @param randomNumberBound the bound (exclusive) of each random value
+     * @return a stream of pseudorandom {@code double} values,
+     *         each with the given origin (inclusive) and bound (exclusive)
+     * @throws IllegalArgumentException if {@code randomNumberOrigin}
+     *         is greater than or equal to {@code randomNumberBound}
+     */
+    public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+        if (!(randomNumberOrigin < randomNumberBound))
+            throw new IllegalArgumentException(BAD_RANGE);
+        return StreamSupport.doubleStream
+            (new RandomDoublesSpliterator
+             (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+             false);
+    }
+
+    /**
+     * Spliterator for int streams.  We multiplex the four int
+     * versions into one class by treating a bound less than origin as
+     * unbounded, and also by treating "infinite" as equivalent to
+     * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
+     * approach. The long and double versions of this class are
+     * identical except for types.
+     */
+    private static final class RandomIntsSpliterator
+            implements Spliterator.OfInt {
+        final SplittableRandom rng;
+        long index;
+        final long fence;
+        final int origin;
+        final int bound;
+        RandomIntsSpliterator(SplittableRandom rng, long index, long fence,
+                              int origin, int bound) {
+            this.rng = rng; this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomIntsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomIntsSpliterator(rng.split(), i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rng.internalNextInt(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(IntConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                SplittableRandom r = rng;
+                int o = origin, b = bound;
+                do {
+                    consumer.accept(r.internalNextInt(o, b));
+                } while (++i < f);
+            }
+        }
+    }
+
+    /**
+     * Spliterator for long streams.
+     */
+    private static final class RandomLongsSpliterator
+            implements Spliterator.OfLong {
+        final SplittableRandom rng;
+        long index;
+        final long fence;
+        final long origin;
+        final long bound;
+        RandomLongsSpliterator(SplittableRandom rng, long index, long fence,
+                               long origin, long bound) {
+            this.rng = rng; this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomLongsSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomLongsSpliterator(rng.split(), i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rng.internalNextLong(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(LongConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                SplittableRandom r = rng;
+                long o = origin, b = bound;
+                do {
+                    consumer.accept(r.internalNextLong(o, b));
+                } while (++i < f);
+            }
+        }
+
+    }
+
+    /**
+     * Spliterator for double streams.
+     */
+    private static final class RandomDoublesSpliterator
+            implements Spliterator.OfDouble {
+        final SplittableRandom rng;
+        long index;
+        final long fence;
+        final double origin;
+        final double bound;
+        RandomDoublesSpliterator(SplittableRandom rng, long index, long fence,
+                                 double origin, double bound) {
+            this.rng = rng; this.index = index; this.fence = fence;
+            this.origin = origin; this.bound = bound;
+        }
+
+        public RandomDoublesSpliterator trySplit() {
+            long i = index, m = (i + fence) >>> 1;
+            return (m <= i) ? null :
+                new RandomDoublesSpliterator(rng.split(), i, index = m, origin, bound);
+        }
+
+        public long estimateSize() {
+            return fence - index;
+        }
+
+        public int characteristics() {
+            return (Spliterator.SIZED | Spliterator.SUBSIZED |
+                    Spliterator.NONNULL | Spliterator.IMMUTABLE);
+        }
+
+        public boolean tryAdvance(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                consumer.accept(rng.internalNextDouble(origin, bound));
+                index = i + 1;
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(DoubleConsumer consumer) {
+            if (consumer == null) throw new NullPointerException();
+            long i = index, f = fence;
+            if (i < f) {
+                index = f;
+                SplittableRandom r = rng;
+                double o = origin, b = bound;
+                do {
+                    consumer.accept(r.internalNextDouble(o, b));
+                } while (++i < f);
+            }
+        }
+    }
+
+}
