ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CompletableFutureTest.java
(Generate patch)

Comparing jsr166/src/test/tck/CompletableFutureTest.java (file contents):
Revision 1.3 by jsr166, Sat Feb 9 19:33:08 2013 UTC vs.
Revision 1.97 by jsr166, Wed Dec 31 16:44:01 2014 UTC

# Line 1 | Line 1
1   /*
2 < * Written by Doug Lea with assistance from members of JCP JSR-166
3 < * Expert Group and released to the public domain, as explained at
2 > * Written by Doug Lea and Martin Buchholz with assistance from
3 > * members of JCP JSR-166 Expert Group and released to the public
4 > * domain, as explained at
5   * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
6   */
7  
8   import junit.framework.*;
9   import java.util.concurrent.Callable;
10 + import java.util.concurrent.Executor;
11   import java.util.concurrent.CancellationException;
12 import java.util.concurrent.CountDownLatch;
12   import java.util.concurrent.ExecutionException;
14 import java.util.concurrent.Future;
13   import java.util.concurrent.CompletableFuture;
14 + import java.util.concurrent.CompletionException;
15 + import java.util.concurrent.CompletionStage;
16 + import java.util.concurrent.ForkJoinPool;
17 + import java.util.concurrent.ForkJoinTask;
18   import java.util.concurrent.TimeoutException;
19   import java.util.concurrent.atomic.AtomicInteger;
20   import static java.util.concurrent.TimeUnit.MILLISECONDS;
21   import static java.util.concurrent.TimeUnit.SECONDS;
22   import java.util.*;
23 + import java.util.function.Supplier;
24 + import java.util.function.Consumer;
25 + import java.util.function.BiConsumer;
26 + import java.util.function.Function;
27 + import java.util.function.BiFunction;
28  
29   public class CompletableFutureTest extends JSR166TestCase {
30  
# Line 28 | Line 35 | public class CompletableFutureTest exten
35          return new TestSuite(CompletableFutureTest.class);
36      }
37  
38 <    // XXXX Just a skeleton implementation for now.
39 <    public void testTODO() {
40 <        fail("Please add some real tests!");
38 >    static class CFException extends RuntimeException {}
39 >
40 >    void checkIncomplete(CompletableFuture<?> f) {
41 >        assertFalse(f.isDone());
42 >        assertFalse(f.isCancelled());
43 >        assertTrue(f.toString().contains("[Not completed]"));
44 >        try {
45 >            assertNull(f.getNow(null));
46 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
47 >        try {
48 >            f.get(0L, SECONDS);
49 >            shouldThrow();
50 >        }
51 >        catch (TimeoutException success) {}
52 >        catch (Throwable fail) { threadUnexpectedException(fail); }
53 >    }
54 >
55 >    <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
56 >        checkTimedGet(f, value);
57 >
58 >        try {
59 >            assertEquals(value, f.join());
60 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
61 >        try {
62 >            assertEquals(value, f.getNow(null));
63 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
64 >        try {
65 >            assertEquals(value, f.get());
66 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
67 >        assertTrue(f.isDone());
68 >        assertFalse(f.isCancelled());
69 >        assertFalse(f.isCompletedExceptionally());
70 >        assertTrue(f.toString().contains("[Completed normally]"));
71 >    }
72 >
73 >    void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
74 >        long startTime = System.nanoTime();
75 >        long timeoutMillis = LONG_DELAY_MS;
76 >        try {
77 >            f.get(timeoutMillis, MILLISECONDS);
78 >            shouldThrow();
79 >        } catch (ExecutionException success) {
80 >            assertTrue(success.getCause() instanceof CFException);
81 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
82 >        assertTrue(millisElapsedSince(startTime) < timeoutMillis/2);
83 >
84 >        try {
85 >            f.join();
86 >            shouldThrow();
87 >        } catch (CompletionException success) {
88 >            assertTrue(success.getCause() instanceof CFException);
89 >        }
90 >        try {
91 >            f.getNow(null);
92 >            shouldThrow();
93 >        } catch (CompletionException success) {
94 >            assertTrue(success.getCause() instanceof CFException);
95 >        }
96 >        try {
97 >            f.get();
98 >            shouldThrow();
99 >        } catch (ExecutionException success) {
100 >            assertTrue(success.getCause() instanceof CFException);
101 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
102 >        assertTrue(f.isDone());
103 >        assertFalse(f.isCancelled());
104 >        assertTrue(f.toString().contains("[Completed exceptionally]"));
105 >    }
106 >
107 >    <U> void checkCompletedExceptionallyWithRootCause(CompletableFuture<U> f,
108 >                                                      Throwable ex) {
109 >        long startTime = System.nanoTime();
110 >        long timeoutMillis = LONG_DELAY_MS;
111 >        try {
112 >            f.get(timeoutMillis, MILLISECONDS);
113 >            shouldThrow();
114 >        } catch (ExecutionException success) {
115 >            assertSame(ex, success.getCause());
116 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
117 >        assertTrue(millisElapsedSince(startTime) < timeoutMillis/2);
118 >
119 >        try {
120 >            f.join();
121 >            shouldThrow();
122 >        } catch (CompletionException success) {
123 >            assertSame(ex, success.getCause());
124 >        }
125 >        try {
126 >            f.getNow(null);
127 >            shouldThrow();
128 >        } catch (CompletionException success) {
129 >            assertSame(ex, success.getCause());
130 >        }
131 >        try {
132 >            f.get();
133 >            shouldThrow();
134 >        } catch (ExecutionException success) {
135 >            assertSame(ex, success.getCause());
136 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
137 >
138 >        assertTrue(f.isDone());
139 >        assertFalse(f.isCancelled());
140 >        assertTrue(f.toString().contains("[Completed exceptionally]"));
141 >    }
142 >
143 >    <U> void checkCompletedWithWrappedException(CompletableFuture<U> f,
144 >                                                Throwable ex) {
145 >        checkCompletedExceptionallyWithRootCause(f, ex);
146 >        try {
147 >            CompletableFuture<Throwable> spy = f.handle
148 >                ((U u, Throwable t) -> t);
149 >            assertTrue(spy.join() instanceof CompletionException);
150 >            assertSame(ex, spy.join().getCause());
151 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
152      }
153  
154 +    <U> void checkCompletedExceptionally(CompletableFuture<U> f, Throwable ex) {
155 +        checkCompletedExceptionallyWithRootCause(f, ex);
156 +        try {
157 +            CompletableFuture<Throwable> spy = f.handle
158 +                ((U u, Throwable t) -> t);
159 +            assertSame(ex, spy.join());
160 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
161 +    }
162 +
163 +    void checkCancelled(CompletableFuture<?> f) {
164 +        long startTime = System.nanoTime();
165 +        long timeoutMillis = LONG_DELAY_MS;
166 +        try {
167 +            f.get(timeoutMillis, MILLISECONDS);
168 +            shouldThrow();
169 +        } catch (CancellationException success) {
170 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
171 +        assertTrue(millisElapsedSince(startTime) < timeoutMillis/2);
172 +
173 +        try {
174 +            f.join();
175 +            shouldThrow();
176 +        } catch (CancellationException success) {}
177 +        try {
178 +            f.getNow(null);
179 +            shouldThrow();
180 +        } catch (CancellationException success) {}
181 +        try {
182 +            f.get();
183 +            shouldThrow();
184 +        } catch (CancellationException success) {
185 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
186 +        assertTrue(f.isDone());
187 +        assertTrue(f.isCompletedExceptionally());
188 +        assertTrue(f.isCancelled());
189 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
190 +    }
191 +
192 +    void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
193 +        long startTime = System.nanoTime();
194 +        long timeoutMillis = LONG_DELAY_MS;
195 +        try {
196 +            f.get(timeoutMillis, MILLISECONDS);
197 +            shouldThrow();
198 +        } catch (ExecutionException success) {
199 +            assertTrue(success.getCause() instanceof CancellationException);
200 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
201 +        assertTrue(millisElapsedSince(startTime) < timeoutMillis/2);
202 +
203 +        try {
204 +            f.join();
205 +            shouldThrow();
206 +        } catch (CompletionException success) {
207 +            assertTrue(success.getCause() instanceof CancellationException);
208 +        }
209 +        try {
210 +            f.getNow(null);
211 +            shouldThrow();
212 +        } catch (CompletionException success) {
213 +            assertTrue(success.getCause() instanceof CancellationException);
214 +        }
215 +        try {
216 +            f.get();
217 +            shouldThrow();
218 +        } catch (ExecutionException success) {
219 +            assertTrue(success.getCause() instanceof CancellationException);
220 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
221 +        assertTrue(f.isDone());
222 +        assertFalse(f.isCancelled());
223 +        assertTrue(f.isCompletedExceptionally());
224 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
225 +    }
226 +
227 +    /**
228 +     * A newly constructed CompletableFuture is incomplete, as indicated
229 +     * by methods isDone, isCancelled, and getNow
230 +     */
231 +    public void testConstructor() {
232 +        CompletableFuture<Integer> f = new CompletableFuture<>();
233 +        checkIncomplete(f);
234 +    }
235 +
236 +    /**
237 +     * complete completes normally, as indicated by methods isDone,
238 +     * isCancelled, join, get, and getNow
239 +     */
240 +    public void testComplete() {
241 +        for (Integer v1 : new Integer[] { 1, null })
242 +    {
243 +        CompletableFuture<Integer> f = new CompletableFuture<>();
244 +        checkIncomplete(f);
245 +        assertTrue(f.complete(v1));
246 +        assertFalse(f.complete(v1));
247 +        checkCompletedNormally(f, v1);
248 +    }}
249 +
250 +    /**
251 +     * completeExceptionally completes exceptionally, as indicated by
252 +     * methods isDone, isCancelled, join, get, and getNow
253 +     */
254 +    public void testCompleteExceptionally() {
255 +        CompletableFuture<Integer> f = new CompletableFuture<>();
256 +        CFException ex = new CFException();
257 +        checkIncomplete(f);
258 +        f.completeExceptionally(ex);
259 +        checkCompletedExceptionally(f, ex);
260 +    }
261 +
262 +    /**
263 +     * cancel completes exceptionally and reports cancelled, as indicated by
264 +     * methods isDone, isCancelled, join, get, and getNow
265 +     */
266 +    public void testCancel() {
267 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
268 +    {
269 +        CompletableFuture<Integer> f = new CompletableFuture<>();
270 +        checkIncomplete(f);
271 +        assertTrue(f.cancel(true));
272 +        assertTrue(f.cancel(true));
273 +        checkCancelled(f);
274 +    }}
275 +
276 +    /**
277 +     * obtrudeValue forces completion with given value
278 +     */
279 +    public void testObtrudeValue() {
280 +        CompletableFuture<Integer> f = new CompletableFuture<>();
281 +        checkIncomplete(f);
282 +        assertTrue(f.complete(one));
283 +        checkCompletedNormally(f, one);
284 +        f.obtrudeValue(three);
285 +        checkCompletedNormally(f, three);
286 +        f.obtrudeValue(two);
287 +        checkCompletedNormally(f, two);
288 +        f = new CompletableFuture<>();
289 +        f.obtrudeValue(three);
290 +        checkCompletedNormally(f, three);
291 +        f.obtrudeValue(null);
292 +        checkCompletedNormally(f, null);
293 +        f = new CompletableFuture<>();
294 +        f.completeExceptionally(new CFException());
295 +        f.obtrudeValue(four);
296 +        checkCompletedNormally(f, four);
297 +    }
298 +
299 +    /**
300 +     * obtrudeException forces completion with given exception
301 +     */
302 +    public void testObtrudeException() {
303 +        for (Integer v1 : new Integer[] { 1, null })
304 +    {
305 +        CFException ex;
306 +        CompletableFuture<Integer> f;
307 +
308 +        f = new CompletableFuture<>();
309 +        assertTrue(f.complete(v1));
310 +        for (int i = 0; i < 2; i++) {
311 +            f.obtrudeException(ex = new CFException());
312 +            checkCompletedExceptionally(f, ex);
313 +        }
314 +
315 +        f = new CompletableFuture<>();
316 +        for (int i = 0; i < 2; i++) {
317 +            f.obtrudeException(ex = new CFException());
318 +            checkCompletedExceptionally(f, ex);
319 +        }
320 +
321 +        f = new CompletableFuture<>();
322 +        f.completeExceptionally(ex = new CFException());
323 +        f.obtrudeValue(v1);
324 +        checkCompletedNormally(f, v1);
325 +        f.obtrudeException(ex = new CFException());
326 +        checkCompletedExceptionally(f, ex);
327 +        f.completeExceptionally(new CFException());
328 +        checkCompletedExceptionally(f, ex);
329 +        assertFalse(f.complete(v1));
330 +        checkCompletedExceptionally(f, ex);
331 +    }}
332 +
333 +    /**
334 +     * getNumberOfDependents returns number of dependent tasks
335 +     */
336 +    public void testGetNumberOfDependents() {
337 +        for (ExecutionMode m : ExecutionMode.values())
338 +        for (Integer v1 : new Integer[] { 1, null })
339 +    {
340 +        CompletableFuture<Integer> f = new CompletableFuture<>();
341 +        assertEquals(0, f.getNumberOfDependents());
342 +        final CompletableFuture<Void> g = m.thenRun(f, new Noop(m));
343 +        assertEquals(1, f.getNumberOfDependents());
344 +        assertEquals(0, g.getNumberOfDependents());
345 +        final CompletableFuture<Void> h = m.thenRun(f, new Noop(m));
346 +        assertEquals(2, f.getNumberOfDependents());
347 +        assertEquals(0, h.getNumberOfDependents());
348 +        assertTrue(f.complete(v1));
349 +        checkCompletedNormally(g, null);
350 +        checkCompletedNormally(h, null);
351 +        assertEquals(0, f.getNumberOfDependents());
352 +        assertEquals(0, g.getNumberOfDependents());
353 +        assertEquals(0, h.getNumberOfDependents());
354 +    }}
355 +
356 +    /**
357 +     * toString indicates current completion state
358 +     */
359      public void testToString() {
360          CompletableFuture<String> f;
361  
362          f = new CompletableFuture<String>();
363          assertTrue(f.toString().contains("[Not completed]"));
364  
365 <        f.complete("foo");
365 >        assertTrue(f.complete("foo"));
366          assertTrue(f.toString().contains("[Completed normally]"));
367  
368          f = new CompletableFuture<String>();
369 <        f.completeExceptionally(new IndexOutOfBoundsException());
369 >        assertTrue(f.completeExceptionally(new IndexOutOfBoundsException()));
370          assertTrue(f.toString().contains("[Completed exceptionally]"));
371 +
372 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
373 +            f = new CompletableFuture<String>();
374 +            assertTrue(f.cancel(mayInterruptIfRunning));
375 +            assertTrue(f.toString().contains("[Completed exceptionally]"));
376 +        }
377 +    }
378 +
379 +    /**
380 +     * completedFuture returns a completed CompletableFuture with given value
381 +     */
382 +    public void testCompletedFuture() {
383 +        CompletableFuture<String> f = CompletableFuture.completedFuture("test");
384 +        checkCompletedNormally(f, "test");
385 +    }
386 +
387 +    abstract class CheckedAction {
388 +        int invocationCount = 0;
389 +        final ExecutionMode m;
390 +        CheckedAction(ExecutionMode m) { this.m = m; }
391 +        void invoked() {
392 +            m.checkExecutionMode();
393 +            assertEquals(0, invocationCount++);
394 +        }
395 +        void assertNotInvoked() { assertEquals(0, invocationCount); }
396 +        void assertInvoked() { assertEquals(1, invocationCount); }
397 +    }
398 +
399 +    abstract class CheckedIntegerAction extends CheckedAction {
400 +        Integer value;
401 +        CheckedIntegerAction(ExecutionMode m) { super(m); }
402 +        void assertValue(Integer expected) {
403 +            assertInvoked();
404 +            assertEquals(expected, value);
405 +        }
406 +    }
407 +
408 +    class IntegerSupplier extends CheckedAction
409 +        implements Supplier<Integer>
410 +    {
411 +        final Integer value;
412 +        IntegerSupplier(ExecutionMode m, Integer value) {
413 +            super(m);
414 +            this.value = value;
415 +        }
416 +        public Integer get() {
417 +            invoked();
418 +            return value;
419 +        }
420 +    }
421 +
422 +    // A function that handles and produces null values as well.
423 +    static Integer inc(Integer x) {
424 +        return (x == null) ? null : x + 1;
425 +    }
426 +
427 +    class NoopConsumer extends CheckedIntegerAction
428 +        implements Consumer<Integer>
429 +    {
430 +        NoopConsumer(ExecutionMode m) { super(m); }
431 +        public void accept(Integer x) {
432 +            invoked();
433 +            value = x;
434 +        }
435 +    }
436 +
437 +    class IncFunction extends CheckedIntegerAction
438 +        implements Function<Integer,Integer>
439 +    {
440 +        IncFunction(ExecutionMode m) { super(m); }
441 +        public Integer apply(Integer x) {
442 +            invoked();
443 +            return value = inc(x);
444 +        }
445 +    }
446 +
447 +    // Choose non-commutative actions for better coverage
448 +    // A non-commutative function that handles and produces null values as well.
449 +    static Integer subtract(Integer x, Integer y) {
450 +        return (x == null && y == null) ? null :
451 +            ((x == null) ? 42 : x.intValue())
452 +            - ((y == null) ? 99 : y.intValue());
453 +    }
454 +
455 +    class SubtractAction extends CheckedIntegerAction
456 +        implements BiConsumer<Integer, Integer>
457 +    {
458 +        SubtractAction(ExecutionMode m) { super(m); }
459 +        public void accept(Integer x, Integer y) {
460 +            invoked();
461 +            value = subtract(x, y);
462 +        }
463 +    }
464 +
465 +    class SubtractFunction extends CheckedIntegerAction
466 +        implements BiFunction<Integer, Integer, Integer>
467 +    {
468 +        SubtractFunction(ExecutionMode m) { super(m); }
469 +        public Integer apply(Integer x, Integer y) {
470 +            invoked();
471 +            return value = subtract(x, y);
472 +        }
473 +    }
474 +
475 +    class Noop extends CheckedAction implements Runnable {
476 +        Noop(ExecutionMode m) { super(m); }
477 +        public void run() {
478 +            invoked();
479 +        }
480 +    }
481 +
482 +    class FailingSupplier extends CheckedAction
483 +        implements Supplier<Integer>
484 +    {
485 +        FailingSupplier(ExecutionMode m) { super(m); }
486 +        public Integer get() {
487 +            invoked();
488 +            throw new CFException();
489 +        }
490 +    }
491 +
492 +    class FailingConsumer extends CheckedIntegerAction
493 +        implements Consumer<Integer>
494 +    {
495 +        FailingConsumer(ExecutionMode m) { super(m); }
496 +        public void accept(Integer x) {
497 +            invoked();
498 +            value = x;
499 +            throw new CFException();
500 +        }
501 +    }
502 +
503 +    class FailingBiConsumer extends CheckedIntegerAction
504 +        implements BiConsumer<Integer, Integer>
505 +    {
506 +        FailingBiConsumer(ExecutionMode m) { super(m); }
507 +        public void accept(Integer x, Integer y) {
508 +            invoked();
509 +            value = subtract(x, y);
510 +            throw new CFException();
511 +        }
512 +    }
513 +
514 +    class FailingFunction extends CheckedIntegerAction
515 +        implements Function<Integer, Integer>
516 +    {
517 +        FailingFunction(ExecutionMode m) { super(m); }
518 +        public Integer apply(Integer x) {
519 +            invoked();
520 +            value = x;
521 +            throw new CFException();
522 +        }
523 +    }
524 +
525 +    class FailingBiFunction extends CheckedIntegerAction
526 +        implements BiFunction<Integer, Integer, Integer>
527 +    {
528 +        FailingBiFunction(ExecutionMode m) { super(m); }
529 +        public Integer apply(Integer x, Integer y) {
530 +            invoked();
531 +            value = subtract(x, y);
532 +            throw new CFException();
533 +        }
534 +    }
535 +
536 +    class FailingRunnable extends CheckedAction implements Runnable {
537 +        FailingRunnable(ExecutionMode m) { super(m); }
538 +        public void run() {
539 +            invoked();
540 +            throw new CFException();
541 +        }
542 +    }
543 +
544 +
545 +    class CompletableFutureInc extends CheckedIntegerAction
546 +        implements Function<Integer, CompletableFuture<Integer>>
547 +    {
548 +        CompletableFutureInc(ExecutionMode m) { super(m); }
549 +        public CompletableFuture<Integer> apply(Integer x) {
550 +            invoked();
551 +            value = x;
552 +            CompletableFuture<Integer> f = new CompletableFuture<>();
553 +            assertTrue(f.complete(inc(x)));
554 +            return f;
555 +        }
556 +    }
557 +
558 +    class FailingCompletableFutureFunction extends CheckedIntegerAction
559 +        implements Function<Integer, CompletableFuture<Integer>>
560 +    {
561 +        FailingCompletableFutureFunction(ExecutionMode m) { super(m); }
562 +        public CompletableFuture<Integer> apply(Integer x) {
563 +            invoked();
564 +            value = x;
565 +            throw new CFException();
566 +        }
567 +    }
568 +
569 +    // Used for explicit executor tests
570 +    static final class ThreadExecutor implements Executor {
571 +        final AtomicInteger count = new AtomicInteger(0);
572 +        static final ThreadGroup tg = new ThreadGroup("ThreadExecutor");
573 +        static boolean startedCurrentThread() {
574 +            return Thread.currentThread().getThreadGroup() == tg;
575 +        }
576 +
577 +        public void execute(Runnable r) {
578 +            count.getAndIncrement();
579 +            new Thread(tg, r).start();
580 +        }
581 +    }
582 +
583 +    static final boolean defaultExecutorIsCommonPool
584 +        = ForkJoinPool.getCommonPoolParallelism() > 1;
585 +
586 +    /**
587 +     * Permits the testing of parallel code for the 3 different
588 +     * execution modes without copy/pasting all the test methods.
589 +     */
590 +    enum ExecutionMode {
591 +        SYNC {
592 +            public void checkExecutionMode() {
593 +                assertFalse(ThreadExecutor.startedCurrentThread());
594 +                assertNull(ForkJoinTask.getPool());
595 +            }
596 +            public CompletableFuture<Void> runAsync(Runnable a) {
597 +                throw new UnsupportedOperationException();
598 +            }
599 +            public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
600 +                throw new UnsupportedOperationException();
601 +            }
602 +            public <T> CompletableFuture<Void> thenRun
603 +                (CompletableFuture<T> f, Runnable a) {
604 +                return f.thenRun(a);
605 +            }
606 +            public <T> CompletableFuture<Void> thenAccept
607 +                (CompletableFuture<T> f, Consumer<? super T> a) {
608 +                return f.thenAccept(a);
609 +            }
610 +            public <T,U> CompletableFuture<U> thenApply
611 +                (CompletableFuture<T> f, Function<? super T,U> a) {
612 +                return f.thenApply(a);
613 +            }
614 +            public <T,U> CompletableFuture<U> thenCompose
615 +                (CompletableFuture<T> f,
616 +                 Function<? super T,? extends CompletionStage<U>> a) {
617 +                return f.thenCompose(a);
618 +            }
619 +            public <T,U> CompletableFuture<U> handle
620 +                (CompletableFuture<T> f,
621 +                 BiFunction<? super T,Throwable,? extends U> a) {
622 +                return f.handle(a);
623 +            }
624 +            public <T> CompletableFuture<T> whenComplete
625 +                (CompletableFuture<T> f,
626 +                 BiConsumer<? super T,? super Throwable> a) {
627 +                return f.whenComplete(a);
628 +            }
629 +            public <T,U> CompletableFuture<Void> runAfterBoth
630 +                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
631 +                return f.runAfterBoth(g, a);
632 +            }
633 +            public <T,U> CompletableFuture<Void> thenAcceptBoth
634 +                (CompletableFuture<T> f,
635 +                 CompletionStage<? extends U> g,
636 +                 BiConsumer<? super T,? super U> a) {
637 +                return f.thenAcceptBoth(g, a);
638 +            }
639 +            public <T,U,V> CompletableFuture<V> thenCombine
640 +                (CompletableFuture<T> f,
641 +                 CompletionStage<? extends U> g,
642 +                 BiFunction<? super T,? super U,? extends V> a) {
643 +                return f.thenCombine(g, a);
644 +            }
645 +            public <T> CompletableFuture<Void> runAfterEither
646 +                (CompletableFuture<T> f,
647 +                 CompletionStage<?> g,
648 +                 java.lang.Runnable a) {
649 +                return f.runAfterEither(g, a);
650 +            }
651 +            public <T> CompletableFuture<Void> acceptEither
652 +                (CompletableFuture<T> f,
653 +                 CompletionStage<? extends T> g,
654 +                 Consumer<? super T> a) {
655 +                return f.acceptEither(g, a);
656 +            }
657 +            public <T,U> CompletableFuture<U> applyToEither
658 +                (CompletableFuture<T> f,
659 +                 CompletionStage<? extends T> g,
660 +                 Function<? super T,U> a) {
661 +                return f.applyToEither(g, a);
662 +            }
663 +        },
664 +
665 +        ASYNC {
666 +            public void checkExecutionMode() {
667 +                assertEquals(defaultExecutorIsCommonPool,
668 +                             (ForkJoinPool.commonPool() == ForkJoinTask.getPool()));
669 +            }
670 +            public CompletableFuture<Void> runAsync(Runnable a) {
671 +                return CompletableFuture.runAsync(a);
672 +            }
673 +            public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
674 +                return CompletableFuture.supplyAsync(a);
675 +            }
676 +            public <T> CompletableFuture<Void> thenRun
677 +                (CompletableFuture<T> f, Runnable a) {
678 +                return f.thenRunAsync(a);
679 +            }
680 +            public <T> CompletableFuture<Void> thenAccept
681 +                (CompletableFuture<T> f, Consumer<? super T> a) {
682 +                return f.thenAcceptAsync(a);
683 +            }
684 +            public <T,U> CompletableFuture<U> thenApply
685 +                (CompletableFuture<T> f, Function<? super T,U> a) {
686 +                return f.thenApplyAsync(a);
687 +            }
688 +            public <T,U> CompletableFuture<U> thenCompose
689 +                (CompletableFuture<T> f,
690 +                 Function<? super T,? extends CompletionStage<U>> a) {
691 +                return f.thenComposeAsync(a);
692 +            }
693 +            public <T,U> CompletableFuture<U> handle
694 +                (CompletableFuture<T> f,
695 +                 BiFunction<? super T,Throwable,? extends U> a) {
696 +                return f.handleAsync(a);
697 +            }
698 +            public <T> CompletableFuture<T> whenComplete
699 +                (CompletableFuture<T> f,
700 +                 BiConsumer<? super T,? super Throwable> a) {
701 +                return f.whenCompleteAsync(a);
702 +            }
703 +            public <T,U> CompletableFuture<Void> runAfterBoth
704 +                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
705 +                return f.runAfterBothAsync(g, a);
706 +            }
707 +            public <T,U> CompletableFuture<Void> thenAcceptBoth
708 +                (CompletableFuture<T> f,
709 +                 CompletionStage<? extends U> g,
710 +                 BiConsumer<? super T,? super U> a) {
711 +                return f.thenAcceptBothAsync(g, a);
712 +            }
713 +            public <T,U,V> CompletableFuture<V> thenCombine
714 +                (CompletableFuture<T> f,
715 +                 CompletionStage<? extends U> g,
716 +                 BiFunction<? super T,? super U,? extends V> a) {
717 +                return f.thenCombineAsync(g, a);
718 +            }
719 +            public <T> CompletableFuture<Void> runAfterEither
720 +                (CompletableFuture<T> f,
721 +                 CompletionStage<?> g,
722 +                 java.lang.Runnable a) {
723 +                return f.runAfterEitherAsync(g, a);
724 +            }
725 +            public <T> CompletableFuture<Void> acceptEither
726 +                (CompletableFuture<T> f,
727 +                 CompletionStage<? extends T> g,
728 +                 Consumer<? super T> a) {
729 +                return f.acceptEitherAsync(g, a);
730 +            }
731 +            public <T,U> CompletableFuture<U> applyToEither
732 +                (CompletableFuture<T> f,
733 +                 CompletionStage<? extends T> g,
734 +                 Function<? super T,U> a) {
735 +                return f.applyToEitherAsync(g, a);
736 +            }
737 +        },
738 +
739 +        EXECUTOR {
740 +            public void checkExecutionMode() {
741 +                assertTrue(ThreadExecutor.startedCurrentThread());
742 +            }
743 +            public CompletableFuture<Void> runAsync(Runnable a) {
744 +                return CompletableFuture.runAsync(a, new ThreadExecutor());
745 +            }
746 +            public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
747 +                return CompletableFuture.supplyAsync(a, new ThreadExecutor());
748 +            }
749 +            public <T> CompletableFuture<Void> thenRun
750 +                (CompletableFuture<T> f, Runnable a) {
751 +                return f.thenRunAsync(a, new ThreadExecutor());
752 +            }
753 +            public <T> CompletableFuture<Void> thenAccept
754 +                (CompletableFuture<T> f, Consumer<? super T> a) {
755 +                return f.thenAcceptAsync(a, new ThreadExecutor());
756 +            }
757 +            public <T,U> CompletableFuture<U> thenApply
758 +                (CompletableFuture<T> f, Function<? super T,U> a) {
759 +                return f.thenApplyAsync(a, new ThreadExecutor());
760 +            }
761 +            public <T,U> CompletableFuture<U> thenCompose
762 +                (CompletableFuture<T> f,
763 +                 Function<? super T,? extends CompletionStage<U>> a) {
764 +                return f.thenComposeAsync(a, new ThreadExecutor());
765 +            }
766 +            public <T,U> CompletableFuture<U> handle
767 +                (CompletableFuture<T> f,
768 +                 BiFunction<? super T,Throwable,? extends U> a) {
769 +                return f.handleAsync(a, new ThreadExecutor());
770 +            }
771 +            public <T> CompletableFuture<T> whenComplete
772 +                (CompletableFuture<T> f,
773 +                 BiConsumer<? super T,? super Throwable> a) {
774 +                return f.whenCompleteAsync(a, new ThreadExecutor());
775 +            }
776 +            public <T,U> CompletableFuture<Void> runAfterBoth
777 +                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
778 +                return f.runAfterBothAsync(g, a, new ThreadExecutor());
779 +            }
780 +            public <T,U> CompletableFuture<Void> thenAcceptBoth
781 +                (CompletableFuture<T> f,
782 +                 CompletionStage<? extends U> g,
783 +                 BiConsumer<? super T,? super U> a) {
784 +                return f.thenAcceptBothAsync(g, a, new ThreadExecutor());
785 +            }
786 +            public <T,U,V> CompletableFuture<V> thenCombine
787 +                (CompletableFuture<T> f,
788 +                 CompletionStage<? extends U> g,
789 +                 BiFunction<? super T,? super U,? extends V> a) {
790 +                return f.thenCombineAsync(g, a, new ThreadExecutor());
791 +            }
792 +            public <T> CompletableFuture<Void> runAfterEither
793 +                (CompletableFuture<T> f,
794 +                 CompletionStage<?> g,
795 +                 java.lang.Runnable a) {
796 +                return f.runAfterEitherAsync(g, a, new ThreadExecutor());
797 +            }
798 +            public <T> CompletableFuture<Void> acceptEither
799 +                (CompletableFuture<T> f,
800 +                 CompletionStage<? extends T> g,
801 +                 Consumer<? super T> a) {
802 +                return f.acceptEitherAsync(g, a, new ThreadExecutor());
803 +            }
804 +            public <T,U> CompletableFuture<U> applyToEither
805 +                (CompletableFuture<T> f,
806 +                 CompletionStage<? extends T> g,
807 +                 Function<? super T,U> a) {
808 +                return f.applyToEitherAsync(g, a, new ThreadExecutor());
809 +            }
810 +        };
811 +
812 +        public abstract void checkExecutionMode();
813 +        public abstract CompletableFuture<Void> runAsync(Runnable a);
814 +        public abstract <U> CompletableFuture<U> supplyAsync(Supplier<U> a);
815 +        public abstract <T> CompletableFuture<Void> thenRun
816 +            (CompletableFuture<T> f, Runnable a);
817 +        public abstract <T> CompletableFuture<Void> thenAccept
818 +            (CompletableFuture<T> f, Consumer<? super T> a);
819 +        public abstract <T,U> CompletableFuture<U> thenApply
820 +            (CompletableFuture<T> f, Function<? super T,U> a);
821 +        public abstract <T,U> CompletableFuture<U> thenCompose
822 +            (CompletableFuture<T> f,
823 +             Function<? super T,? extends CompletionStage<U>> a);
824 +        public abstract <T,U> CompletableFuture<U> handle
825 +            (CompletableFuture<T> f,
826 +             BiFunction<? super T,Throwable,? extends U> a);
827 +        public abstract <T> CompletableFuture<T> whenComplete
828 +            (CompletableFuture<T> f,
829 +             BiConsumer<? super T,? super Throwable> a);
830 +        public abstract <T,U> CompletableFuture<Void> runAfterBoth
831 +            (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a);
832 +        public abstract <T,U> CompletableFuture<Void> thenAcceptBoth
833 +            (CompletableFuture<T> f,
834 +             CompletionStage<? extends U> g,
835 +             BiConsumer<? super T,? super U> a);
836 +        public abstract <T,U,V> CompletableFuture<V> thenCombine
837 +            (CompletableFuture<T> f,
838 +             CompletionStage<? extends U> g,
839 +             BiFunction<? super T,? super U,? extends V> a);
840 +        public abstract <T> CompletableFuture<Void> runAfterEither
841 +            (CompletableFuture<T> f,
842 +             CompletionStage<?> g,
843 +             java.lang.Runnable a);
844 +        public abstract <T> CompletableFuture<Void> acceptEither
845 +            (CompletableFuture<T> f,
846 +             CompletionStage<? extends T> g,
847 +             Consumer<? super T> a);
848 +        public abstract <T,U> CompletableFuture<U> applyToEither
849 +            (CompletableFuture<T> f,
850 +             CompletionStage<? extends T> g,
851 +             Function<? super T,U> a);
852      }
853 +
854 +    /**
855 +     * exceptionally action is not invoked when source completes
856 +     * normally, and source result is propagated
857 +     */
858 +    public void testExceptionally_normalCompletion() {
859 +        for (boolean createIncomplete : new boolean[] { true, false })
860 +        for (Integer v1 : new Integer[] { 1, null })
861 +    {
862 +        final AtomicInteger a = new AtomicInteger(0);
863 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
864 +        if (!createIncomplete) assertTrue(f.complete(v1));
865 +        final CompletableFuture<Integer> g = f.exceptionally
866 +            ((Throwable t) -> {
867 +                // Should not be called
868 +                a.getAndIncrement();
869 +                throw new AssertionError();
870 +            });
871 +        if (createIncomplete) assertTrue(f.complete(v1));
872 +
873 +        checkCompletedNormally(g, v1);
874 +        checkCompletedNormally(f, v1);
875 +        assertEquals(0, a.get());
876 +    }}
877 +
878 +    /**
879 +     * exceptionally action completes with function value on source
880 +     * exception
881 +     */
882 +    public void testExceptionally_exceptionalCompletion() {
883 +        for (boolean createIncomplete : new boolean[] { true, false })
884 +        for (Integer v1 : new Integer[] { 1, null })
885 +    {
886 +        final AtomicInteger a = new AtomicInteger(0);
887 +        final CFException ex = new CFException();
888 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
889 +        if (!createIncomplete) f.completeExceptionally(ex);
890 +        final CompletableFuture<Integer> g = f.exceptionally
891 +            ((Throwable t) -> {
892 +                ExecutionMode.SYNC.checkExecutionMode();
893 +                threadAssertSame(t, ex);
894 +                a.getAndIncrement();
895 +                return v1;
896 +            });
897 +        if (createIncomplete) f.completeExceptionally(ex);
898 +
899 +        checkCompletedNormally(g, v1);
900 +        assertEquals(1, a.get());
901 +    }}
902 +
903 +    public void testExceptionally_exceptionalCompletionActionFailed() {
904 +        for (boolean createIncomplete : new boolean[] { true, false })
905 +        for (Integer v1 : new Integer[] { 1, null })
906 +    {
907 +        final AtomicInteger a = new AtomicInteger(0);
908 +        final CFException ex1 = new CFException();
909 +        final CFException ex2 = new CFException();
910 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
911 +        if (!createIncomplete) f.completeExceptionally(ex1);
912 +        final CompletableFuture<Integer> g = f.exceptionally
913 +            ((Throwable t) -> {
914 +                ExecutionMode.SYNC.checkExecutionMode();
915 +                threadAssertSame(t, ex1);
916 +                a.getAndIncrement();
917 +                throw ex2;
918 +            });
919 +        if (createIncomplete) f.completeExceptionally(ex1);
920 +
921 +        checkCompletedWithWrappedException(g, ex2);
922 +        assertEquals(1, a.get());
923 +    }}
924 +
925 +    /**
926 +     * whenComplete action executes on normal completion, propagating
927 +     * source result.
928 +     */
929 +    public void testWhenComplete_normalCompletion1() {
930 +        for (ExecutionMode m : ExecutionMode.values())
931 +        for (boolean createIncomplete : new boolean[] { true, false })
932 +        for (Integer v1 : new Integer[] { 1, null })
933 +    {
934 +        final AtomicInteger a = new AtomicInteger(0);
935 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
936 +        if (!createIncomplete) assertTrue(f.complete(v1));
937 +        final CompletableFuture<Integer> g = m.whenComplete
938 +            (f,
939 +             (Integer x, Throwable t) -> {
940 +                m.checkExecutionMode();
941 +                threadAssertSame(x, v1);
942 +                threadAssertNull(t);
943 +                a.getAndIncrement();
944 +            });
945 +        if (createIncomplete) assertTrue(f.complete(v1));
946 +
947 +        checkCompletedNormally(g, v1);
948 +        checkCompletedNormally(f, v1);
949 +        assertEquals(1, a.get());
950 +    }}
951 +
952 +    /**
953 +     * whenComplete action executes on exceptional completion, propagating
954 +     * source result.
955 +     */
956 +    public void testWhenComplete_exceptionalCompletion() {
957 +        for (ExecutionMode m : ExecutionMode.values())
958 +        for (boolean createIncomplete : new boolean[] { true, false })
959 +        for (Integer v1 : new Integer[] { 1, null })
960 +    {
961 +        final AtomicInteger a = new AtomicInteger(0);
962 +        final CFException ex = new CFException();
963 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
964 +        if (!createIncomplete) f.completeExceptionally(ex);
965 +        final CompletableFuture<Integer> g = m.whenComplete
966 +            (f,
967 +             (Integer x, Throwable t) -> {
968 +                m.checkExecutionMode();
969 +                threadAssertNull(x);
970 +                threadAssertSame(t, ex);
971 +                a.getAndIncrement();
972 +            });
973 +        if (createIncomplete) f.completeExceptionally(ex);
974 +
975 +        checkCompletedWithWrappedException(g, ex);
976 +        checkCompletedExceptionally(f, ex);
977 +        assertEquals(1, a.get());
978 +    }}
979 +
980 +    /**
981 +     * whenComplete action executes on cancelled source, propagating
982 +     * CancellationException.
983 +     */
984 +    public void testWhenComplete_sourceCancelled() {
985 +        for (ExecutionMode m : ExecutionMode.values())
986 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
987 +        for (boolean createIncomplete : new boolean[] { true, false })
988 +    {
989 +        final AtomicInteger a = new AtomicInteger(0);
990 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
991 +        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
992 +        final CompletableFuture<Integer> g = m.whenComplete
993 +            (f,
994 +             (Integer x, Throwable t) -> {
995 +                m.checkExecutionMode();
996 +                threadAssertNull(x);
997 +                threadAssertTrue(t instanceof CancellationException);
998 +                a.getAndIncrement();
999 +            });
1000 +        if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1001 +
1002 +        checkCompletedWithWrappedCancellationException(g);
1003 +        checkCancelled(f);
1004 +        assertEquals(1, a.get());
1005 +    }}
1006 +
1007 +    /**
1008 +     * If a whenComplete action throws an exception when triggered by
1009 +     * a normal completion, it completes exceptionally
1010 +     */
1011 +    public void testWhenComplete_actionFailed() {
1012 +        for (boolean createIncomplete : new boolean[] { true, false })
1013 +        for (ExecutionMode m : ExecutionMode.values())
1014 +        for (Integer v1 : new Integer[] { 1, null })
1015 +    {
1016 +        final AtomicInteger a = new AtomicInteger(0);
1017 +        final CFException ex = new CFException();
1018 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1019 +        if (!createIncomplete) assertTrue(f.complete(v1));
1020 +        final CompletableFuture<Integer> g = m.whenComplete
1021 +            (f,
1022 +             (Integer x, Throwable t) -> {
1023 +                m.checkExecutionMode();
1024 +                threadAssertSame(x, v1);
1025 +                threadAssertNull(t);
1026 +                a.getAndIncrement();
1027 +                throw ex;
1028 +            });
1029 +        if (createIncomplete) assertTrue(f.complete(v1));
1030 +
1031 +        checkCompletedWithWrappedException(g, ex);
1032 +        checkCompletedNormally(f, v1);
1033 +        assertEquals(1, a.get());
1034 +    }}
1035 +
1036 +    /**
1037 +     * If a whenComplete action throws an exception when triggered by
1038 +     * a source completion that also throws an exception, the source
1039 +     * exception takes precedence.
1040 +     */
1041 +    public void testWhenComplete_actionFailedSourceFailed() {
1042 +        for (boolean createIncomplete : new boolean[] { true, false })
1043 +        for (ExecutionMode m : ExecutionMode.values())
1044 +        for (Integer v1 : new Integer[] { 1, null })
1045 +    {
1046 +        final AtomicInteger a = new AtomicInteger(0);
1047 +        final CFException ex1 = new CFException();
1048 +        final CFException ex2 = new CFException();
1049 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1050 +
1051 +        if (!createIncomplete) f.completeExceptionally(ex1);
1052 +        final CompletableFuture<Integer> g = m.whenComplete
1053 +            (f,
1054 +             (Integer x, Throwable t) -> {
1055 +                m.checkExecutionMode();
1056 +                threadAssertSame(t, ex1);
1057 +                threadAssertNull(x);
1058 +                a.getAndIncrement();
1059 +                throw ex2;
1060 +            });
1061 +        if (createIncomplete) f.completeExceptionally(ex1);
1062 +
1063 +        checkCompletedWithWrappedException(g, ex1);
1064 +        checkCompletedExceptionally(f, ex1);
1065 +        assertEquals(1, a.get());
1066 +    }}
1067 +
1068 +    /**
1069 +     * handle action completes normally with function value on normal
1070 +     * completion of source
1071 +     */
1072 +    public void testHandle_normalCompletion() {
1073 +        for (ExecutionMode m : ExecutionMode.values())
1074 +        for (boolean createIncomplete : new boolean[] { true, false })
1075 +        for (Integer v1 : new Integer[] { 1, null })
1076 +    {
1077 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1078 +        final AtomicInteger a = new AtomicInteger(0);
1079 +        if (!createIncomplete) assertTrue(f.complete(v1));
1080 +        final CompletableFuture<Integer> g = m.handle
1081 +            (f,
1082 +             (Integer x, Throwable t) -> {
1083 +                m.checkExecutionMode();
1084 +                threadAssertSame(x, v1);
1085 +                threadAssertNull(t);
1086 +                a.getAndIncrement();
1087 +                return inc(v1);
1088 +            });
1089 +        if (createIncomplete) assertTrue(f.complete(v1));
1090 +
1091 +        checkCompletedNormally(g, inc(v1));
1092 +        checkCompletedNormally(f, v1);
1093 +        assertEquals(1, a.get());
1094 +    }}
1095 +
1096 +    /**
1097 +     * handle action completes normally with function value on
1098 +     * exceptional completion of source
1099 +     */
1100 +    public void testHandle_exceptionalCompletion() {
1101 +        for (ExecutionMode m : ExecutionMode.values())
1102 +        for (boolean createIncomplete : new boolean[] { true, false })
1103 +        for (Integer v1 : new Integer[] { 1, null })
1104 +    {
1105 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1106 +        final AtomicInteger a = new AtomicInteger(0);
1107 +        final CFException ex = new CFException();
1108 +        if (!createIncomplete) f.completeExceptionally(ex);
1109 +        final CompletableFuture<Integer> g = m.handle
1110 +            (f,
1111 +             (Integer x, Throwable t) -> {
1112 +                m.checkExecutionMode();
1113 +                threadAssertNull(x);
1114 +                threadAssertSame(t, ex);
1115 +                a.getAndIncrement();
1116 +                return v1;
1117 +            });
1118 +        if (createIncomplete) f.completeExceptionally(ex);
1119 +
1120 +        checkCompletedNormally(g, v1);
1121 +        checkCompletedExceptionally(f, ex);
1122 +        assertEquals(1, a.get());
1123 +    }}
1124 +
1125 +    /**
1126 +     * handle action completes normally with function value on
1127 +     * cancelled source
1128 +     */
1129 +    public void testHandle_sourceCancelled() {
1130 +        for (ExecutionMode m : ExecutionMode.values())
1131 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1132 +        for (boolean createIncomplete : new boolean[] { true, false })
1133 +        for (Integer v1 : new Integer[] { 1, null })
1134 +    {
1135 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1136 +        final AtomicInteger a = new AtomicInteger(0);
1137 +        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1138 +        final CompletableFuture<Integer> g = m.handle
1139 +            (f,
1140 +             (Integer x, Throwable t) -> {
1141 +                m.checkExecutionMode();
1142 +                threadAssertNull(x);
1143 +                threadAssertTrue(t instanceof CancellationException);
1144 +                a.getAndIncrement();
1145 +                return v1;
1146 +            });
1147 +        if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1148 +
1149 +        checkCompletedNormally(g, v1);
1150 +        checkCancelled(f);
1151 +        assertEquals(1, a.get());
1152 +    }}
1153 +
1154 +    /**
1155 +     * handle result completes exceptionally if action does
1156 +     */
1157 +    public void testHandle_sourceFailedActionFailed() {
1158 +        for (ExecutionMode m : ExecutionMode.values())
1159 +        for (boolean createIncomplete : new boolean[] { true, false })
1160 +    {
1161 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1162 +        final AtomicInteger a = new AtomicInteger(0);
1163 +        final CFException ex1 = new CFException();
1164 +        final CFException ex2 = new CFException();
1165 +        if (!createIncomplete) f.completeExceptionally(ex1);
1166 +        final CompletableFuture<Integer> g = m.handle
1167 +            (f,
1168 +             (Integer x, Throwable t) -> {
1169 +                m.checkExecutionMode();
1170 +                threadAssertNull(x);
1171 +                threadAssertSame(ex1, t);
1172 +                a.getAndIncrement();
1173 +                throw ex2;
1174 +            });
1175 +        if (createIncomplete) f.completeExceptionally(ex1);
1176 +
1177 +        checkCompletedWithWrappedException(g, ex2);
1178 +        checkCompletedExceptionally(f, ex1);
1179 +        assertEquals(1, a.get());
1180 +    }}
1181 +
1182 +    public void testHandle_sourceCompletedNormallyActionFailed() {
1183 +        for (ExecutionMode m : ExecutionMode.values())
1184 +        for (boolean createIncomplete : new boolean[] { true, false })
1185 +        for (Integer v1 : new Integer[] { 1, null })
1186 +    {
1187 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1188 +        final AtomicInteger a = new AtomicInteger(0);
1189 +        final CFException ex = new CFException();
1190 +        if (!createIncomplete) assertTrue(f.complete(v1));
1191 +        final CompletableFuture<Integer> g = m.handle
1192 +            (f,
1193 +             (Integer x, Throwable t) -> {
1194 +                m.checkExecutionMode();
1195 +                threadAssertSame(x, v1);
1196 +                threadAssertNull(t);
1197 +                a.getAndIncrement();
1198 +                throw ex;
1199 +            });
1200 +        if (createIncomplete) assertTrue(f.complete(v1));
1201 +
1202 +        checkCompletedWithWrappedException(g, ex);
1203 +        checkCompletedNormally(f, v1);
1204 +        assertEquals(1, a.get());
1205 +    }}
1206 +
1207 +    /**
1208 +     * runAsync completes after running Runnable
1209 +     */
1210 +    public void testRunAsync_normalCompletion() {
1211 +        ExecutionMode[] executionModes = {
1212 +            ExecutionMode.ASYNC,
1213 +            ExecutionMode.EXECUTOR,
1214 +        };
1215 +        for (ExecutionMode m : executionModes)
1216 +    {
1217 +        final Noop r = new Noop(m);
1218 +        final CompletableFuture<Void> f = m.runAsync(r);
1219 +        assertNull(f.join());
1220 +        checkCompletedNormally(f, null);
1221 +        r.assertInvoked();
1222 +    }}
1223 +
1224 +    /**
1225 +     * failing runAsync completes exceptionally after running Runnable
1226 +     */
1227 +    public void testRunAsync_exceptionalCompletion() {
1228 +        ExecutionMode[] executionModes = {
1229 +            ExecutionMode.ASYNC,
1230 +            ExecutionMode.EXECUTOR,
1231 +        };
1232 +        for (ExecutionMode m : executionModes)
1233 +    {
1234 +        final FailingRunnable r = new FailingRunnable(m);
1235 +        final CompletableFuture<Void> f = m.runAsync(r);
1236 +        checkCompletedWithWrappedCFException(f);
1237 +        r.assertInvoked();
1238 +    }}
1239 +
1240 +    /**
1241 +     * supplyAsync completes with result of supplier
1242 +     */
1243 +    public void testSupplyAsync_normalCompletion() {
1244 +        ExecutionMode[] executionModes = {
1245 +            ExecutionMode.ASYNC,
1246 +            ExecutionMode.EXECUTOR,
1247 +        };
1248 +        for (ExecutionMode m : executionModes)
1249 +        for (Integer v1 : new Integer[] { 1, null })
1250 +    {
1251 +        final IntegerSupplier r = new IntegerSupplier(m, v1);
1252 +        final CompletableFuture<Integer> f = m.supplyAsync(r);
1253 +        assertSame(v1, f.join());
1254 +        checkCompletedNormally(f, v1);
1255 +        r.assertInvoked();
1256 +    }}
1257 +
1258 +    /**
1259 +     * Failing supplyAsync completes exceptionally
1260 +     */
1261 +    public void testSupplyAsync_exceptionalCompletion() {
1262 +        ExecutionMode[] executionModes = {
1263 +            ExecutionMode.ASYNC,
1264 +            ExecutionMode.EXECUTOR,
1265 +        };
1266 +        for (ExecutionMode m : executionModes)
1267 +    {
1268 +        FailingSupplier r = new FailingSupplier(m);
1269 +        CompletableFuture<Integer> f = m.supplyAsync(r);
1270 +        checkCompletedWithWrappedCFException(f);
1271 +        r.assertInvoked();
1272 +    }}
1273 +
1274 +    // seq completion methods
1275 +
1276 +    /**
1277 +     * thenRun result completes normally after normal completion of source
1278 +     */
1279 +    public void testThenRun_normalCompletion() {
1280 +        for (ExecutionMode m : ExecutionMode.values())
1281 +        for (Integer v1 : new Integer[] { 1, null })
1282 +    {
1283 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1284 +        final Noop[] rs = new Noop[6];
1285 +        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1286 +
1287 +        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1288 +        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1289 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1290 +        checkIncomplete(h0);
1291 +        checkIncomplete(h1);
1292 +        checkIncomplete(h2);
1293 +        assertTrue(f.complete(v1));
1294 +        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1295 +        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1296 +        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1297 +
1298 +        checkCompletedNormally(h0, null);
1299 +        checkCompletedNormally(h1, null);
1300 +        checkCompletedNormally(h2, null);
1301 +        checkCompletedNormally(h3, null);
1302 +        checkCompletedNormally(h4, null);
1303 +        checkCompletedNormally(h5, null);
1304 +        checkCompletedNormally(f, v1);
1305 +        for (Noop r : rs) r.assertInvoked();
1306 +    }}
1307 +
1308 +    /**
1309 +     * thenRun result completes exceptionally after exceptional
1310 +     * completion of source
1311 +     */
1312 +    public void testThenRun_exceptionalCompletion() {
1313 +        for (ExecutionMode m : ExecutionMode.values())
1314 +    {
1315 +        final CFException ex = new CFException();
1316 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1317 +        final Noop[] rs = new Noop[6];
1318 +        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1319 +
1320 +        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1321 +        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1322 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1323 +        checkIncomplete(h0);
1324 +        checkIncomplete(h1);
1325 +        checkIncomplete(h2);
1326 +        assertTrue(f.completeExceptionally(ex));
1327 +        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1328 +        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1329 +        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1330 +
1331 +        checkCompletedWithWrappedException(h0, ex);
1332 +        checkCompletedWithWrappedException(h1, ex);
1333 +        checkCompletedWithWrappedException(h2, ex);
1334 +        checkCompletedWithWrappedException(h3, ex);
1335 +        checkCompletedWithWrappedException(h4, ex);
1336 +        checkCompletedWithWrappedException(h5, ex);
1337 +        checkCompletedExceptionally(f, ex);
1338 +        for (Noop r : rs) r.assertNotInvoked();
1339 +    }}
1340 +
1341 +    /**
1342 +     * thenRun result completes exceptionally if source cancelled
1343 +     */
1344 +    public void testThenRun_sourceCancelled() {
1345 +        for (ExecutionMode m : ExecutionMode.values())
1346 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1347 +    {
1348 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1349 +        final Noop[] rs = new Noop[6];
1350 +        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1351 +
1352 +        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1353 +        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1354 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1355 +        checkIncomplete(h0);
1356 +        checkIncomplete(h1);
1357 +        checkIncomplete(h2);
1358 +        assertTrue(f.cancel(mayInterruptIfRunning));
1359 +        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1360 +        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1361 +        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1362 +
1363 +        checkCompletedWithWrappedCancellationException(h0);
1364 +        checkCompletedWithWrappedCancellationException(h1);
1365 +        checkCompletedWithWrappedCancellationException(h2);
1366 +        checkCompletedWithWrappedCancellationException(h3);
1367 +        checkCompletedWithWrappedCancellationException(h4);
1368 +        checkCompletedWithWrappedCancellationException(h5);
1369 +        checkCancelled(f);
1370 +        for (Noop r : rs) r.assertNotInvoked();
1371 +    }}
1372 +
1373 +    /**
1374 +     * thenRun result completes exceptionally if action does
1375 +     */
1376 +    public void testThenRun_actionFailed() {
1377 +        for (ExecutionMode m : ExecutionMode.values())
1378 +        for (Integer v1 : new Integer[] { 1, null })
1379 +    {
1380 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1381 +        final FailingRunnable[] rs = new FailingRunnable[6];
1382 +        for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
1383 +
1384 +        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1385 +        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1386 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1387 +        assertTrue(f.complete(v1));
1388 +        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1389 +        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1390 +        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1391 +
1392 +        checkCompletedWithWrappedCFException(h0);
1393 +        checkCompletedWithWrappedCFException(h1);
1394 +        checkCompletedWithWrappedCFException(h2);
1395 +        checkCompletedWithWrappedCFException(h3);
1396 +        checkCompletedWithWrappedCFException(h4);
1397 +        checkCompletedWithWrappedCFException(h5);
1398 +        checkCompletedNormally(f, v1);
1399 +    }}
1400 +
1401 +    /**
1402 +     * thenApply result completes normally after normal completion of source
1403 +     */
1404 +    public void testThenApply_normalCompletion() {
1405 +        for (ExecutionMode m : ExecutionMode.values())
1406 +        for (Integer v1 : new Integer[] { 1, null })
1407 +    {
1408 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1409 +        final IncFunction[] rs = new IncFunction[4];
1410 +        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1411 +
1412 +        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1413 +        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1414 +        checkIncomplete(h0);
1415 +        checkIncomplete(h1);
1416 +        assertTrue(f.complete(v1));
1417 +        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1418 +        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1419 +
1420 +        checkCompletedNormally(h0, inc(v1));
1421 +        checkCompletedNormally(h1, inc(v1));
1422 +        checkCompletedNormally(h2, inc(v1));
1423 +        checkCompletedNormally(h3, inc(v1));
1424 +        checkCompletedNormally(f, v1);
1425 +        for (IncFunction r : rs) r.assertValue(inc(v1));
1426 +    }}
1427 +
1428 +    /**
1429 +     * thenApply result completes exceptionally after exceptional
1430 +     * completion of source
1431 +     */
1432 +    public void testThenApply_exceptionalCompletion() {
1433 +        for (ExecutionMode m : ExecutionMode.values())
1434 +    {
1435 +        final CFException ex = new CFException();
1436 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1437 +        final IncFunction[] rs = new IncFunction[4];
1438 +        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1439 +
1440 +        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1441 +        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1442 +        assertTrue(f.completeExceptionally(ex));
1443 +        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1444 +        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1445 +
1446 +        checkCompletedWithWrappedException(h0, ex);
1447 +        checkCompletedWithWrappedException(h1, ex);
1448 +        checkCompletedWithWrappedException(h2, ex);
1449 +        checkCompletedWithWrappedException(h3, ex);
1450 +        checkCompletedExceptionally(f, ex);
1451 +        for (IncFunction r : rs) r.assertNotInvoked();
1452 +    }}
1453 +
1454 +    /**
1455 +     * thenApply result completes exceptionally if source cancelled
1456 +     */
1457 +    public void testThenApply_sourceCancelled() {
1458 +        for (ExecutionMode m : ExecutionMode.values())
1459 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1460 +    {
1461 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1462 +        final IncFunction[] rs = new IncFunction[4];
1463 +        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1464 +
1465 +        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1466 +        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1467 +        assertTrue(f.cancel(mayInterruptIfRunning));
1468 +        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1469 +        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1470 +
1471 +        checkCompletedWithWrappedCancellationException(h0);
1472 +        checkCompletedWithWrappedCancellationException(h1);
1473 +        checkCompletedWithWrappedCancellationException(h2);
1474 +        checkCompletedWithWrappedCancellationException(h3);
1475 +        checkCancelled(f);
1476 +        for (IncFunction r : rs) r.assertNotInvoked();
1477 +    }}
1478 +
1479 +    /**
1480 +     * thenApply result completes exceptionally if action does
1481 +     */
1482 +    public void testThenApply_actionFailed() {
1483 +        for (ExecutionMode m : ExecutionMode.values())
1484 +        for (Integer v1 : new Integer[] { 1, null })
1485 +    {
1486 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1487 +        final FailingFunction[] rs = new FailingFunction[4];
1488 +        for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
1489 +
1490 +        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1491 +        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1492 +        assertTrue(f.complete(v1));
1493 +        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1494 +        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1495 +
1496 +        checkCompletedWithWrappedCFException(h0);
1497 +        checkCompletedWithWrappedCFException(h1);
1498 +        checkCompletedWithWrappedCFException(h2);
1499 +        checkCompletedWithWrappedCFException(h3);
1500 +        checkCompletedNormally(f, v1);
1501 +    }}
1502 +
1503 +    /**
1504 +     * thenAccept result completes normally after normal completion of source
1505 +     */
1506 +    public void testThenAccept_normalCompletion() {
1507 +        for (ExecutionMode m : ExecutionMode.values())
1508 +        for (Integer v1 : new Integer[] { 1, null })
1509 +    {
1510 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1511 +        final NoopConsumer[] rs = new NoopConsumer[4];
1512 +        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1513 +
1514 +        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1515 +        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1516 +        checkIncomplete(h0);
1517 +        checkIncomplete(h1);
1518 +        assertTrue(f.complete(v1));
1519 +        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1520 +        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1521 +
1522 +        checkCompletedNormally(h0, null);
1523 +        checkCompletedNormally(h1, null);
1524 +        checkCompletedNormally(h2, null);
1525 +        checkCompletedNormally(h3, null);
1526 +        checkCompletedNormally(f, v1);
1527 +        for (NoopConsumer r : rs) r.assertValue(v1);
1528 +    }}
1529 +
1530 +    /**
1531 +     * thenAccept result completes exceptionally after exceptional
1532 +     * completion of source
1533 +     */
1534 +    public void testThenAccept_exceptionalCompletion() {
1535 +        for (ExecutionMode m : ExecutionMode.values())
1536 +    {
1537 +        final CFException ex = new CFException();
1538 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1539 +        final NoopConsumer[] rs = new NoopConsumer[4];
1540 +        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1541 +
1542 +        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1543 +        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1544 +        assertTrue(f.completeExceptionally(ex));
1545 +        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1546 +        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1547 +
1548 +        checkCompletedWithWrappedException(h0, ex);
1549 +        checkCompletedWithWrappedException(h1, ex);
1550 +        checkCompletedWithWrappedException(h2, ex);
1551 +        checkCompletedWithWrappedException(h3, ex);
1552 +        checkCompletedExceptionally(f, ex);
1553 +        for (NoopConsumer r : rs) r.assertNotInvoked();
1554 +    }}
1555 +
1556 +    /**
1557 +     * thenAccept result completes exceptionally if source cancelled
1558 +     */
1559 +    public void testThenAccept_sourceCancelled() {
1560 +        for (ExecutionMode m : ExecutionMode.values())
1561 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1562 +    {
1563 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1564 +        final NoopConsumer[] rs = new NoopConsumer[4];
1565 +        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1566 +
1567 +        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1568 +        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1569 +        assertTrue(f.cancel(mayInterruptIfRunning));
1570 +        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1571 +        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1572 +
1573 +        checkCompletedWithWrappedCancellationException(h0);
1574 +        checkCompletedWithWrappedCancellationException(h1);
1575 +        checkCompletedWithWrappedCancellationException(h2);
1576 +        checkCompletedWithWrappedCancellationException(h3);
1577 +        checkCancelled(f);
1578 +        for (NoopConsumer r : rs) r.assertNotInvoked();
1579 +    }}
1580 +
1581 +    /**
1582 +     * thenAccept result completes exceptionally if action does
1583 +     */
1584 +    public void testThenAccept_actionFailed() {
1585 +        for (ExecutionMode m : ExecutionMode.values())
1586 +        for (Integer v1 : new Integer[] { 1, null })
1587 +    {
1588 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1589 +        final FailingConsumer[] rs = new FailingConsumer[4];
1590 +        for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
1591 +
1592 +        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1593 +        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1594 +        assertTrue(f.complete(v1));
1595 +        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1596 +        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1597 +
1598 +        checkCompletedWithWrappedCFException(h0);
1599 +        checkCompletedWithWrappedCFException(h1);
1600 +        checkCompletedWithWrappedCFException(h2);
1601 +        checkCompletedWithWrappedCFException(h3);
1602 +        checkCompletedNormally(f, v1);
1603 +    }}
1604 +
1605 +    /**
1606 +     * thenCombine result completes normally after normal completion
1607 +     * of sources
1608 +     */
1609 +    public void testThenCombine_normalCompletion() {
1610 +        for (ExecutionMode m : ExecutionMode.values())
1611 +        for (boolean fFirst : new boolean[] { true, false })
1612 +        for (Integer v1 : new Integer[] { 1, null })
1613 +        for (Integer v2 : new Integer[] { 2, null })
1614 +    {
1615 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1616 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1617 +        final SubtractFunction[] rs = new SubtractFunction[6];
1618 +        for (int i = 0; i < rs.length; i++) rs[i] = new SubtractFunction(m);
1619 +
1620 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1621 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1622 +        final Integer w1 =  fFirst ? v1 : v2;
1623 +        final Integer w2 = !fFirst ? v1 : v2;
1624 +
1625 +        final CompletableFuture<Integer> h0 = m.thenCombine(f, g, rs[0]);
1626 +        final CompletableFuture<Integer> h1 = m.thenCombine(fst, fst, rs[1]);
1627 +        assertTrue(fst.complete(w1));
1628 +        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, rs[2]);
1629 +        final CompletableFuture<Integer> h3 = m.thenCombine(fst, fst, rs[3]);
1630 +        checkIncomplete(h0); rs[0].assertNotInvoked();
1631 +        checkIncomplete(h2); rs[2].assertNotInvoked();
1632 +        checkCompletedNormally(h1, subtract(w1, w1));
1633 +        checkCompletedNormally(h3, subtract(w1, w1));
1634 +        rs[1].assertValue(subtract(w1, w1));
1635 +        rs[3].assertValue(subtract(w1, w1));
1636 +        assertTrue(snd.complete(w2));
1637 +        final CompletableFuture<Integer> h4 = m.thenCombine(f, g, rs[4]);
1638 +
1639 +        checkCompletedNormally(h0, subtract(v1, v2));
1640 +        checkCompletedNormally(h2, subtract(v1, v2));
1641 +        checkCompletedNormally(h4, subtract(v1, v2));
1642 +        rs[0].assertValue(subtract(v1, v2));
1643 +        rs[2].assertValue(subtract(v1, v2));
1644 +        rs[4].assertValue(subtract(v1, v2));
1645 +
1646 +        checkCompletedNormally(f, v1);
1647 +        checkCompletedNormally(g, v2);
1648 +    }}
1649 +
1650 +    /**
1651 +     * thenCombine result completes exceptionally after exceptional
1652 +     * completion of either source
1653 +     */
1654 +    public void testThenCombine_exceptionalCompletion() throws Throwable {
1655 +        for (ExecutionMode m : ExecutionMode.values())
1656 +        for (boolean fFirst : new boolean[] { true, false })
1657 +        for (boolean failFirst : new boolean[] { true, false })
1658 +        for (Integer v1 : new Integer[] { 1, null })
1659 +    {
1660 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1661 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1662 +        final CFException ex = new CFException();
1663 +        final SubtractFunction r1 = new SubtractFunction(m);
1664 +        final SubtractFunction r2 = new SubtractFunction(m);
1665 +        final SubtractFunction r3 = new SubtractFunction(m);
1666 +
1667 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1668 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1669 +        final Callable<Boolean> complete1 = failFirst ?
1670 +            () -> fst.completeExceptionally(ex) :
1671 +            () -> fst.complete(v1);
1672 +        final Callable<Boolean> complete2 = failFirst ?
1673 +            () -> snd.complete(v1) :
1674 +            () -> snd.completeExceptionally(ex);
1675 +
1676 +        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1677 +        assertTrue(complete1.call());
1678 +        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1679 +        checkIncomplete(h1);
1680 +        checkIncomplete(h2);
1681 +        assertTrue(complete2.call());
1682 +        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1683 +
1684 +        checkCompletedWithWrappedException(h1, ex);
1685 +        checkCompletedWithWrappedException(h2, ex);
1686 +        checkCompletedWithWrappedException(h3, ex);
1687 +        r1.assertNotInvoked();
1688 +        r2.assertNotInvoked();
1689 +        r3.assertNotInvoked();
1690 +        checkCompletedNormally(failFirst ? snd : fst, v1);
1691 +        checkCompletedExceptionally(failFirst ? fst : snd, ex);
1692 +    }}
1693 +
1694 +    /**
1695 +     * thenCombine result completes exceptionally if either source cancelled
1696 +     */
1697 +    public void testThenCombine_sourceCancelled() throws Throwable {
1698 +        for (ExecutionMode m : ExecutionMode.values())
1699 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1700 +        for (boolean fFirst : new boolean[] { true, false })
1701 +        for (boolean failFirst : new boolean[] { true, false })
1702 +        for (Integer v1 : new Integer[] { 1, null })
1703 +    {
1704 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1705 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1706 +        final SubtractFunction r1 = new SubtractFunction(m);
1707 +        final SubtractFunction r2 = new SubtractFunction(m);
1708 +        final SubtractFunction r3 = new SubtractFunction(m);
1709 +
1710 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1711 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1712 +        final Callable<Boolean> complete1 = failFirst ?
1713 +            () -> fst.cancel(mayInterruptIfRunning) :
1714 +            () -> fst.complete(v1);
1715 +        final Callable<Boolean> complete2 = failFirst ?
1716 +            () -> snd.complete(v1) :
1717 +            () -> snd.cancel(mayInterruptIfRunning);
1718 +
1719 +        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1720 +        assertTrue(complete1.call());
1721 +        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1722 +        checkIncomplete(h1);
1723 +        checkIncomplete(h2);
1724 +        assertTrue(complete2.call());
1725 +        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1726 +
1727 +        checkCompletedWithWrappedCancellationException(h1);
1728 +        checkCompletedWithWrappedCancellationException(h2);
1729 +        checkCompletedWithWrappedCancellationException(h3);
1730 +        r1.assertNotInvoked();
1731 +        r2.assertNotInvoked();
1732 +        r3.assertNotInvoked();
1733 +        checkCompletedNormally(failFirst ? snd : fst, v1);
1734 +        checkCancelled(failFirst ? fst : snd);
1735 +    }}
1736 +
1737 +    /**
1738 +     * thenCombine result completes exceptionally if action does
1739 +     */
1740 +    public void testThenCombine_actionFailed() {
1741 +        for (ExecutionMode m : ExecutionMode.values())
1742 +        for (boolean fFirst : new boolean[] { true, false })
1743 +        for (Integer v1 : new Integer[] { 1, null })
1744 +        for (Integer v2 : new Integer[] { 2, null })
1745 +    {
1746 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1747 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1748 +        final FailingBiFunction r1 = new FailingBiFunction(m);
1749 +        final FailingBiFunction r2 = new FailingBiFunction(m);
1750 +        final FailingBiFunction r3 = new FailingBiFunction(m);
1751 +
1752 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1753 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1754 +        final Integer w1 =  fFirst ? v1 : v2;
1755 +        final Integer w2 = !fFirst ? v1 : v2;
1756 +
1757 +        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1758 +        assertTrue(fst.complete(w1));
1759 +        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1760 +        assertTrue(snd.complete(w2));
1761 +        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1762 +
1763 +        checkCompletedWithWrappedCFException(h1);
1764 +        checkCompletedWithWrappedCFException(h2);
1765 +        checkCompletedWithWrappedCFException(h3);
1766 +        r1.assertInvoked();
1767 +        r2.assertInvoked();
1768 +        r3.assertInvoked();
1769 +        checkCompletedNormally(f, v1);
1770 +        checkCompletedNormally(g, v2);
1771 +    }}
1772 +
1773 +    /**
1774 +     * thenAcceptBoth result completes normally after normal
1775 +     * completion of sources
1776 +     */
1777 +    public void testThenAcceptBoth_normalCompletion() {
1778 +        for (ExecutionMode m : ExecutionMode.values())
1779 +        for (boolean fFirst : new boolean[] { true, false })
1780 +        for (Integer v1 : new Integer[] { 1, null })
1781 +        for (Integer v2 : new Integer[] { 2, null })
1782 +    {
1783 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1784 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1785 +        final SubtractAction r1 = new SubtractAction(m);
1786 +        final SubtractAction r2 = new SubtractAction(m);
1787 +        final SubtractAction r3 = new SubtractAction(m);
1788 +
1789 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1790 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1791 +        final Integer w1 =  fFirst ? v1 : v2;
1792 +        final Integer w2 = !fFirst ? v1 : v2;
1793 +
1794 +        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1795 +        assertTrue(fst.complete(w1));
1796 +        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1797 +        checkIncomplete(h1);
1798 +        checkIncomplete(h2);
1799 +        r1.assertNotInvoked();
1800 +        r2.assertNotInvoked();
1801 +        assertTrue(snd.complete(w2));
1802 +        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1803 +
1804 +        checkCompletedNormally(h1, null);
1805 +        checkCompletedNormally(h2, null);
1806 +        checkCompletedNormally(h3, null);
1807 +        r1.assertValue(subtract(v1, v2));
1808 +        r2.assertValue(subtract(v1, v2));
1809 +        r3.assertValue(subtract(v1, v2));
1810 +        checkCompletedNormally(f, v1);
1811 +        checkCompletedNormally(g, v2);
1812 +    }}
1813 +
1814 +    /**
1815 +     * thenAcceptBoth result completes exceptionally after exceptional
1816 +     * completion of either source
1817 +     */
1818 +    public void testThenAcceptBoth_exceptionalCompletion() throws Throwable {
1819 +        for (ExecutionMode m : ExecutionMode.values())
1820 +        for (boolean fFirst : new boolean[] { true, false })
1821 +        for (boolean failFirst : new boolean[] { true, false })
1822 +        for (Integer v1 : new Integer[] { 1, null })
1823 +    {
1824 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1825 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1826 +        final CFException ex = new CFException();
1827 +        final SubtractAction r1 = new SubtractAction(m);
1828 +        final SubtractAction r2 = new SubtractAction(m);
1829 +        final SubtractAction r3 = new SubtractAction(m);
1830 +
1831 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1832 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1833 +        final Callable<Boolean> complete1 = failFirst ?
1834 +            () -> fst.completeExceptionally(ex) :
1835 +            () -> fst.complete(v1);
1836 +        final Callable<Boolean> complete2 = failFirst ?
1837 +            () -> snd.complete(v1) :
1838 +            () -> snd.completeExceptionally(ex);
1839 +
1840 +        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1841 +        assertTrue(complete1.call());
1842 +        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1843 +        checkIncomplete(h1);
1844 +        checkIncomplete(h2);
1845 +        assertTrue(complete2.call());
1846 +        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1847 +
1848 +        checkCompletedWithWrappedException(h1, ex);
1849 +        checkCompletedWithWrappedException(h2, ex);
1850 +        checkCompletedWithWrappedException(h3, ex);
1851 +        r1.assertNotInvoked();
1852 +        r2.assertNotInvoked();
1853 +        r3.assertNotInvoked();
1854 +        checkCompletedNormally(failFirst ? snd : fst, v1);
1855 +        checkCompletedExceptionally(failFirst ? fst : snd, ex);
1856 +    }}
1857 +
1858 +    /**
1859 +     * thenAcceptBoth result completes exceptionally if either source cancelled
1860 +     */
1861 +    public void testThenAcceptBoth_sourceCancelled() throws Throwable {
1862 +        for (ExecutionMode m : ExecutionMode.values())
1863 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1864 +        for (boolean fFirst : new boolean[] { true, false })
1865 +        for (boolean failFirst : new boolean[] { true, false })
1866 +        for (Integer v1 : new Integer[] { 1, null })
1867 +    {
1868 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1869 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1870 +        final SubtractAction r1 = new SubtractAction(m);
1871 +        final SubtractAction r2 = new SubtractAction(m);
1872 +        final SubtractAction r3 = new SubtractAction(m);
1873 +
1874 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1875 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1876 +        final Callable<Boolean> complete1 = failFirst ?
1877 +            () -> fst.cancel(mayInterruptIfRunning) :
1878 +            () -> fst.complete(v1);
1879 +        final Callable<Boolean> complete2 = failFirst ?
1880 +            () -> snd.complete(v1) :
1881 +            () -> snd.cancel(mayInterruptIfRunning);
1882 +
1883 +        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1884 +        assertTrue(complete1.call());
1885 +        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1886 +        checkIncomplete(h1);
1887 +        checkIncomplete(h2);
1888 +        assertTrue(complete2.call());
1889 +        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1890 +
1891 +        checkCompletedWithWrappedCancellationException(h1);
1892 +        checkCompletedWithWrappedCancellationException(h2);
1893 +        checkCompletedWithWrappedCancellationException(h3);
1894 +        r1.assertNotInvoked();
1895 +        r2.assertNotInvoked();
1896 +        r3.assertNotInvoked();
1897 +        checkCompletedNormally(failFirst ? snd : fst, v1);
1898 +        checkCancelled(failFirst ? fst : snd);
1899 +    }}
1900 +
1901 +    /**
1902 +     * thenAcceptBoth result completes exceptionally if action does
1903 +     */
1904 +    public void testThenAcceptBoth_actionFailed() {
1905 +        for (ExecutionMode m : ExecutionMode.values())
1906 +        for (boolean fFirst : new boolean[] { true, false })
1907 +        for (Integer v1 : new Integer[] { 1, null })
1908 +        for (Integer v2 : new Integer[] { 2, null })
1909 +    {
1910 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1911 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1912 +        final FailingBiConsumer r1 = new FailingBiConsumer(m);
1913 +        final FailingBiConsumer r2 = new FailingBiConsumer(m);
1914 +        final FailingBiConsumer r3 = new FailingBiConsumer(m);
1915 +
1916 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1917 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1918 +        final Integer w1 =  fFirst ? v1 : v2;
1919 +        final Integer w2 = !fFirst ? v1 : v2;
1920 +
1921 +        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1922 +        assertTrue(fst.complete(w1));
1923 +        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1924 +        assertTrue(snd.complete(w2));
1925 +        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1926 +
1927 +        checkCompletedWithWrappedCFException(h1);
1928 +        checkCompletedWithWrappedCFException(h2);
1929 +        checkCompletedWithWrappedCFException(h3);
1930 +        r1.assertInvoked();
1931 +        r2.assertInvoked();
1932 +        r3.assertInvoked();
1933 +        checkCompletedNormally(f, v1);
1934 +        checkCompletedNormally(g, v2);
1935 +    }}
1936 +
1937 +    /**
1938 +     * runAfterBoth result completes normally after normal
1939 +     * completion of sources
1940 +     */
1941 +    public void testRunAfterBoth_normalCompletion() {
1942 +        for (ExecutionMode m : ExecutionMode.values())
1943 +        for (boolean fFirst : new boolean[] { true, false })
1944 +        for (Integer v1 : new Integer[] { 1, null })
1945 +        for (Integer v2 : new Integer[] { 2, null })
1946 +    {
1947 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1948 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1949 +        final Noop r1 = new Noop(m);
1950 +        final Noop r2 = new Noop(m);
1951 +        final Noop r3 = new Noop(m);
1952 +
1953 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1954 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1955 +        final Integer w1 =  fFirst ? v1 : v2;
1956 +        final Integer w2 = !fFirst ? v1 : v2;
1957 +
1958 +        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
1959 +        assertTrue(fst.complete(w1));
1960 +        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
1961 +        checkIncomplete(h1);
1962 +        checkIncomplete(h2);
1963 +        r1.assertNotInvoked();
1964 +        r2.assertNotInvoked();
1965 +        assertTrue(snd.complete(w2));
1966 +        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
1967 +
1968 +        checkCompletedNormally(h1, null);
1969 +        checkCompletedNormally(h2, null);
1970 +        checkCompletedNormally(h3, null);
1971 +        r1.assertInvoked();
1972 +        r2.assertInvoked();
1973 +        r3.assertInvoked();
1974 +        checkCompletedNormally(f, v1);
1975 +        checkCompletedNormally(g, v2);
1976 +    }}
1977 +
1978 +    /**
1979 +     * runAfterBoth result completes exceptionally after exceptional
1980 +     * completion of either source
1981 +     */
1982 +    public void testRunAfterBoth_exceptionalCompletion() throws Throwable {
1983 +        for (ExecutionMode m : ExecutionMode.values())
1984 +        for (boolean fFirst : new boolean[] { true, false })
1985 +        for (boolean failFirst : new boolean[] { true, false })
1986 +        for (Integer v1 : new Integer[] { 1, null })
1987 +    {
1988 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1989 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1990 +        final CFException ex = new CFException();
1991 +        final Noop r1 = new Noop(m);
1992 +        final Noop r2 = new Noop(m);
1993 +        final Noop r3 = new Noop(m);
1994 +
1995 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1996 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1997 +        final Callable<Boolean> complete1 = failFirst ?
1998 +            () -> fst.completeExceptionally(ex) :
1999 +            () -> fst.complete(v1);
2000 +        final Callable<Boolean> complete2 = failFirst ?
2001 +            () -> snd.complete(v1) :
2002 +            () -> snd.completeExceptionally(ex);
2003 +
2004 +        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2005 +        assertTrue(complete1.call());
2006 +        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2007 +        checkIncomplete(h1);
2008 +        checkIncomplete(h2);
2009 +        assertTrue(complete2.call());
2010 +        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2011 +
2012 +        checkCompletedWithWrappedException(h1, ex);
2013 +        checkCompletedWithWrappedException(h2, ex);
2014 +        checkCompletedWithWrappedException(h3, ex);
2015 +        r1.assertNotInvoked();
2016 +        r2.assertNotInvoked();
2017 +        r3.assertNotInvoked();
2018 +        checkCompletedNormally(failFirst ? snd : fst, v1);
2019 +        checkCompletedExceptionally(failFirst ? fst : snd, ex);
2020 +    }}
2021 +
2022 +    /**
2023 +     * runAfterBoth result completes exceptionally if either source cancelled
2024 +     */
2025 +    public void testRunAfterBoth_sourceCancelled() throws Throwable {
2026 +        for (ExecutionMode m : ExecutionMode.values())
2027 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2028 +        for (boolean fFirst : new boolean[] { true, false })
2029 +        for (boolean failFirst : new boolean[] { true, false })
2030 +        for (Integer v1 : new Integer[] { 1, null })
2031 +    {
2032 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2033 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2034 +        final Noop r1 = new Noop(m);
2035 +        final Noop r2 = new Noop(m);
2036 +        final Noop r3 = new Noop(m);
2037 +
2038 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
2039 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
2040 +        final Callable<Boolean> complete1 = failFirst ?
2041 +            () -> fst.cancel(mayInterruptIfRunning) :
2042 +            () -> fst.complete(v1);
2043 +        final Callable<Boolean> complete2 = failFirst ?
2044 +            () -> snd.complete(v1) :
2045 +            () -> snd.cancel(mayInterruptIfRunning);
2046 +
2047 +        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2048 +        assertTrue(complete1.call());
2049 +        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2050 +        checkIncomplete(h1);
2051 +        checkIncomplete(h2);
2052 +        assertTrue(complete2.call());
2053 +        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2054 +
2055 +        checkCompletedWithWrappedCancellationException(h1);
2056 +        checkCompletedWithWrappedCancellationException(h2);
2057 +        checkCompletedWithWrappedCancellationException(h3);
2058 +        r1.assertNotInvoked();
2059 +        r2.assertNotInvoked();
2060 +        r3.assertNotInvoked();
2061 +        checkCompletedNormally(failFirst ? snd : fst, v1);
2062 +        checkCancelled(failFirst ? fst : snd);
2063 +    }}
2064 +
2065 +    /**
2066 +     * runAfterBoth result completes exceptionally if action does
2067 +     */
2068 +    public void testRunAfterBoth_actionFailed() {
2069 +        for (ExecutionMode m : ExecutionMode.values())
2070 +        for (boolean fFirst : new boolean[] { true, false })
2071 +        for (Integer v1 : new Integer[] { 1, null })
2072 +        for (Integer v2 : new Integer[] { 2, null })
2073 +    {
2074 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2075 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2076 +        final FailingRunnable r1 = new FailingRunnable(m);
2077 +        final FailingRunnable r2 = new FailingRunnable(m);
2078 +        final FailingRunnable r3 = new FailingRunnable(m);
2079 +
2080 +        final CompletableFuture<Integer> fst =  fFirst ? f : g;
2081 +        final CompletableFuture<Integer> snd = !fFirst ? f : g;
2082 +        final Integer w1 =  fFirst ? v1 : v2;
2083 +        final Integer w2 = !fFirst ? v1 : v2;
2084 +
2085 +        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2086 +        assertTrue(fst.complete(w1));
2087 +        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2088 +        assertTrue(snd.complete(w2));
2089 +        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2090 +
2091 +        checkCompletedWithWrappedCFException(h1);
2092 +        checkCompletedWithWrappedCFException(h2);
2093 +        checkCompletedWithWrappedCFException(h3);
2094 +        r1.assertInvoked();
2095 +        r2.assertInvoked();
2096 +        r3.assertInvoked();
2097 +        checkCompletedNormally(f, v1);
2098 +        checkCompletedNormally(g, v2);
2099 +    }}
2100 +
2101 +    /**
2102 +     * applyToEither result completes normally after normal completion
2103 +     * of either source
2104 +     */
2105 +    public void testApplyToEither_normalCompletion() {
2106 +        for (ExecutionMode m : ExecutionMode.values())
2107 +        for (Integer v1 : new Integer[] { 1, null })
2108 +        for (Integer v2 : new Integer[] { 2, null })
2109 +    {
2110 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2111 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2112 +        final IncFunction[] rs = new IncFunction[6];
2113 +        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2114 +
2115 +        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2116 +        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2117 +        checkIncomplete(h0);
2118 +        checkIncomplete(h1);
2119 +        rs[0].assertNotInvoked();
2120 +        rs[1].assertNotInvoked();
2121 +        f.complete(v1);
2122 +        checkCompletedNormally(h0, inc(v1));
2123 +        checkCompletedNormally(h1, inc(v1));
2124 +        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2125 +        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2126 +        checkCompletedNormally(h2, inc(v1));
2127 +        checkCompletedNormally(h3, inc(v1));
2128 +        g.complete(v2);
2129 +
2130 +        // unspecified behavior - both source completions available
2131 +        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2132 +        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2133 +        rs[4].assertValue(h4.join());
2134 +        rs[5].assertValue(h5.join());
2135 +        assertTrue(Objects.equals(inc(v1), h4.join()) ||
2136 +                   Objects.equals(inc(v2), h4.join()));
2137 +        assertTrue(Objects.equals(inc(v1), h5.join()) ||
2138 +                   Objects.equals(inc(v2), h5.join()));
2139 +
2140 +        checkCompletedNormally(f, v1);
2141 +        checkCompletedNormally(g, v2);
2142 +        checkCompletedNormally(h0, inc(v1));
2143 +        checkCompletedNormally(h1, inc(v1));
2144 +        checkCompletedNormally(h2, inc(v1));
2145 +        checkCompletedNormally(h3, inc(v1));
2146 +        for (int i = 0; i < 4; i++) rs[i].assertValue(inc(v1));
2147 +    }}
2148 +
2149 +    /**
2150 +     * applyToEither result completes exceptionally after exceptional
2151 +     * completion of either source
2152 +     */
2153 +    public void testApplyToEither_exceptionalCompletion() {
2154 +        for (ExecutionMode m : ExecutionMode.values())
2155 +        for (Integer v1 : new Integer[] { 1, null })
2156 +    {
2157 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2158 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2159 +        final CFException ex = new CFException();
2160 +        final IncFunction[] rs = new IncFunction[6];
2161 +        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2162 +
2163 +        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2164 +        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2165 +        checkIncomplete(h0);
2166 +        checkIncomplete(h1);
2167 +        rs[0].assertNotInvoked();
2168 +        rs[1].assertNotInvoked();
2169 +        f.completeExceptionally(ex);
2170 +        checkCompletedWithWrappedException(h0, ex);
2171 +        checkCompletedWithWrappedException(h1, ex);
2172 +        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2173 +        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2174 +        checkCompletedWithWrappedException(h2, ex);
2175 +        checkCompletedWithWrappedException(h3, ex);
2176 +        g.complete(v1);
2177 +
2178 +        // unspecified behavior - both source completions available
2179 +        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2180 +        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2181 +        try {
2182 +            assertEquals(inc(v1), h4.join());
2183 +            rs[4].assertValue(inc(v1));
2184 +        } catch (CompletionException ok) {
2185 +            checkCompletedWithWrappedException(h4, ex);
2186 +            rs[4].assertNotInvoked();
2187 +        }
2188 +        try {
2189 +            assertEquals(inc(v1), h5.join());
2190 +            rs[5].assertValue(inc(v1));
2191 +        } catch (CompletionException ok) {
2192 +            checkCompletedWithWrappedException(h5, ex);
2193 +            rs[5].assertNotInvoked();
2194 +        }
2195 +
2196 +        checkCompletedExceptionally(f, ex);
2197 +        checkCompletedNormally(g, v1);
2198 +        checkCompletedWithWrappedException(h0, ex);
2199 +        checkCompletedWithWrappedException(h1, ex);
2200 +        checkCompletedWithWrappedException(h2, ex);
2201 +        checkCompletedWithWrappedException(h3, ex);
2202 +        checkCompletedWithWrappedException(h4, ex);
2203 +        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2204 +    }}
2205 +
2206 +    public void testApplyToEither_exceptionalCompletion2() {
2207 +        for (ExecutionMode m : ExecutionMode.values())
2208 +        for (boolean fFirst : new boolean[] { true, false })
2209 +        for (Integer v1 : new Integer[] { 1, null })
2210 +    {
2211 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2212 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2213 +        final CFException ex = new CFException();
2214 +        final IncFunction[] rs = new IncFunction[6];
2215 +        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2216 +
2217 +        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2218 +        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2219 +        assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2220 +        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2221 +        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2222 +        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2223 +
2224 +        // unspecified behavior - both source completions available
2225 +        try {
2226 +            assertEquals(inc(v1), h0.join());
2227 +            rs[0].assertValue(inc(v1));
2228 +        } catch (CompletionException ok) {
2229 +            checkCompletedWithWrappedException(h0, ex);
2230 +            rs[0].assertNotInvoked();
2231 +        }
2232 +        try {
2233 +            assertEquals(inc(v1), h1.join());
2234 +            rs[1].assertValue(inc(v1));
2235 +        } catch (CompletionException ok) {
2236 +            checkCompletedWithWrappedException(h1, ex);
2237 +            rs[1].assertNotInvoked();
2238 +        }
2239 +        try {
2240 +            assertEquals(inc(v1), h2.join());
2241 +            rs[2].assertValue(inc(v1));
2242 +        } catch (CompletionException ok) {
2243 +            checkCompletedWithWrappedException(h2, ex);
2244 +            rs[2].assertNotInvoked();
2245 +        }
2246 +        try {
2247 +            assertEquals(inc(v1), h3.join());
2248 +            rs[3].assertValue(inc(v1));
2249 +        } catch (CompletionException ok) {
2250 +            checkCompletedWithWrappedException(h3, ex);
2251 +            rs[3].assertNotInvoked();
2252 +        }
2253 +
2254 +        checkCompletedNormally(f, v1);
2255 +        checkCompletedExceptionally(g, ex);
2256 +    }}
2257 +
2258 +    /**
2259 +     * applyToEither result completes exceptionally if either source cancelled
2260 +     */
2261 +    public void testApplyToEither_sourceCancelled() {
2262 +        for (ExecutionMode m : ExecutionMode.values())
2263 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2264 +        for (Integer v1 : new Integer[] { 1, null })
2265 +    {
2266 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2267 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2268 +        final IncFunction[] rs = new IncFunction[6];
2269 +        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2270 +
2271 +        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2272 +        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2273 +        checkIncomplete(h0);
2274 +        checkIncomplete(h1);
2275 +        rs[0].assertNotInvoked();
2276 +        rs[1].assertNotInvoked();
2277 +        f.cancel(mayInterruptIfRunning);
2278 +        checkCompletedWithWrappedCancellationException(h0);
2279 +        checkCompletedWithWrappedCancellationException(h1);
2280 +        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2281 +        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2282 +        checkCompletedWithWrappedCancellationException(h2);
2283 +        checkCompletedWithWrappedCancellationException(h3);
2284 +        g.complete(v1);
2285 +
2286 +        // unspecified behavior - both source completions available
2287 +        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2288 +        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2289 +        try {
2290 +            assertEquals(inc(v1), h4.join());
2291 +            rs[4].assertValue(inc(v1));
2292 +        } catch (CompletionException ok) {
2293 +            checkCompletedWithWrappedCancellationException(h4);
2294 +            rs[4].assertNotInvoked();
2295 +        }
2296 +        try {
2297 +            assertEquals(inc(v1), h5.join());
2298 +            rs[5].assertValue(inc(v1));
2299 +        } catch (CompletionException ok) {
2300 +            checkCompletedWithWrappedCancellationException(h5);
2301 +            rs[5].assertNotInvoked();
2302 +        }
2303 +
2304 +        checkCancelled(f);
2305 +        checkCompletedNormally(g, v1);
2306 +        checkCompletedWithWrappedCancellationException(h0);
2307 +        checkCompletedWithWrappedCancellationException(h1);
2308 +        checkCompletedWithWrappedCancellationException(h2);
2309 +        checkCompletedWithWrappedCancellationException(h3);
2310 +        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2311 +    }}
2312 +
2313 +    public void testApplyToEither_sourceCancelled2() {
2314 +        for (ExecutionMode m : ExecutionMode.values())
2315 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2316 +        for (boolean fFirst : new boolean[] { true, false })
2317 +        for (Integer v1 : new Integer[] { 1, null })
2318 +    {
2319 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2320 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2321 +        final IncFunction[] rs = new IncFunction[6];
2322 +        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2323 +
2324 +        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2325 +        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2326 +        assertTrue(fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
2327 +        assertTrue(!fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
2328 +        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2329 +        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2330 +
2331 +        // unspecified behavior - both source completions available
2332 +        try {
2333 +            assertEquals(inc(v1), h0.join());
2334 +            rs[0].assertValue(inc(v1));
2335 +        } catch (CompletionException ok) {
2336 +            checkCompletedWithWrappedCancellationException(h0);
2337 +            rs[0].assertNotInvoked();
2338 +        }
2339 +        try {
2340 +            assertEquals(inc(v1), h1.join());
2341 +            rs[1].assertValue(inc(v1));
2342 +        } catch (CompletionException ok) {
2343 +            checkCompletedWithWrappedCancellationException(h1);
2344 +            rs[1].assertNotInvoked();
2345 +        }
2346 +        try {
2347 +            assertEquals(inc(v1), h2.join());
2348 +            rs[2].assertValue(inc(v1));
2349 +        } catch (CompletionException ok) {
2350 +            checkCompletedWithWrappedCancellationException(h2);
2351 +            rs[2].assertNotInvoked();
2352 +        }
2353 +        try {
2354 +            assertEquals(inc(v1), h3.join());
2355 +            rs[3].assertValue(inc(v1));
2356 +        } catch (CompletionException ok) {
2357 +            checkCompletedWithWrappedCancellationException(h3);
2358 +            rs[3].assertNotInvoked();
2359 +        }
2360 +
2361 +        checkCompletedNormally(f, v1);
2362 +        checkCancelled(g);
2363 +    }}
2364 +
2365 +    /**
2366 +     * applyToEither result completes exceptionally if action does
2367 +     */
2368 +    public void testApplyToEither_actionFailed() {
2369 +        for (ExecutionMode m : ExecutionMode.values())
2370 +        for (Integer v1 : new Integer[] { 1, null })
2371 +        for (Integer v2 : new Integer[] { 2, null })
2372 +    {
2373 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2374 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2375 +        final FailingFunction[] rs = new FailingFunction[6];
2376 +        for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
2377 +
2378 +        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2379 +        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2380 +        f.complete(v1);
2381 +        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2382 +        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2383 +        checkCompletedWithWrappedCFException(h0);
2384 +        checkCompletedWithWrappedCFException(h1);
2385 +        checkCompletedWithWrappedCFException(h2);
2386 +        checkCompletedWithWrappedCFException(h3);
2387 +        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2388 +
2389 +        g.complete(v2);
2390 +
2391 +        // unspecified behavior - both source completions available
2392 +        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2393 +        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2394 +
2395 +        checkCompletedWithWrappedCFException(h4);
2396 +        assertTrue(Objects.equals(v1, rs[4].value) ||
2397 +                   Objects.equals(v2, rs[4].value));
2398 +        checkCompletedWithWrappedCFException(h5);
2399 +        assertTrue(Objects.equals(v1, rs[5].value) ||
2400 +                   Objects.equals(v2, rs[5].value));
2401 +
2402 +        checkCompletedNormally(f, v1);
2403 +        checkCompletedNormally(g, v2);
2404 +    }}
2405 +
2406 +    /**
2407 +     * acceptEither result completes normally after normal completion
2408 +     * of either source
2409 +     */
2410 +    public void testAcceptEither_normalCompletion() {
2411 +        for (ExecutionMode m : ExecutionMode.values())
2412 +        for (Integer v1 : new Integer[] { 1, null })
2413 +        for (Integer v2 : new Integer[] { 2, null })
2414 +    {
2415 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2416 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2417 +        final NoopConsumer[] rs = new NoopConsumer[6];
2418 +        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2419 +
2420 +        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2421 +        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2422 +        checkIncomplete(h0);
2423 +        checkIncomplete(h1);
2424 +        rs[0].assertNotInvoked();
2425 +        rs[1].assertNotInvoked();
2426 +        f.complete(v1);
2427 +        checkCompletedNormally(h0, null);
2428 +        checkCompletedNormally(h1, null);
2429 +        rs[0].assertValue(v1);
2430 +        rs[1].assertValue(v1);
2431 +        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2432 +        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2433 +        checkCompletedNormally(h2, null);
2434 +        checkCompletedNormally(h3, null);
2435 +        rs[2].assertValue(v1);
2436 +        rs[3].assertValue(v1);
2437 +        g.complete(v2);
2438 +
2439 +        // unspecified behavior - both source completions available
2440 +        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2441 +        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2442 +        checkCompletedNormally(h4, null);
2443 +        checkCompletedNormally(h5, null);
2444 +        assertTrue(Objects.equals(v1, rs[4].value) ||
2445 +                   Objects.equals(v2, rs[4].value));
2446 +        assertTrue(Objects.equals(v1, rs[5].value) ||
2447 +                   Objects.equals(v2, rs[5].value));
2448 +
2449 +        checkCompletedNormally(f, v1);
2450 +        checkCompletedNormally(g, v2);
2451 +        checkCompletedNormally(h0, null);
2452 +        checkCompletedNormally(h1, null);
2453 +        checkCompletedNormally(h2, null);
2454 +        checkCompletedNormally(h3, null);
2455 +        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2456 +    }}
2457 +
2458 +    /**
2459 +     * acceptEither result completes exceptionally after exceptional
2460 +     * completion of either source
2461 +     */
2462 +    public void testAcceptEither_exceptionalCompletion() {
2463 +        for (ExecutionMode m : ExecutionMode.values())
2464 +        for (Integer v1 : new Integer[] { 1, null })
2465 +    {
2466 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2467 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2468 +        final CFException ex = new CFException();
2469 +        final NoopConsumer[] rs = new NoopConsumer[6];
2470 +        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2471 +
2472 +        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2473 +        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2474 +        checkIncomplete(h0);
2475 +        checkIncomplete(h1);
2476 +        rs[0].assertNotInvoked();
2477 +        rs[1].assertNotInvoked();
2478 +        f.completeExceptionally(ex);
2479 +        checkCompletedWithWrappedException(h0, ex);
2480 +        checkCompletedWithWrappedException(h1, ex);
2481 +        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2482 +        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2483 +        checkCompletedWithWrappedException(h2, ex);
2484 +        checkCompletedWithWrappedException(h3, ex);
2485 +
2486 +        g.complete(v1);
2487 +
2488 +        // unspecified behavior - both source completions available
2489 +        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2490 +        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2491 +        try {
2492 +            assertNull(h4.join());
2493 +            rs[4].assertValue(v1);
2494 +        } catch (CompletionException ok) {
2495 +            checkCompletedWithWrappedException(h4, ex);
2496 +            rs[4].assertNotInvoked();
2497 +        }
2498 +        try {
2499 +            assertNull(h5.join());
2500 +            rs[5].assertValue(v1);
2501 +        } catch (CompletionException ok) {
2502 +            checkCompletedWithWrappedException(h5, ex);
2503 +            rs[5].assertNotInvoked();
2504 +        }
2505 +
2506 +        checkCompletedExceptionally(f, ex);
2507 +        checkCompletedNormally(g, v1);
2508 +        checkCompletedWithWrappedException(h0, ex);
2509 +        checkCompletedWithWrappedException(h1, ex);
2510 +        checkCompletedWithWrappedException(h2, ex);
2511 +        checkCompletedWithWrappedException(h3, ex);
2512 +        checkCompletedWithWrappedException(h4, ex);
2513 +        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2514 +    }}
2515 +
2516 +    public void testAcceptEither_exceptionalCompletion2() {
2517 +        for (ExecutionMode m : ExecutionMode.values())
2518 +        for (boolean fFirst : new boolean[] { true, false })
2519 +        for (Integer v1 : new Integer[] { 1, null })
2520 +    {
2521 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2522 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2523 +        final CFException ex = new CFException();
2524 +        final NoopConsumer[] rs = new NoopConsumer[6];
2525 +        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2526 +
2527 +        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2528 +        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2529 +        assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2530 +        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2531 +        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2532 +        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2533 +
2534 +        // unspecified behavior - both source completions available
2535 +        try {
2536 +            assertEquals(null, h0.join());
2537 +            rs[0].assertValue(v1);
2538 +        } catch (CompletionException ok) {
2539 +            checkCompletedWithWrappedException(h0, ex);
2540 +            rs[0].assertNotInvoked();
2541 +        }
2542 +        try {
2543 +            assertEquals(null, h1.join());
2544 +            rs[1].assertValue(v1);
2545 +        } catch (CompletionException ok) {
2546 +            checkCompletedWithWrappedException(h1, ex);
2547 +            rs[1].assertNotInvoked();
2548 +        }
2549 +        try {
2550 +            assertEquals(null, h2.join());
2551 +            rs[2].assertValue(v1);
2552 +        } catch (CompletionException ok) {
2553 +            checkCompletedWithWrappedException(h2, ex);
2554 +            rs[2].assertNotInvoked();
2555 +        }
2556 +        try {
2557 +            assertEquals(null, h3.join());
2558 +            rs[3].assertValue(v1);
2559 +        } catch (CompletionException ok) {
2560 +            checkCompletedWithWrappedException(h3, ex);
2561 +            rs[3].assertNotInvoked();
2562 +        }
2563 +
2564 +        checkCompletedNormally(f, v1);
2565 +        checkCompletedExceptionally(g, ex);
2566 +    }}
2567 +
2568 +    /**
2569 +     * acceptEither result completes exceptionally if either source cancelled
2570 +     */
2571 +    public void testAcceptEither_sourceCancelled() {
2572 +        for (ExecutionMode m : ExecutionMode.values())
2573 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2574 +        for (Integer v1 : new Integer[] { 1, null })
2575 +    {
2576 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2577 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2578 +        final NoopConsumer[] rs = new NoopConsumer[6];
2579 +        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2580 +
2581 +        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2582 +        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2583 +        checkIncomplete(h0);
2584 +        checkIncomplete(h1);
2585 +        rs[0].assertNotInvoked();
2586 +        rs[1].assertNotInvoked();
2587 +        f.cancel(mayInterruptIfRunning);
2588 +        checkCompletedWithWrappedCancellationException(h0);
2589 +        checkCompletedWithWrappedCancellationException(h1);
2590 +        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2591 +        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2592 +        checkCompletedWithWrappedCancellationException(h2);
2593 +        checkCompletedWithWrappedCancellationException(h3);
2594 +
2595 +        g.complete(v1);
2596 +
2597 +        // unspecified behavior - both source completions available
2598 +        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2599 +        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2600 +        try {
2601 +            assertNull(h4.join());
2602 +            rs[4].assertValue(v1);
2603 +        } catch (CompletionException ok) {
2604 +            checkCompletedWithWrappedCancellationException(h4);
2605 +            rs[4].assertNotInvoked();
2606 +        }
2607 +        try {
2608 +            assertNull(h5.join());
2609 +            rs[5].assertValue(v1);
2610 +        } catch (CompletionException ok) {
2611 +            checkCompletedWithWrappedCancellationException(h5);
2612 +            rs[5].assertNotInvoked();
2613 +        }
2614 +
2615 +        checkCancelled(f);
2616 +        checkCompletedNormally(g, v1);
2617 +        checkCompletedWithWrappedCancellationException(h0);
2618 +        checkCompletedWithWrappedCancellationException(h1);
2619 +        checkCompletedWithWrappedCancellationException(h2);
2620 +        checkCompletedWithWrappedCancellationException(h3);
2621 +        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2622 +    }}
2623 +
2624 +    /**
2625 +     * acceptEither result completes exceptionally if action does
2626 +     */
2627 +    public void testAcceptEither_actionFailed() {
2628 +        for (ExecutionMode m : ExecutionMode.values())
2629 +        for (Integer v1 : new Integer[] { 1, null })
2630 +        for (Integer v2 : new Integer[] { 2, null })
2631 +    {
2632 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2633 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2634 +        final FailingConsumer[] rs = new FailingConsumer[6];
2635 +        for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
2636 +
2637 +        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2638 +        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2639 +        f.complete(v1);
2640 +        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2641 +        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2642 +        checkCompletedWithWrappedCFException(h0);
2643 +        checkCompletedWithWrappedCFException(h1);
2644 +        checkCompletedWithWrappedCFException(h2);
2645 +        checkCompletedWithWrappedCFException(h3);
2646 +        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2647 +
2648 +        g.complete(v2);
2649 +
2650 +        // unspecified behavior - both source completions available
2651 +        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2652 +        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2653 +
2654 +        checkCompletedWithWrappedCFException(h4);
2655 +        assertTrue(Objects.equals(v1, rs[4].value) ||
2656 +                   Objects.equals(v2, rs[4].value));
2657 +        checkCompletedWithWrappedCFException(h5);
2658 +        assertTrue(Objects.equals(v1, rs[5].value) ||
2659 +                   Objects.equals(v2, rs[5].value));
2660 +
2661 +        checkCompletedNormally(f, v1);
2662 +        checkCompletedNormally(g, v2);
2663 +    }}
2664 +
2665 +    /**
2666 +     * runAfterEither result completes normally after normal completion
2667 +     * of either source
2668 +     */
2669 +    public void testRunAfterEither_normalCompletion() {
2670 +        for (ExecutionMode m : ExecutionMode.values())
2671 +        for (Integer v1 : new Integer[] { 1, null })
2672 +        for (Integer v2 : new Integer[] { 2, null })
2673 +    {
2674 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2675 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2676 +        final Noop[] rs = new Noop[6];
2677 +        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2678 +
2679 +        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2680 +        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2681 +        checkIncomplete(h0);
2682 +        checkIncomplete(h1);
2683 +        rs[0].assertNotInvoked();
2684 +        rs[1].assertNotInvoked();
2685 +        f.complete(v1);
2686 +        checkCompletedNormally(h0, null);
2687 +        checkCompletedNormally(h1, null);
2688 +        rs[0].assertInvoked();
2689 +        rs[1].assertInvoked();
2690 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2691 +        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2692 +        checkCompletedNormally(h2, null);
2693 +        checkCompletedNormally(h3, null);
2694 +        rs[2].assertInvoked();
2695 +        rs[3].assertInvoked();
2696 +
2697 +        g.complete(v2);
2698 +
2699 +        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2700 +        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2701 +
2702 +        checkCompletedNormally(f, v1);
2703 +        checkCompletedNormally(g, v2);
2704 +        checkCompletedNormally(h0, null);
2705 +        checkCompletedNormally(h1, null);
2706 +        checkCompletedNormally(h2, null);
2707 +        checkCompletedNormally(h3, null);
2708 +        checkCompletedNormally(h4, null);
2709 +        checkCompletedNormally(h5, null);
2710 +        for (int i = 0; i < 6; i++) rs[i].assertInvoked();
2711 +    }}
2712 +
2713 +    /**
2714 +     * runAfterEither result completes exceptionally after exceptional
2715 +     * completion of either source
2716 +     */
2717 +    public void testRunAfterEither_exceptionalCompletion() {
2718 +        for (ExecutionMode m : ExecutionMode.values())
2719 +        for (Integer v1 : new Integer[] { 1, null })
2720 +    {
2721 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2722 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2723 +        final CFException ex = new CFException();
2724 +        final Noop[] rs = new Noop[6];
2725 +        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2726 +
2727 +        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2728 +        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2729 +        checkIncomplete(h0);
2730 +        checkIncomplete(h1);
2731 +        rs[0].assertNotInvoked();
2732 +        rs[1].assertNotInvoked();
2733 +        assertTrue(f.completeExceptionally(ex));
2734 +        checkCompletedWithWrappedException(h0, ex);
2735 +        checkCompletedWithWrappedException(h1, ex);
2736 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2737 +        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2738 +        checkCompletedWithWrappedException(h2, ex);
2739 +        checkCompletedWithWrappedException(h3, ex);
2740 +
2741 +        assertTrue(g.complete(v1));
2742 +
2743 +        // unspecified behavior - both source completions available
2744 +        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2745 +        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2746 +        try {
2747 +            assertNull(h4.join());
2748 +            rs[4].assertInvoked();
2749 +        } catch (CompletionException ok) {
2750 +            checkCompletedWithWrappedException(h4, ex);
2751 +            rs[4].assertNotInvoked();
2752 +        }
2753 +        try {
2754 +            assertNull(h5.join());
2755 +            rs[5].assertInvoked();
2756 +        } catch (CompletionException ok) {
2757 +            checkCompletedWithWrappedException(h5, ex);
2758 +            rs[5].assertNotInvoked();
2759 +        }
2760 +
2761 +        checkCompletedExceptionally(f, ex);
2762 +        checkCompletedNormally(g, v1);
2763 +        checkCompletedWithWrappedException(h0, ex);
2764 +        checkCompletedWithWrappedException(h1, ex);
2765 +        checkCompletedWithWrappedException(h2, ex);
2766 +        checkCompletedWithWrappedException(h3, ex);
2767 +        checkCompletedWithWrappedException(h4, ex);
2768 +        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2769 +    }}
2770 +
2771 +    public void testRunAfterEither_exceptionalCompletion2() {
2772 +        for (ExecutionMode m : ExecutionMode.values())
2773 +        for (boolean fFirst : new boolean[] { true, false })
2774 +        for (Integer v1 : new Integer[] { 1, null })
2775 +    {
2776 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2777 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2778 +        final CFException ex = new CFException();
2779 +        final Noop[] rs = new Noop[6];
2780 +        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2781 +
2782 +        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2783 +        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2784 +        assertTrue( fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2785 +        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2786 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2787 +        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2788 +
2789 +        // unspecified behavior - both source completions available
2790 +        try {
2791 +            assertEquals(null, h0.join());
2792 +            rs[0].assertInvoked();
2793 +        } catch (CompletionException ok) {
2794 +            checkCompletedWithWrappedException(h0, ex);
2795 +            rs[0].assertNotInvoked();
2796 +        }
2797 +        try {
2798 +            assertEquals(null, h1.join());
2799 +            rs[1].assertInvoked();
2800 +        } catch (CompletionException ok) {
2801 +            checkCompletedWithWrappedException(h1, ex);
2802 +            rs[1].assertNotInvoked();
2803 +        }
2804 +        try {
2805 +            assertEquals(null, h2.join());
2806 +            rs[2].assertInvoked();
2807 +        } catch (CompletionException ok) {
2808 +            checkCompletedWithWrappedException(h2, ex);
2809 +            rs[2].assertNotInvoked();
2810 +        }
2811 +        try {
2812 +            assertEquals(null, h3.join());
2813 +            rs[3].assertInvoked();
2814 +        } catch (CompletionException ok) {
2815 +            checkCompletedWithWrappedException(h3, ex);
2816 +            rs[3].assertNotInvoked();
2817 +        }
2818 +
2819 +        checkCompletedNormally(f, v1);
2820 +        checkCompletedExceptionally(g, ex);
2821 +    }}
2822 +
2823 +    /**
2824 +     * runAfterEither result completes exceptionally if either source cancelled
2825 +     */
2826 +    public void testRunAfterEither_sourceCancelled() {
2827 +        for (ExecutionMode m : ExecutionMode.values())
2828 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2829 +        for (Integer v1 : new Integer[] { 1, null })
2830 +    {
2831 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2832 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2833 +        final Noop[] rs = new Noop[6];
2834 +        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2835 +
2836 +        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2837 +        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2838 +        checkIncomplete(h0);
2839 +        checkIncomplete(h1);
2840 +        rs[0].assertNotInvoked();
2841 +        rs[1].assertNotInvoked();
2842 +        f.cancel(mayInterruptIfRunning);
2843 +        checkCompletedWithWrappedCancellationException(h0);
2844 +        checkCompletedWithWrappedCancellationException(h1);
2845 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2846 +        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2847 +        checkCompletedWithWrappedCancellationException(h2);
2848 +        checkCompletedWithWrappedCancellationException(h3);
2849 +
2850 +        assertTrue(g.complete(v1));
2851 +
2852 +        // unspecified behavior - both source completions available
2853 +        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2854 +        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2855 +        try {
2856 +            assertNull(h4.join());
2857 +            rs[4].assertInvoked();
2858 +        } catch (CompletionException ok) {
2859 +            checkCompletedWithWrappedCancellationException(h4);
2860 +            rs[4].assertNotInvoked();
2861 +        }
2862 +        try {
2863 +            assertNull(h5.join());
2864 +            rs[5].assertInvoked();
2865 +        } catch (CompletionException ok) {
2866 +            checkCompletedWithWrappedCancellationException(h5);
2867 +            rs[5].assertNotInvoked();
2868 +        }
2869 +
2870 +        checkCancelled(f);
2871 +        checkCompletedNormally(g, v1);
2872 +        checkCompletedWithWrappedCancellationException(h0);
2873 +        checkCompletedWithWrappedCancellationException(h1);
2874 +        checkCompletedWithWrappedCancellationException(h2);
2875 +        checkCompletedWithWrappedCancellationException(h3);
2876 +        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2877 +    }}
2878 +
2879 +    /**
2880 +     * runAfterEither result completes exceptionally if action does
2881 +     */
2882 +    public void testRunAfterEither_actionFailed() {
2883 +        for (ExecutionMode m : ExecutionMode.values())
2884 +        for (Integer v1 : new Integer[] { 1, null })
2885 +        for (Integer v2 : new Integer[] { 2, null })
2886 +    {
2887 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2888 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2889 +        final FailingRunnable[] rs = new FailingRunnable[6];
2890 +        for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
2891 +
2892 +        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2893 +        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2894 +        assertTrue(f.complete(v1));
2895 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2896 +        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2897 +        checkCompletedWithWrappedCFException(h0);
2898 +        checkCompletedWithWrappedCFException(h1);
2899 +        checkCompletedWithWrappedCFException(h2);
2900 +        checkCompletedWithWrappedCFException(h3);
2901 +        for (int i = 0; i < 4; i++) rs[i].assertInvoked();
2902 +        assertTrue(g.complete(v2));
2903 +        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2904 +        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2905 +        checkCompletedWithWrappedCFException(h4);
2906 +        checkCompletedWithWrappedCFException(h5);
2907 +
2908 +        checkCompletedNormally(f, v1);
2909 +        checkCompletedNormally(g, v2);
2910 +        for (int i = 0; i < 6; i++) rs[i].assertInvoked();
2911 +    }}
2912 +
2913 +    /**
2914 +     * thenCompose result completes normally after normal completion of source
2915 +     */
2916 +    public void testThenCompose_normalCompletion() {
2917 +        for (ExecutionMode m : ExecutionMode.values())
2918 +        for (boolean createIncomplete : new boolean[] { true, false })
2919 +        for (Integer v1 : new Integer[] { 1, null })
2920 +    {
2921 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2922 +        final CompletableFutureInc r = new CompletableFutureInc(m);
2923 +        if (!createIncomplete) assertTrue(f.complete(v1));
2924 +        final CompletableFuture<Integer> g = m.thenCompose(f, r);
2925 +        if (createIncomplete) assertTrue(f.complete(v1));
2926 +
2927 +        checkCompletedNormally(g, inc(v1));
2928 +        checkCompletedNormally(f, v1);
2929 +        r.assertValue(v1);
2930 +    }}
2931 +
2932 +    /**
2933 +     * thenCompose result completes exceptionally after exceptional
2934 +     * completion of source
2935 +     */
2936 +    public void testThenCompose_exceptionalCompletion() {
2937 +        for (ExecutionMode m : ExecutionMode.values())
2938 +        for (boolean createIncomplete : new boolean[] { true, false })
2939 +    {
2940 +        final CFException ex = new CFException();
2941 +        final CompletableFutureInc r = new CompletableFutureInc(m);
2942 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2943 +        if (!createIncomplete) f.completeExceptionally(ex);
2944 +        final CompletableFuture<Integer> g = m.thenCompose(f, r);
2945 +        if (createIncomplete) f.completeExceptionally(ex);
2946 +
2947 +        checkCompletedWithWrappedException(g, ex);
2948 +        checkCompletedExceptionally(f, ex);
2949 +        r.assertNotInvoked();
2950 +    }}
2951 +
2952 +    /**
2953 +     * thenCompose result completes exceptionally if action does
2954 +     */
2955 +    public void testThenCompose_actionFailed() {
2956 +        for (ExecutionMode m : ExecutionMode.values())
2957 +        for (boolean createIncomplete : new boolean[] { true, false })
2958 +        for (Integer v1 : new Integer[] { 1, null })
2959 +    {
2960 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2961 +        final FailingCompletableFutureFunction r
2962 +            = new FailingCompletableFutureFunction(m);
2963 +        if (!createIncomplete) assertTrue(f.complete(v1));
2964 +        final CompletableFuture<Integer> g = m.thenCompose(f, r);
2965 +        if (createIncomplete) assertTrue(f.complete(v1));
2966 +
2967 +        checkCompletedWithWrappedCFException(g);
2968 +        checkCompletedNormally(f, v1);
2969 +    }}
2970 +
2971 +    /**
2972 +     * thenCompose result completes exceptionally if source cancelled
2973 +     */
2974 +    public void testThenCompose_sourceCancelled() {
2975 +        for (ExecutionMode m : ExecutionMode.values())
2976 +        for (boolean createIncomplete : new boolean[] { true, false })
2977 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2978 +    {
2979 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2980 +        final CompletableFutureInc r = new CompletableFutureInc(m);
2981 +        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
2982 +        final CompletableFuture<Integer> g = m.thenCompose(f, r);
2983 +        if (createIncomplete) {
2984 +            checkIncomplete(g);
2985 +            assertTrue(f.cancel(mayInterruptIfRunning));
2986 +        }
2987 +
2988 +        checkCompletedWithWrappedCancellationException(g);
2989 +        checkCancelled(f);
2990 +    }}
2991 +
2992 +    // other static methods
2993 +
2994 +    /**
2995 +     * allOf(no component futures) returns a future completed normally
2996 +     * with the value null
2997 +     */
2998 +    public void testAllOf_empty() throws Exception {
2999 +        CompletableFuture<Void> f = CompletableFuture.allOf();
3000 +        checkCompletedNormally(f, null);
3001 +    }
3002 +
3003 +    /**
3004 +     * allOf returns a future completed normally with the value null
3005 +     * when all components complete normally
3006 +     */
3007 +    public void testAllOf_normal() throws Exception {
3008 +        for (int k = 1; k < 10; k++) {
3009 +            CompletableFuture<Integer>[] fs
3010 +                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3011 +            for (int i = 0; i < k; i++)
3012 +                fs[i] = new CompletableFuture<>();
3013 +            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3014 +            for (int i = 0; i < k; i++) {
3015 +                checkIncomplete(f);
3016 +                checkIncomplete(CompletableFuture.allOf(fs));
3017 +                fs[i].complete(one);
3018 +            }
3019 +            checkCompletedNormally(f, null);
3020 +            checkCompletedNormally(CompletableFuture.allOf(fs), null);
3021 +        }
3022 +    }
3023 +
3024 +    public void testAllOf_backwards() throws Exception {
3025 +        for (int k = 1; k < 10; k++) {
3026 +            CompletableFuture<Integer>[] fs
3027 +                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3028 +            for (int i = 0; i < k; i++)
3029 +                fs[i] = new CompletableFuture<>();
3030 +            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3031 +            for (int i = k - 1; i >= 0; i--) {
3032 +                checkIncomplete(f);
3033 +                checkIncomplete(CompletableFuture.allOf(fs));
3034 +                fs[i].complete(one);
3035 +            }
3036 +            checkCompletedNormally(f, null);
3037 +            checkCompletedNormally(CompletableFuture.allOf(fs), null);
3038 +        }
3039 +    }
3040 +
3041 +    public void testAllOf_exceptional() throws Exception {
3042 +        for (int k = 1; k < 10; k++) {
3043 +            CompletableFuture<Integer>[] fs
3044 +                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3045 +            CFException ex = new CFException();
3046 +            for (int i = 0; i < k; i++)
3047 +                fs[i] = new CompletableFuture<>();
3048 +            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3049 +            for (int i = 0; i < k; i++) {
3050 +                checkIncomplete(f);
3051 +                checkIncomplete(CompletableFuture.allOf(fs));
3052 +                if (i != k/2) {
3053 +                    fs[i].complete(i);
3054 +                    checkCompletedNormally(fs[i], i);
3055 +                } else {
3056 +                    fs[i].completeExceptionally(ex);
3057 +                    checkCompletedExceptionally(fs[i], ex);
3058 +                }
3059 +            }
3060 +            checkCompletedWithWrappedException(f, ex);
3061 +            checkCompletedWithWrappedException(CompletableFuture.allOf(fs), ex);
3062 +        }
3063 +    }
3064 +
3065 +    /**
3066 +     * anyOf(no component futures) returns an incomplete future
3067 +     */
3068 +    public void testAnyOf_empty() throws Exception {
3069 +        for (Integer v1 : new Integer[] { 1, null })
3070 +    {
3071 +        CompletableFuture<Object> f = CompletableFuture.anyOf();
3072 +        checkIncomplete(f);
3073 +
3074 +        f.complete(v1);
3075 +        checkCompletedNormally(f, v1);
3076 +    }}
3077 +
3078 +    /**
3079 +     * anyOf returns a future completed normally with a value when
3080 +     * a component future does
3081 +     */
3082 +    public void testAnyOf_normal() throws Exception {
3083 +        for (int k = 0; k < 10; k++) {
3084 +            CompletableFuture[] fs = new CompletableFuture[k];
3085 +            for (int i = 0; i < k; i++)
3086 +                fs[i] = new CompletableFuture<>();
3087 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3088 +            checkIncomplete(f);
3089 +            for (int i = 0; i < k; i++) {
3090 +                fs[i].complete(i);
3091 +                checkCompletedNormally(f, 0);
3092 +                int x = (int) CompletableFuture.anyOf(fs).join();
3093 +                assertTrue(0 <= x && x <= i);
3094 +            }
3095 +        }
3096 +    }
3097 +    public void testAnyOf_normal_backwards() throws Exception {
3098 +        for (int k = 0; k < 10; k++) {
3099 +            CompletableFuture[] fs = new CompletableFuture[k];
3100 +            for (int i = 0; i < k; i++)
3101 +                fs[i] = new CompletableFuture<>();
3102 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3103 +            checkIncomplete(f);
3104 +            for (int i = k - 1; i >= 0; i--) {
3105 +                fs[i].complete(i);
3106 +                checkCompletedNormally(f, k - 1);
3107 +                int x = (int) CompletableFuture.anyOf(fs).join();
3108 +                assertTrue(i <= x && x <= k - 1);
3109 +            }
3110 +        }
3111 +    }
3112 +
3113 +    /**
3114 +     * anyOf result completes exceptionally when any component does.
3115 +     */
3116 +    public void testAnyOf_exceptional() throws Exception {
3117 +        for (int k = 0; k < 10; k++) {
3118 +            CompletableFuture[] fs = new CompletableFuture[k];
3119 +            CFException[] exs = new CFException[k];
3120 +            for (int i = 0; i < k; i++) {
3121 +                fs[i] = new CompletableFuture<>();
3122 +                exs[i] = new CFException();
3123 +            }
3124 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3125 +            checkIncomplete(f);
3126 +            for (int i = 0; i < k; i++) {
3127 +                fs[i].completeExceptionally(exs[i]);
3128 +                checkCompletedWithWrappedException(f, exs[0]);
3129 +                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3130 +            }
3131 +        }
3132 +    }
3133 +
3134 +    public void testAnyOf_exceptional_backwards() throws Exception {
3135 +        for (int k = 0; k < 10; k++) {
3136 +            CompletableFuture[] fs = new CompletableFuture[k];
3137 +            CFException[] exs = new CFException[k];
3138 +            for (int i = 0; i < k; i++) {
3139 +                fs[i] = new CompletableFuture<>();
3140 +                exs[i] = new CFException();
3141 +            }
3142 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3143 +            checkIncomplete(f);
3144 +            for (int i = k - 1; i >= 0; i--) {
3145 +                fs[i].completeExceptionally(exs[i]);
3146 +                checkCompletedWithWrappedException(f, exs[k - 1]);
3147 +                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3148 +            }
3149 +        }
3150 +    }
3151 +
3152 +    /**
3153 +     * Completion methods throw NullPointerException with null arguments
3154 +     */
3155 +    public void testNPE() {
3156 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3157 +        CompletableFuture<Integer> g = new CompletableFuture<>();
3158 +        CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
3159 +        CompletableFuture<?> h;
3160 +        ThreadExecutor exec = new ThreadExecutor();
3161 +
3162 +        Runnable[] throwingActions = {
3163 +            () -> CompletableFuture.supplyAsync(null),
3164 +            () -> CompletableFuture.supplyAsync(null, exec),
3165 +            () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.SYNC, 42), null),
3166 +
3167 +            () -> CompletableFuture.runAsync(null),
3168 +            () -> CompletableFuture.runAsync(null, exec),
3169 +            () -> CompletableFuture.runAsync(() -> {}, null),
3170 +
3171 +            () -> f.completeExceptionally(null),
3172 +
3173 +            () -> f.thenApply(null),
3174 +            () -> f.thenApplyAsync(null),
3175 +            () -> f.thenApplyAsync((x) -> x, null),
3176 +            () -> f.thenApplyAsync(null, exec),
3177 +
3178 +            () -> f.thenAccept(null),
3179 +            () -> f.thenAcceptAsync(null),
3180 +            () -> f.thenAcceptAsync((x) -> {} , null),
3181 +            () -> f.thenAcceptAsync(null, exec),
3182 +
3183 +            () -> f.thenRun(null),
3184 +            () -> f.thenRunAsync(null),
3185 +            () -> f.thenRunAsync(() -> {} , null),
3186 +            () -> f.thenRunAsync(null, exec),
3187 +
3188 +            () -> f.thenCombine(g, null),
3189 +            () -> f.thenCombineAsync(g, null),
3190 +            () -> f.thenCombineAsync(g, null, exec),
3191 +            () -> f.thenCombine(nullFuture, (x, y) -> x),
3192 +            () -> f.thenCombineAsync(nullFuture, (x, y) -> x),
3193 +            () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec),
3194 +            () -> f.thenCombineAsync(g, (x, y) -> x, null),
3195 +
3196 +            () -> f.thenAcceptBoth(g, null),
3197 +            () -> f.thenAcceptBothAsync(g, null),
3198 +            () -> f.thenAcceptBothAsync(g, null, exec),
3199 +            () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}),
3200 +            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}),
3201 +            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec),
3202 +            () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null),
3203 +
3204 +            () -> f.runAfterBoth(g, null),
3205 +            () -> f.runAfterBothAsync(g, null),
3206 +            () -> f.runAfterBothAsync(g, null, exec),
3207 +            () -> f.runAfterBoth(nullFuture, () -> {}),
3208 +            () -> f.runAfterBothAsync(nullFuture, () -> {}),
3209 +            () -> f.runAfterBothAsync(nullFuture, () -> {}, exec),
3210 +            () -> f.runAfterBothAsync(g, () -> {}, null),
3211 +
3212 +            () -> f.applyToEither(g, null),
3213 +            () -> f.applyToEitherAsync(g, null),
3214 +            () -> f.applyToEitherAsync(g, null, exec),
3215 +            () -> f.applyToEither(nullFuture, (x) -> x),
3216 +            () -> f.applyToEitherAsync(nullFuture, (x) -> x),
3217 +            () -> f.applyToEitherAsync(nullFuture, (x) -> x, exec),
3218 +            () -> f.applyToEitherAsync(g, (x) -> x, null),
3219 +
3220 +            () -> f.acceptEither(g, null),
3221 +            () -> f.acceptEitherAsync(g, null),
3222 +            () -> f.acceptEitherAsync(g, null, exec),
3223 +            () -> f.acceptEither(nullFuture, (x) -> {}),
3224 +            () -> f.acceptEitherAsync(nullFuture, (x) -> {}),
3225 +            () -> f.acceptEitherAsync(nullFuture, (x) -> {}, exec),
3226 +            () -> f.acceptEitherAsync(g, (x) -> {}, null),
3227 +
3228 +            () -> f.runAfterEither(g, null),
3229 +            () -> f.runAfterEitherAsync(g, null),
3230 +            () -> f.runAfterEitherAsync(g, null, exec),
3231 +            () -> f.runAfterEither(nullFuture, () -> {}),
3232 +            () -> f.runAfterEitherAsync(nullFuture, () -> {}),
3233 +            () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec),
3234 +            () -> f.runAfterEitherAsync(g, () -> {}, null),
3235 +
3236 +            () -> f.thenCompose(null),
3237 +            () -> f.thenComposeAsync(null),
3238 +            () -> f.thenComposeAsync(new CompletableFutureInc(ExecutionMode.EXECUTOR), null),
3239 +            () -> f.thenComposeAsync(null, exec),
3240 +
3241 +            () -> f.exceptionally(null),
3242 +
3243 +            () -> f.handle(null),
3244 +
3245 +            () -> CompletableFuture.allOf((CompletableFuture<?>)null),
3246 +            () -> CompletableFuture.allOf((CompletableFuture<?>[])null),
3247 +            () -> CompletableFuture.allOf(f, null),
3248 +            () -> CompletableFuture.allOf(null, f),
3249 +
3250 +            () -> CompletableFuture.anyOf((CompletableFuture<?>)null),
3251 +            () -> CompletableFuture.anyOf((CompletableFuture<?>[])null),
3252 +            () -> CompletableFuture.anyOf(f, null),
3253 +            () -> CompletableFuture.anyOf(null, f),
3254 +
3255 +            () -> f.obtrudeException(null),
3256 +        };
3257 +
3258 +        assertThrows(NullPointerException.class, throwingActions);
3259 +        assertEquals(0, exec.count.get());
3260 +    }
3261 +
3262 +    /**
3263 +     * toCompletableFuture returns this CompletableFuture.
3264 +     */
3265 +    public void testToCompletableFuture() {
3266 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3267 +        assertSame(f, f.toCompletableFuture());
3268 +    }
3269 +
3270 +    //--- tests of implementation details; not part of official tck ---
3271 +
3272 +    Object resultOf(CompletableFuture<?> f) {
3273 +        try {
3274 +            java.lang.reflect.Field resultField
3275 +                = CompletableFuture.class.getDeclaredField("result");
3276 +            resultField.setAccessible(true);
3277 +            return resultField.get(f);
3278 +        } catch (Throwable t) { throw new AssertionError(t); }
3279 +    }
3280 +
3281 +    public void testExceptionPropagationReusesResultObject() {
3282 +        if (!testImplementationDetails) return;
3283 +        for (ExecutionMode m : ExecutionMode.values())
3284 +    {
3285 +        final CFException ex = new CFException();
3286 +        final CompletableFuture<Integer> v42 = CompletableFuture.completedFuture(42);
3287 +        final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
3288 +
3289 +        List<Function<CompletableFuture<Integer>, CompletableFuture<?>>> funs
3290 +            = new ArrayList<>();
3291 +
3292 +        funs.add((y) -> m.thenRun(y, new Noop(m)));
3293 +        funs.add((y) -> m.thenAccept(y, new NoopConsumer(m)));
3294 +        funs.add((y) -> m.thenApply(y, new IncFunction(m)));
3295 +
3296 +        funs.add((y) -> m.runAfterEither(y, incomplete, new Noop(m)));
3297 +        funs.add((y) -> m.acceptEither(y, incomplete, new NoopConsumer(m)));
3298 +        funs.add((y) -> m.applyToEither(y, incomplete, new IncFunction(m)));
3299 +
3300 +        funs.add((y) -> m.runAfterBoth(y, v42, new Noop(m)));
3301 +        funs.add((y) -> m.thenAcceptBoth(y, v42, new SubtractAction(m)));
3302 +        funs.add((y) -> m.thenCombine(y, v42, new SubtractFunction(m)));
3303 +
3304 +        funs.add((y) -> m.whenComplete(y, (Integer x, Throwable t) -> {}));
3305 +
3306 +        funs.add((y) -> m.thenCompose(y, new CompletableFutureInc(m)));
3307 +
3308 +        funs.add((y) -> CompletableFuture.allOf(new CompletableFuture<?>[] {y, v42}));
3309 +        funs.add((y) -> CompletableFuture.anyOf(new CompletableFuture<?>[] {y, incomplete}));
3310 +
3311 +        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3312 +                 fun : funs) {
3313 +            CompletableFuture<Integer> f = new CompletableFuture<>();
3314 +            f.completeExceptionally(ex);
3315 +            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3316 +            checkCompletedWithWrappedException(src, ex);
3317 +            CompletableFuture<?> dep = fun.apply(src);
3318 +            checkCompletedWithWrappedException(dep, ex);
3319 +            assertSame(resultOf(src), resultOf(dep));
3320 +        }
3321 +
3322 +        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3323 +                 fun : funs) {
3324 +            CompletableFuture<Integer> f = new CompletableFuture<>();
3325 +            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3326 +            CompletableFuture<?> dep = fun.apply(src);
3327 +            f.completeExceptionally(ex);
3328 +            checkCompletedWithWrappedException(src, ex);
3329 +            checkCompletedWithWrappedException(dep, ex);
3330 +            assertSame(resultOf(src), resultOf(dep));
3331 +        }
3332 +
3333 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
3334 +        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3335 +                 fun : funs) {
3336 +            CompletableFuture<Integer> f = new CompletableFuture<>();
3337 +            f.cancel(mayInterruptIfRunning);
3338 +            checkCancelled(f);
3339 +            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3340 +            checkCompletedWithWrappedCancellationException(src);
3341 +            CompletableFuture<?> dep = fun.apply(src);
3342 +            checkCompletedWithWrappedCancellationException(dep);
3343 +            assertSame(resultOf(src), resultOf(dep));
3344 +        }
3345 +
3346 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
3347 +        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3348 +                 fun : funs) {
3349 +            CompletableFuture<Integer> f = new CompletableFuture<>();
3350 +            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3351 +            CompletableFuture<?> dep = fun.apply(src);
3352 +            f.cancel(mayInterruptIfRunning);
3353 +            checkCancelled(f);
3354 +            checkCompletedWithWrappedCancellationException(src);
3355 +            checkCompletedWithWrappedCancellationException(dep);
3356 +            assertSame(resultOf(src), resultOf(dep));
3357 +        }
3358 +    }}
3359 +
3360   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines