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

Comparing jsr166/src/test/tck/CountedCompleterTest.java (file contents):
Revision 1.2 by dl, Thu Mar 21 16:26:43 2013 UTC vs.
Revision 1.32 by jsr166, Sat Mar 11 17:33:32 2017 UTC

# Line 3 | Line 3
3   * Expert Group and released to the public domain, as explained at
4   * http://creativecommons.org/publicdomain/zero/1.0/
5   */
6 < import java.util.concurrent.ExecutionException;
6 >
7 > import static java.util.concurrent.TimeUnit.MILLISECONDS;
8 > import static java.util.concurrent.TimeUnit.SECONDS;
9 >
10 > import java.util.HashSet;
11   import java.util.concurrent.CancellationException;
12 + import java.util.concurrent.CountedCompleter;
13 + import java.util.concurrent.ExecutionException;
14   import java.util.concurrent.ForkJoinPool;
15   import java.util.concurrent.ForkJoinTask;
10 import java.util.concurrent.CountedCompleter;
11 import java.util.concurrent.ForkJoinWorkerThread;
12 import java.util.concurrent.RecursiveAction;
13 import java.util.concurrent.TimeUnit;
16   import java.util.concurrent.TimeoutException;
17 < import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
18 < import static java.util.concurrent.TimeUnit.MILLISECONDS;
19 < import static java.util.concurrent.TimeUnit.SECONDS;
20 < import java.util.HashSet;
21 < import junit.framework.*;
17 > import java.util.concurrent.atomic.AtomicInteger;
18 > import java.util.concurrent.atomic.AtomicReference;
19 >
20 > import junit.framework.Test;
21 > import junit.framework.TestSuite;
22  
23   public class CountedCompleterTest extends JSR166TestCase {
24  
25      public static void main(String[] args) {
26 <        junit.textui.TestRunner.run(suite());
26 >        main(suite(), args);
27      }
28  
29      public static Test suite() {
# Line 32 | Line 34 | public class CountedCompleterTest extend
34      static final int mainPoolSize =
35          Math.max(2, Runtime.getRuntime().availableProcessors());
36  
35    /**
36     * Analog of CheckedRunnable for ForkJoinTasks
37     */
38    public abstract class CheckedFJTask extends RecursiveAction {
39        protected abstract void realCompute() throws Throwable;
40
41        public final void compute() {
42            try {
43                realCompute();
44            } catch (Throwable t) {
45                threadUnexpectedException(t);
46            }
47        }
48    }
49
37      private static ForkJoinPool mainPool() {
38          return new ForkJoinPool(mainPoolSize);
39      }
# Line 62 | Line 49 | public class CountedCompleterTest extend
49      }
50  
51      private void testInvokeOnPool(ForkJoinPool pool, ForkJoinTask a) {
52 <        try {
52 >        try (PoolCleaner cleaner = cleaner(pool)) {
53              assertFalse(a.isDone());
54              assertFalse(a.isCompletedNormally());
55              assertFalse(a.isCompletedAbnormally());
# Line 78 | Line 65 | public class CountedCompleterTest extend
65              assertFalse(a.isCancelled());
66              assertNull(a.getException());
67              assertNull(a.getRawResult());
81        } finally {
82            joinPool(pool);
68          }
69      }
70  
# Line 98 | Line 83 | public class CountedCompleterTest extend
83          } catch (Throwable fail) { threadUnexpectedException(fail); }
84      }
85  
86 <    <T> void checkCompletedNormally(CountedCompleter<T> a) {
102 <        checkCompletedNormally(a, null);
103 <    }
104 <
105 <    <T> void checkCompletedNormally(CountedCompleter<T> a, T expected) {
86 >    void checkCompletedNormally(CountedCompleter<?> a) {
87          assertTrue(a.isDone());
88          assertFalse(a.isCancelled());
89          assertTrue(a.isCompletedNormally());
90          assertFalse(a.isCompletedAbnormally());
91          assertNull(a.getException());
92 <        assertSame(expected, a.getRawResult());
92 >        assertNull(a.getRawResult());
93  
94          {
95              Thread.currentThread().interrupt();
96 <            long t0 = System.nanoTime();
97 <            assertSame(expected, a.join());
98 <            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
96 >            long startTime = System.nanoTime();
97 >            assertNull(a.join());
98 >            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
99              Thread.interrupted();
100          }
101  
102          {
103              Thread.currentThread().interrupt();
104 <            long t0 = System.nanoTime();
104 >            long startTime = System.nanoTime();
105              a.quietlyJoin();        // should be no-op
106 <            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
106 >            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
107              Thread.interrupted();
108          }
109  
110          assertFalse(a.cancel(false));
111          assertFalse(a.cancel(true));
112          try {
113 <            assertSame(expected, a.get());
113 >            assertNull(a.get());
114          } catch (Throwable fail) { threadUnexpectedException(fail); }
115          try {
116 <            assertSame(expected, a.get(5L, SECONDS));
116 >            assertNull(a.get(5L, SECONDS));
117          } catch (Throwable fail) { threadUnexpectedException(fail); }
118      }
119  
# Line 155 | Line 136 | public class CountedCompleterTest extend
136          Thread.interrupted();
137  
138          {
139 <            long t0 = System.nanoTime();
139 >            long startTime = System.nanoTime();
140              a.quietlyJoin();        // should be no-op
141 <            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
141 >            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
142          }
143  
144          try {
# Line 193 | Line 174 | public class CountedCompleterTest extend
174          Thread.interrupted();
175  
176          {
177 <            long t0 = System.nanoTime();
177 >            long startTime = System.nanoTime();
178              a.quietlyJoin();        // should be no-op
179 <            assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS);
179 >            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
180          }
181  
182          try {
# Line 211 | Line 192 | public class CountedCompleterTest extend
192          } catch (ExecutionException success) {
193              assertSame(t.getClass(), success.getCause().getClass());
194          } catch (Throwable fail) { threadUnexpectedException(fail); }
195 +
196 +        try {
197 +            a.invoke();
198 +            shouldThrow();
199 +        } catch (Throwable success) {
200 +            assertSame(t, success);
201 +        }
202      }
203  
204      public static final class FJException extends RuntimeException {
205          FJException() { super(); }
206      }
207  
208 <    static final class NoopCountedCompleter extends CountedCompleter {
209 <        boolean post; // set true if onCompletion called
210 <        NoopCountedCompleter() { super(); }
211 <        NoopCountedCompleter(CountedCompleter p) { super(p); }
212 <        public void compute() {}
213 <        public final void onCompletion(CountedCompleter caller) {
214 <            post = true;
208 >    abstract class CheckedCC extends CountedCompleter<Object> {
209 >        final AtomicInteger computeN = new AtomicInteger(0);
210 >        final AtomicInteger onCompletionN = new AtomicInteger(0);
211 >        final AtomicInteger onExceptionalCompletionN = new AtomicInteger(0);
212 >        final AtomicInteger setRawResultN = new AtomicInteger(0);
213 >        final AtomicReference<Object> rawResult = new AtomicReference<>(null);
214 >        int computeN() { return computeN.get(); }
215 >        int onCompletionN() { return onCompletionN.get(); }
216 >        int onExceptionalCompletionN() { return onExceptionalCompletionN.get(); }
217 >        int setRawResultN() { return setRawResultN.get(); }
218 >
219 >        CheckedCC() { super(); }
220 >        CheckedCC(CountedCompleter p) { super(p); }
221 >        CheckedCC(CountedCompleter p, int n) { super(p, n); }
222 >        abstract void realCompute();
223 >        public final void compute() {
224 >            computeN.incrementAndGet();
225 >            realCompute();
226 >        }
227 >        public void onCompletion(CountedCompleter caller) {
228 >            onCompletionN.incrementAndGet();
229 >            super.onCompletion(caller);
230 >        }
231 >        public boolean onExceptionalCompletion(Throwable ex,
232 >                                               CountedCompleter caller) {
233 >            onExceptionalCompletionN.incrementAndGet();
234 >            assertNotNull(ex);
235 >            assertTrue(isCompletedAbnormally());
236 >            assertTrue(super.onExceptionalCompletion(ex, caller));
237 >            return true;
238 >        }
239 >        protected void setRawResult(Object t) {
240 >            setRawResultN.incrementAndGet();
241 >            rawResult.set(t);
242 >            super.setRawResult(t);
243 >        }
244 >        void checkIncomplete() {
245 >            assertEquals(0, computeN());
246 >            assertEquals(0, onCompletionN());
247 >            assertEquals(0, onExceptionalCompletionN());
248 >            assertEquals(0, setRawResultN());
249 >            checkNotDone(this);
250 >        }
251 >        void checkCompletes(Object rawResult) {
252 >            checkIncomplete();
253 >            int pendingCount = getPendingCount();
254 >            complete(rawResult);
255 >            assertEquals(pendingCount, getPendingCount());
256 >            assertEquals(0, computeN());
257 >            assertEquals(1, onCompletionN());
258 >            assertEquals(0, onExceptionalCompletionN());
259 >            assertEquals(1, setRawResultN());
260 >            assertSame(rawResult, this.rawResult.get());
261 >            checkCompletedNormally(this);
262 >        }
263 >        void checkCompletesExceptionally(Throwable ex) {
264 >            checkIncomplete();
265 >            completeExceptionally(ex);
266 >            checkCompletedExceptionally(ex);
267 >        }
268 >        void checkCompletedExceptionally(Throwable ex) {
269 >            assertEquals(0, computeN());
270 >            assertEquals(0, onCompletionN());
271 >            assertEquals(1, onExceptionalCompletionN());
272 >            assertEquals(0, setRawResultN());
273 >            assertNull(this.rawResult.get());
274 >            checkCompletedAbnormally(this, ex);
275          }
276      }
277  
278 +    final class NoopCC extends CheckedCC {
279 +        NoopCC() { super(); }
280 +        NoopCC(CountedCompleter p) { super(p); }
281 +        NoopCC(CountedCompleter p, int initialPendingCount) {
282 +            super(p, initialPendingCount);
283 +        }
284 +        protected void realCompute() {}
285 +    }
286 +
287      /**
288 <     * A newly constructed CountedCompleter is not completed;
289 <     * complete() causes completion.
288 >     * A newly constructed CountedCompleter is not completed;
289 >     * complete() causes completion. pendingCount is ignored.
290       */
291      public void testComplete() {
292 <        NoopCountedCompleter a = new NoopCountedCompleter();
293 <        assertFalse(a.isDone());
294 <        assertFalse(a.isCompletedNormally());
295 <        assertFalse(a.isCompletedAbnormally());
296 <        assertFalse(a.isCancelled());
297 <        assertNull(a.getException());
298 <        assertNull(a.getRawResult());
299 <        assertFalse(a.post);
300 <        a.complete(null);
301 <        assertTrue(a.post);
302 <        assertTrue(a.isDone());
246 <        assertTrue(a.isCompletedNormally());
247 <        assertFalse(a.isCompletedAbnormally());
248 <        assertFalse(a.isCancelled());
249 <        assertNull(a.getException());
250 <        assertNull(a.getRawResult());
292 >        for (Object x : new Object[] { Boolean.TRUE, null }) {
293 >            for (int pendingCount : new int[] { 0, 42 }) {
294 >                testComplete(new NoopCC(), x, pendingCount);
295 >                testComplete(new NoopCC(new NoopCC()), x, pendingCount);
296 >            }
297 >        }
298 >    }
299 >    void testComplete(NoopCC cc, Object x, int pendingCount) {
300 >        cc.setPendingCount(pendingCount);
301 >        cc.checkCompletes(x);
302 >        assertEquals(pendingCount, cc.getPendingCount());
303      }
304  
305      /**
306       * completeExceptionally completes exceptionally
307       */
308      public void testCompleteExceptionally() {
309 <        NoopCountedCompleter a = new NoopCountedCompleter();
310 <        assertFalse(a.isDone());
311 <        assertFalse(a.isCompletedNormally());
312 <        assertFalse(a.isCompletedAbnormally());
313 <        assertFalse(a.isCancelled());
314 <        assertNull(a.getException());
315 <        assertNull(a.getRawResult());
316 <        assertFalse(a.post);
317 <        a.completeExceptionally(new FJException());
318 <        assertFalse(a.post);
319 <        assertTrue(a.isDone());
320 <        assertFalse(a.isCompletedNormally());
321 <        assertTrue(a.isCompletedAbnormally());
322 <        assertFalse(a.isCancelled());
323 <        assertTrue(a.getException() instanceof FJException);
324 <        assertNull(a.getRawResult());
309 >        new NoopCC()
310 >            .checkCompletesExceptionally(new FJException());
311 >        new NoopCC(new NoopCC())
312 >            .checkCompletesExceptionally(new FJException());
313 >    }
314 >
315 >    /**
316 >     * completeExceptionally(null) surprisingly has the same effect as
317 >     * completeExceptionally(new RuntimeException())
318 >     */
319 >    public void testCompleteExceptionally_null() {
320 >        NoopCC a = new NoopCC();
321 >        a.completeExceptionally(null);
322 >        try {
323 >            a.invoke();
324 >            shouldThrow();
325 >        } catch (RuntimeException success) {
326 >            assertSame(success.getClass(), RuntimeException.class);
327 >            assertNull(success.getCause());
328 >            a.checkCompletedExceptionally(success);
329 >        }
330      }
331  
332      /**
333       * setPendingCount sets the reported pending count
334       */
335      public void testSetPendingCount() {
336 <        NoopCountedCompleter a = new NoopCountedCompleter();
336 >        NoopCC a = new NoopCC();
337          assertEquals(0, a.getPendingCount());
338 <        a.setPendingCount(1);
339 <        assertEquals(1, a.getPendingCount());
340 <        a.setPendingCount(27);
341 <        assertEquals(27, a.getPendingCount());
338 >        int[] vals = {
339 >             -1, 0, 1,
340 >             Integer.MIN_VALUE,
341 >             Integer.MAX_VALUE,
342 >        };
343 >        for (int val : vals) {
344 >            a.setPendingCount(val);
345 >            assertEquals(val, a.getPendingCount());
346 >        }
347      }
348  
349      /**
350       * addToPendingCount adds to the reported pending count
351       */
352      public void testAddToPendingCount() {
353 <        NoopCountedCompleter a = new NoopCountedCompleter();
353 >        NoopCC a = new NoopCC();
354          assertEquals(0, a.getPendingCount());
355          a.addToPendingCount(1);
356          assertEquals(1, a.getPendingCount());
357          a.addToPendingCount(27);
358          assertEquals(28, a.getPendingCount());
359 +        a.addToPendingCount(-28);
360 +        assertEquals(0, a.getPendingCount());
361      }
362  
363      /**
364       * decrementPendingCountUnlessZero decrements reported pending
365       * count unless zero
366       */
367 <    public void testDecrementPendingCount() {
368 <        NoopCountedCompleter a = new NoopCountedCompleter();
369 <        assertEquals(0, a.getPendingCount());
370 <        a.addToPendingCount(1);
367 >    public void testDecrementPendingCountUnlessZero() {
368 >        NoopCC a = new NoopCC(null, 2);
369 >        assertEquals(2, a.getPendingCount());
370 >        assertEquals(2, a.decrementPendingCountUnlessZero());
371          assertEquals(1, a.getPendingCount());
372 <        a.decrementPendingCountUnlessZero();
372 >        assertEquals(1, a.decrementPendingCountUnlessZero());
373          assertEquals(0, a.getPendingCount());
374 <        a.decrementPendingCountUnlessZero();
374 >        assertEquals(0, a.decrementPendingCountUnlessZero());
375          assertEquals(0, a.getPendingCount());
376 +        a.setPendingCount(-1);
377 +        assertEquals(-1, a.decrementPendingCountUnlessZero());
378 +        assertEquals(-2, a.getPendingCount());
379 +    }
380 +
381 +    /**
382 +     * compareAndSetPendingCount compares and sets the reported
383 +     * pending count
384 +     */
385 +    public void testCompareAndSetPendingCount() {
386 +        NoopCC a = new NoopCC();
387 +        assertEquals(0, a.getPendingCount());
388 +        assertTrue(a.compareAndSetPendingCount(0, 1));
389 +        assertEquals(1, a.getPendingCount());
390 +        assertTrue(a.compareAndSetPendingCount(1, 2));
391 +        assertEquals(2, a.getPendingCount());
392 +        assertFalse(a.compareAndSetPendingCount(1, 3));
393 +        assertEquals(2, a.getPendingCount());
394      }
395  
396      /**
397       * getCompleter returns parent or null if at root
398       */
399      public void testGetCompleter() {
400 <        NoopCountedCompleter a = new NoopCountedCompleter();
400 >        NoopCC a = new NoopCC();
401          assertNull(a.getCompleter());
402 <        CountedCompleter b = new NoopCountedCompleter(a);
403 <        assertEquals(a, b.getCompleter());
402 >        CountedCompleter b = new NoopCC(a);
403 >        assertSame(a, b.getCompleter());
404 >        CountedCompleter c = new NoopCC(b);
405 >        assertSame(b, c.getCompleter());
406      }
407 <    
407 >
408      /**
409       * getRoot returns self if no parent, else parent's root
410       */
411      public void testGetRoot() {
412 <        NoopCountedCompleter a = new NoopCountedCompleter();
413 <        NoopCountedCompleter b = new NoopCountedCompleter(a);
414 <        assertEquals(a, a.getRoot());
415 <        assertEquals(a, b.getRoot());
412 >        NoopCC a = new NoopCC();
413 >        NoopCC b = new NoopCC(a);
414 >        NoopCC c = new NoopCC(b);
415 >        assertSame(a, a.getRoot());
416 >        assertSame(a, b.getRoot());
417 >        assertSame(a, c.getRoot());
418      }
419 <              
419 >
420      /**
421 <     * tryComplete causes completion if pending count is zero
421 >     * tryComplete decrements pending count unless zero, in which case
422 >     * causes completion
423       */
424 <    public void testTryComplete1() {
425 <        NoopCountedCompleter a = new NoopCountedCompleter();
424 >    public void testTryComplete() {
425 >        NoopCC a = new NoopCC();
426          assertEquals(0, a.getPendingCount());
427 +        int n = 3;
428 +        a.setPendingCount(n);
429 +        for (; n > 0; n--) {
430 +            assertEquals(n, a.getPendingCount());
431 +            a.tryComplete();
432 +            a.checkIncomplete();
433 +            assertEquals(n - 1, a.getPendingCount());
434 +        }
435          a.tryComplete();
436 <        assertTrue(a.post);
437 <        assertTrue(a.isDone());
436 >        assertEquals(0, a.computeN());
437 >        assertEquals(1, a.onCompletionN());
438 >        assertEquals(0, a.onExceptionalCompletionN());
439 >        assertEquals(0, a.setRawResultN());
440 >        checkCompletedNormally(a);
441      }
442  
443      /**
444 <     * propagateCompletion causes completion without invokein
445 <     * onCompletion if pending count is zero
444 >     * propagateCompletion decrements pending count unless zero, in
445 >     * which case causes completion, without invoking onCompletion
446       */
447      public void testPropagateCompletion() {
448 <        NoopCountedCompleter a = new NoopCountedCompleter();
448 >        NoopCC a = new NoopCC();
449          assertEquals(0, a.getPendingCount());
450 +        int n = 3;
451 +        a.setPendingCount(n);
452 +        for (; n > 0; n--) {
453 +            assertEquals(n, a.getPendingCount());
454 +            a.propagateCompletion();
455 +            a.checkIncomplete();
456 +            assertEquals(n - 1, a.getPendingCount());
457 +        }
458          a.propagateCompletion();
459 <        assertFalse(a.post);
460 <        assertTrue(a.isDone());
461 <    }
462 <
463 <    /**
358 <     * tryComplete decrments pending count unless zero
359 <     */
360 <    public void testTryComplete2() {
361 <        NoopCountedCompleter a = new NoopCountedCompleter();
362 <        assertEquals(0, a.getPendingCount());
363 <        a.setPendingCount(1);
364 <        a.tryComplete();
365 <        assertFalse(a.post);
366 <        assertFalse(a.isDone());
367 <        assertEquals(0, a.getPendingCount());
368 <        a.tryComplete();
369 <        assertTrue(a.post);
370 <        assertTrue(a.isDone());
459 >        assertEquals(0, a.computeN());
460 >        assertEquals(0, a.onCompletionN());
461 >        assertEquals(0, a.onExceptionalCompletionN());
462 >        assertEquals(0, a.setRawResultN());
463 >        checkCompletedNormally(a);
464      }
465  
466      /**
467       * firstComplete returns this if pending count is zero else null
468       */
469      public void testFirstComplete() {
470 <        NoopCountedCompleter a = new NoopCountedCompleter();
470 >        NoopCC a = new NoopCC();
471          a.setPendingCount(1);
472          assertNull(a.firstComplete());
473 <        assertEquals(a, a.firstComplete());
473 >        a.checkIncomplete();
474 >        assertSame(a, a.firstComplete());
475 >        a.checkIncomplete();
476      }
477  
478      /**
# Line 385 | Line 480 | public class CountedCompleterTest extend
480       * zero else null
481       */
482      public void testNextComplete() {
483 <        NoopCountedCompleter a = new NoopCountedCompleter();
484 <        NoopCountedCompleter b = new NoopCountedCompleter(a);
483 >        NoopCC a = new NoopCC();
484 >        NoopCC b = new NoopCC(a);
485          a.setPendingCount(1);
486          b.setPendingCount(1);
487          assertNull(b.firstComplete());
488 <        CountedCompleter c = b.firstComplete();
489 <        assertEquals(b, c);
490 <        CountedCompleter d = c.nextComplete();
491 <        assertNull(d);
492 <        CountedCompleter e = c.nextComplete();
493 <        assertEquals(a, e);
488 >        assertSame(b, b.firstComplete());
489 >        assertNull(b.nextComplete());
490 >        a.checkIncomplete();
491 >        b.checkIncomplete();
492 >        assertSame(a, b.nextComplete());
493 >        assertSame(a, b.nextComplete());
494 >        a.checkIncomplete();
495 >        b.checkIncomplete();
496 >        assertNull(a.nextComplete());
497 >        b.checkIncomplete();
498 >        checkCompletedNormally(a);
499      }
500  
501      /**
502 <     * quietlyCompleteRoot completes root task
502 >     * quietlyCompleteRoot completes root task and only root task
503       */
504      public void testQuietlyCompleteRoot() {
505 <        NoopCountedCompleter a = new NoopCountedCompleter();
506 <        NoopCountedCompleter b = new NoopCountedCompleter(a);
505 >        NoopCC a = new NoopCC();
506 >        NoopCC b = new NoopCC(a);
507 >        NoopCC c = new NoopCC(b);
508          a.setPendingCount(1);
509          b.setPendingCount(1);
510 <        b.quietlyCompleteRoot();
510 >        c.setPendingCount(1);
511 >        c.quietlyCompleteRoot();
512          assertTrue(a.isDone());
513          assertFalse(b.isDone());
514 +        assertFalse(c.isDone());
515      }
516  
517      // Invocation tests use some interdependent task classes
518      // to better test propagation etc
519  
520 <    
521 <    // Version of Fibonacci with different classes for left vs right forks
522 <    static abstract class CCF extends CountedCompleter {
520 >    /**
521 >     * Version of Fibonacci with different classes for left vs right forks
522 >     */
523 >    abstract class CCF extends CheckedCC {
524          int number;
525          int rnumber;
526  
# Line 425 | Line 529 | public class CountedCompleterTest extend
529              this.number = n;
530          }
531  
532 <        public final void compute() {
429 <            CountedCompleter p;
532 >        protected final void realCompute() {
533              CCF f = this;
534              int n = number;
535              while (n >= 2) {
536                  new RCCF(f, n - 2).fork();
537                  f = new LCCF(f, --n);
538              }
539 <            f.number = n;
437 <            f.onCompletion(f);
438 <            if ((p = f.getCompleter()) != null)
439 <                p.tryComplete();
440 <            else
441 <                f.quietlyComplete();
539 >            f.complete(null);
540          }
541      }
542  
543 <    static final class LCCF extends CCF {
543 >    final class LCCF extends CCF {
544 >        public LCCF(int n) { this(null, n); }
545          public LCCF(CountedCompleter parent, int n) {
546              super(parent, n);
547          }
548          public final void onCompletion(CountedCompleter caller) {
549 +            super.onCompletion(caller);
550              CCF p = (CCF)getCompleter();
551              int n = number + rnumber;
552              if (p != null)
# Line 455 | Line 555 | public class CountedCompleterTest extend
555                  number = n;
556          }
557      }
558 <    static final class RCCF extends CCF {
558 >    final class RCCF extends CCF {
559          public RCCF(CountedCompleter parent, int n) {
560              super(parent, n);
561          }
562          public final void onCompletion(CountedCompleter caller) {
563 +            super.onCompletion(caller);
564              CCF p = (CCF)getCompleter();
565              int n = number + rnumber;
566              if (p != null)
# Line 470 | Line 571 | public class CountedCompleterTest extend
571      }
572  
573      // Version of CCF with forced failure in left completions
574 <    static abstract class FailingCCF extends CountedCompleter {
574 >    abstract class FailingCCF extends CheckedCC {
575          int number;
576          int rnumber;
577  
# Line 479 | Line 580 | public class CountedCompleterTest extend
580              this.number = n;
581          }
582  
583 <        public final void compute() {
483 <            CountedCompleter p;
583 >        protected final void realCompute() {
584              FailingCCF f = this;
585              int n = number;
586              while (n >= 2) {
587                  new RFCCF(f, n - 2).fork();
588                  f = new LFCCF(f, --n);
589              }
590 <            f.number = n;
491 <            f.onCompletion(f);
492 <            if ((p = f.getCompleter()) != null)
493 <                p.tryComplete();
494 <            else
495 <                f.quietlyComplete();
590 >            f.complete(null);
591          }
592      }
593  
594 <    static final class LFCCF extends FailingCCF {
594 >    final class LFCCF extends FailingCCF {
595 >        public LFCCF(int n) { this(null, n); }
596          public LFCCF(CountedCompleter parent, int n) {
597              super(parent, n);
598          }
599          public final void onCompletion(CountedCompleter caller) {
600 +            super.onCompletion(caller);
601              FailingCCF p = (FailingCCF)getCompleter();
602              int n = number + rnumber;
603              if (p != null)
# Line 509 | Line 606 | public class CountedCompleterTest extend
606                  number = n;
607          }
608      }
609 <    static final class RFCCF extends FailingCCF {
609 >    final class RFCCF extends FailingCCF {
610          public RFCCF(CountedCompleter parent, int n) {
611              super(parent, n);
612          }
613          public final void onCompletion(CountedCompleter caller) {
614 +            super.onCompletion(caller);
615              completeExceptionally(new FJException());
616          }
617      }
618 <    
618 >
619      /**
620       * invoke returns when task completes normally.
621       * isCompletedAbnormally and isCancelled return false for normally
622       * completed tasks; getRawResult returns null.
623       */
624      public void testInvoke() {
625 <       ForkJoinTask a =  new CheckedFJTask() {
626 <            public void realCompute() {
627 <                CCF f = new LCCF(null, 8);
625 >        ForkJoinTask a = new CheckedRecursiveAction() {
626 >            protected void realCompute() {
627 >                CCF f = new LCCF(8);
628                  assertNull(f.invoke());
629                  assertEquals(21, f.number);
630                  checkCompletedNormally(f);
# Line 540 | Line 638 | public class CountedCompleterTest extend
638       * completed tasks
639       */
640      public void testQuietlyInvoke() {
641 <       ForkJoinTask a =  new CheckedFJTask() {
642 <            public void realCompute() {
643 <                CCF f = new LCCF(null, 8);
641 >        ForkJoinTask a = new CheckedRecursiveAction() {
642 >            protected void realCompute() {
643 >                CCF f = new LCCF(8);
644                  f.quietlyInvoke();
645                  assertEquals(21, f.number);
646                  checkCompletedNormally(f);
# Line 554 | Line 652 | public class CountedCompleterTest extend
652       * join of a forked task returns when task completes
653       */
654      public void testForkJoin() {
655 <       ForkJoinTask a =  new CheckedFJTask() {
656 <            public void realCompute() {
657 <                CCF f = new LCCF(null, 8);
655 >        ForkJoinTask a = new CheckedRecursiveAction() {
656 >            protected void realCompute() {
657 >                CCF f = new LCCF(8);
658                  assertSame(f, f.fork());
659                  assertNull(f.join());
660                  assertEquals(21, f.number);
# Line 569 | Line 667 | public class CountedCompleterTest extend
667       * get of a forked task returns when task completes
668       */
669      public void testForkGet() {
670 <       ForkJoinTask a =  new CheckedFJTask() {
671 <            public void realCompute() throws Exception {
672 <                CCF f = new LCCF(null, 8);
670 >        ForkJoinTask a = new CheckedRecursiveAction() {
671 >            protected void realCompute() throws Exception {
672 >                CCF f = new LCCF(8);
673                  assertSame(f, f.fork());
674                  assertNull(f.get());
675                  assertEquals(21, f.number);
# Line 584 | Line 682 | public class CountedCompleterTest extend
682       * timed get of a forked task returns when task completes
683       */
684      public void testForkTimedGet() {
685 <       ForkJoinTask a =  new CheckedFJTask() {
686 <            public void realCompute() throws Exception {
687 <                CCF f = new LCCF(null, 8);
685 >        ForkJoinTask a = new CheckedRecursiveAction() {
686 >            protected void realCompute() throws Exception {
687 >                CCF f = new LCCF(8);
688                  assertSame(f, f.fork());
689                  assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
690                  assertEquals(21, f.number);
# Line 599 | Line 697 | public class CountedCompleterTest extend
697       * timed get with null time unit throws NPE
698       */
699      public void testForkTimedGetNPE() {
700 <       ForkJoinTask a =  new CheckedFJTask() {
701 <            public void realCompute() throws Exception {
702 <                CCF f = new LCCF(null, 8);
700 >        ForkJoinTask a = new CheckedRecursiveAction() {
701 >            protected void realCompute() throws Exception {
702 >                CCF f = new LCCF(8);
703                  assertSame(f, f.fork());
704                  try {
705                      f.get(5L, null);
# Line 615 | Line 713 | public class CountedCompleterTest extend
713       * quietlyJoin of a forked task returns when task completes
714       */
715      public void testForkQuietlyJoin() {
716 <       ForkJoinTask a =  new CheckedFJTask() {
717 <            public void realCompute() {
718 <                CCF f = new LCCF(null, 8);
716 >        ForkJoinTask a = new CheckedRecursiveAction() {
717 >            protected void realCompute() {
718 >                CCF f = new LCCF(8);
719                  assertSame(f, f.fork());
720                  f.quietlyJoin();
721                  assertEquals(21, f.number);
# Line 631 | Line 729 | public class CountedCompleterTest extend
729       * getQueuedTaskCount returns 0 when quiescent
730       */
731      public void testForkHelpQuiesce() {
732 <       ForkJoinTask a =  new CheckedFJTask() {
733 <            public void realCompute() {
734 <                CCF f = new LCCF(null, 8);
732 >        ForkJoinTask a = new CheckedRecursiveAction() {
733 >            protected void realCompute() {
734 >                CCF f = new LCCF(8);
735                  assertSame(f, f.fork());
736                  helpQuiesce();
737                  assertEquals(21, f.number);
# Line 647 | Line 745 | public class CountedCompleterTest extend
745       * invoke task throws exception when task completes abnormally
746       */
747      public void testAbnormalInvoke() {
748 <       ForkJoinTask a =  new CheckedFJTask() {
749 <            public void realCompute() {
750 <                FailingCCF f = new LFCCF(null, 8);
748 >        ForkJoinTask a = new CheckedRecursiveAction() {
749 >            protected void realCompute() {
750 >                FailingCCF f = new LFCCF(8);
751                  try {
752                      f.invoke();
753                      shouldThrow();
# Line 664 | Line 762 | public class CountedCompleterTest extend
762       * quietlyInvoke task returns when task completes abnormally
763       */
764      public void testAbnormalQuietlyInvoke() {
765 <       ForkJoinTask a =  new CheckedFJTask() {
766 <            public void realCompute() {
767 <                FailingCCF f = new LFCCF(null, 8);
765 >        ForkJoinTask a = new CheckedRecursiveAction() {
766 >            protected void realCompute() {
767 >                FailingCCF f = new LFCCF(8);
768                  f.quietlyInvoke();
769                  assertTrue(f.getException() instanceof FJException);
770                  checkCompletedAbnormally(f, f.getException());
# Line 678 | Line 776 | public class CountedCompleterTest extend
776       * join of a forked task throws exception when task completes abnormally
777       */
778      public void testAbnormalForkJoin() {
779 <       ForkJoinTask a =  new CheckedFJTask() {
780 <            public void realCompute() {
781 <                FailingCCF f = new LFCCF(null, 8);
779 >        ForkJoinTask a = new CheckedRecursiveAction() {
780 >            protected void realCompute() {
781 >                FailingCCF f = new LFCCF(8);
782                  assertSame(f, f.fork());
783                  try {
784                      f.join();
# Line 696 | Line 794 | public class CountedCompleterTest extend
794       * get of a forked task throws exception when task completes abnormally
795       */
796      public void testAbnormalForkGet() {
797 <       ForkJoinTask a =  new CheckedFJTask() {
798 <            public void realCompute() throws Exception {
799 <                FailingCCF f = new LFCCF(null, 8);
797 >        ForkJoinTask a = new CheckedRecursiveAction() {
798 >            protected void realCompute() throws Exception {
799 >                FailingCCF f = new LFCCF(8);
800                  assertSame(f, f.fork());
801                  try {
802                      f.get();
# Line 716 | Line 814 | public class CountedCompleterTest extend
814       * timed get of a forked task throws exception when task completes abnormally
815       */
816      public void testAbnormalForkTimedGet() {
817 <       ForkJoinTask a =  new CheckedFJTask() {
818 <            public void realCompute() throws Exception {
819 <                FailingCCF f = new LFCCF(null, 8);
817 >        ForkJoinTask a = new CheckedRecursiveAction() {
818 >            protected void realCompute() throws Exception {
819 >                FailingCCF f = new LFCCF(8);
820                  assertSame(f, f.fork());
821                  try {
822                      f.get(LONG_DELAY_MS, MILLISECONDS);
# Line 736 | Line 834 | public class CountedCompleterTest extend
834       * quietlyJoin of a forked task returns when task completes abnormally
835       */
836      public void testAbnormalForkQuietlyJoin() {
837 <       ForkJoinTask a =  new CheckedFJTask() {
838 <            public void realCompute() {
839 <                FailingCCF f = new LFCCF(null, 8);
837 >        ForkJoinTask a = new CheckedRecursiveAction() {
838 >            protected void realCompute() {
839 >                FailingCCF f = new LFCCF(8);
840                  assertSame(f, f.fork());
841                  f.quietlyJoin();
842                  assertTrue(f.getException() instanceof FJException);
# Line 751 | Line 849 | public class CountedCompleterTest extend
849       * invoke task throws exception when task cancelled
850       */
851      public void testCancelledInvoke() {
852 <       ForkJoinTask a =  new CheckedFJTask() {
853 <            public void realCompute() {
854 <                CCF f = new LCCF(null, 8);
852 >        ForkJoinTask a = new CheckedRecursiveAction() {
853 >            protected void realCompute() {
854 >                CCF f = new LCCF(8);
855                  assertTrue(f.cancel(true));
856                  try {
857                      f.invoke();
# Line 769 | Line 867 | public class CountedCompleterTest extend
867       * join of a forked task throws exception when task cancelled
868       */
869      public void testCancelledForkJoin() {
870 <       ForkJoinTask a =  new CheckedFJTask() {
871 <            public void realCompute() {
872 <                CCF f = new LCCF(null, 8);
870 >        ForkJoinTask a = new CheckedRecursiveAction() {
871 >            protected void realCompute() {
872 >                CCF f = new LCCF(8);
873                  assertTrue(f.cancel(true));
874                  assertSame(f, f.fork());
875                  try {
# Line 788 | Line 886 | public class CountedCompleterTest extend
886       * get of a forked task throws exception when task cancelled
887       */
888      public void testCancelledForkGet() {
889 <       ForkJoinTask a =  new CheckedFJTask() {
890 <            public void realCompute() throws Exception {
891 <                CCF f = new LCCF(null, 8);
889 >        ForkJoinTask a = new CheckedRecursiveAction() {
890 >            protected void realCompute() throws Exception {
891 >                CCF f = new LCCF(8);
892                  assertTrue(f.cancel(true));
893                  assertSame(f, f.fork());
894                  try {
# Line 807 | Line 905 | public class CountedCompleterTest extend
905       * timed get of a forked task throws exception when task cancelled
906       */
907      public void testCancelledForkTimedGet() throws Exception {
908 <       ForkJoinTask a =  new CheckedFJTask() {
909 <            public void realCompute() throws Exception {
910 <                CCF f = new LCCF(null, 8);
908 >        ForkJoinTask a = new CheckedRecursiveAction() {
909 >            protected void realCompute() throws Exception {
910 >                CCF f = new LCCF(8);
911                  assertTrue(f.cancel(true));
912                  assertSame(f, f.fork());
913                  try {
# Line 826 | Line 924 | public class CountedCompleterTest extend
924       * quietlyJoin of a forked task returns when task cancelled
925       */
926      public void testCancelledForkQuietlyJoin() {
927 <       ForkJoinTask a =  new CheckedFJTask() {
928 <            public void realCompute() {
929 <                CCF f = new LCCF(null, 8);
927 >        ForkJoinTask a = new CheckedRecursiveAction() {
928 >            protected void realCompute() {
929 >                CCF f = new LCCF(8);
930                  assertTrue(f.cancel(true));
931                  assertSame(f, f.fork());
932                  f.quietlyJoin();
# Line 842 | Line 940 | public class CountedCompleterTest extend
940       */
941      public void testGetPool() {
942          final ForkJoinPool mainPool = mainPool();
943 <       ForkJoinTask a =  new CheckedFJTask() {
944 <            public void realCompute() {
943 >        ForkJoinTask a = new CheckedRecursiveAction() {
944 >            protected void realCompute() {
945                  assertSame(mainPool, getPool());
946              }};
947          testInvokeOnPool(mainPool, a);
# Line 853 | Line 951 | public class CountedCompleterTest extend
951       * getPool of non-FJ task returns null
952       */
953      public void testGetPool2() {
954 <       ForkJoinTask a =  new CheckedFJTask() {
955 <            public void realCompute() {
954 >        ForkJoinTask a = new CheckedRecursiveAction() {
955 >            protected void realCompute() {
956                  assertNull(getPool());
957              }};
958          assertNull(a.invoke());
# Line 864 | Line 962 | public class CountedCompleterTest extend
962       * inForkJoinPool of executing task returns true
963       */
964      public void testInForkJoinPool() {
965 <       ForkJoinTask a =  new CheckedFJTask() {
966 <            public void realCompute() {
965 >        ForkJoinTask a = new CheckedRecursiveAction() {
966 >            protected void realCompute() {
967                  assertTrue(inForkJoinPool());
968              }};
969          testInvokeOnPool(mainPool(), a);
# Line 875 | Line 973 | public class CountedCompleterTest extend
973       * inForkJoinPool of non-FJ task returns false
974       */
975      public void testInForkJoinPool2() {
976 <       ForkJoinTask a =  new CheckedFJTask() {
977 <            public void realCompute() {
976 >        ForkJoinTask a = new CheckedRecursiveAction() {
977 >            protected void realCompute() {
978                  assertFalse(inForkJoinPool());
979              }};
980          assertNull(a.invoke());
# Line 886 | Line 984 | public class CountedCompleterTest extend
984       * setRawResult(null) succeeds
985       */
986      public void testSetRawResult() {
987 <       ForkJoinTask a =  new CheckedFJTask() {
988 <            public void realCompute() {
987 >        ForkJoinTask a = new CheckedRecursiveAction() {
988 >            protected void realCompute() {
989                  setRawResult(null);
990                  assertNull(getRawResult());
991              }};
# Line 898 | Line 996 | public class CountedCompleterTest extend
996       * invoke task throws exception after invoking completeExceptionally
997       */
998      public void testCompleteExceptionally2() {
999 <       ForkJoinTask a =  new CheckedFJTask() {
1000 <            public void realCompute() {
1001 <                CCF f = new LCCF(null, 8);
1002 <                f.completeExceptionally(new FJException());
1003 <                try {
1004 <                    f.invoke();
1005 <                    shouldThrow();
1006 <                } catch (FJException success) {
909 <                    checkCompletedAbnormally(f, success);
910 <                }
999 >        ForkJoinTask a = new CheckedRecursiveAction() {
1000 >            protected void realCompute() {
1001 >                CCF n = new LCCF(8);
1002 >                CCF f = new LCCF(n, 8);
1003 >                FJException ex = new FJException();
1004 >                f.completeExceptionally(ex);
1005 >                f.checkCompletedExceptionally(ex);
1006 >                n.checkCompletedExceptionally(ex);
1007              }};
1008          testInvokeOnPool(mainPool(), a);
1009      }
# Line 916 | Line 1012 | public class CountedCompleterTest extend
1012       * invokeAll(t1, t2) invokes all task arguments
1013       */
1014      public void testInvokeAll2() {
1015 <       ForkJoinTask a =  new CheckedFJTask() {
1016 <            public void realCompute() {
1017 <                CCF f = new LCCF(null, 8);
1018 <                CCF g = new LCCF(null, 9);
1015 >        ForkJoinTask a = new CheckedRecursiveAction() {
1016 >            protected void realCompute() {
1017 >                CCF f = new LCCF(8);
1018 >                CCF g = new LCCF(9);
1019                  invokeAll(f, g);
1020                  assertEquals(21, f.number);
1021                  assertEquals(34, g.number);
# Line 933 | Line 1029 | public class CountedCompleterTest extend
1029       * invokeAll(tasks) with 1 argument invokes task
1030       */
1031      public void testInvokeAll1() {
1032 <       ForkJoinTask a =  new CheckedFJTask() {
1033 <            public void realCompute() {
1034 <                CCF f = new LCCF(null, 8);
1032 >        ForkJoinTask a = new CheckedRecursiveAction() {
1033 >            protected void realCompute() {
1034 >                CCF f = new LCCF(8);
1035                  invokeAll(f);
1036                  checkCompletedNormally(f);
1037                  assertEquals(21, f.number);
# Line 947 | Line 1043 | public class CountedCompleterTest extend
1043       * invokeAll(tasks) with > 2 argument invokes tasks
1044       */
1045      public void testInvokeAll3() {
1046 <       ForkJoinTask a =  new CheckedFJTask() {
1047 <            public void realCompute() {
1048 <                CCF f = new LCCF(null, 8);
1049 <                CCF g = new LCCF(null, 9);
1050 <                CCF h = new LCCF(null, 7);
1046 >        ForkJoinTask a = new CheckedRecursiveAction() {
1047 >            protected void realCompute() {
1048 >                CCF f = new LCCF(8);
1049 >                CCF g = new LCCF(9);
1050 >                CCF h = new LCCF(7);
1051                  invokeAll(f, g, h);
1052                  assertEquals(21, f.number);
1053                  assertEquals(34, g.number);
# Line 967 | Line 1063 | public class CountedCompleterTest extend
1063       * invokeAll(collection) invokes all tasks in the collection
1064       */
1065      public void testInvokeAllCollection() {
1066 <       ForkJoinTask a =  new CheckedFJTask() {
1067 <            public void realCompute() {
1068 <                CCF f = new LCCF(null, 8);
1069 <                CCF g = new LCCF(null, 9);
1070 <                CCF h = new LCCF(null, 7);
1066 >        ForkJoinTask a = new CheckedRecursiveAction() {
1067 >            protected void realCompute() {
1068 >                CCF f = new LCCF(8);
1069 >                CCF g = new LCCF(9);
1070 >                CCF h = new LCCF(7);
1071                  HashSet set = new HashSet();
1072                  set.add(f);
1073                  set.add(g);
# Line 991 | Line 1087 | public class CountedCompleterTest extend
1087       * invokeAll(tasks) with any null task throws NPE
1088       */
1089      public void testInvokeAllNPE() {
1090 <       ForkJoinTask a =  new CheckedFJTask() {
1091 <            public void realCompute() {
1092 <                CCF f = new LCCF(null, 8);
1093 <                CCF g = new LCCF(null, 9);
1090 >        ForkJoinTask a = new CheckedRecursiveAction() {
1091 >            protected void realCompute() {
1092 >                CCF f = new LCCF(8);
1093 >                CCF g = new LCCF(9);
1094                  CCF h = null;
1095                  try {
1096                      invokeAll(f, g, h);
# Line 1008 | Line 1104 | public class CountedCompleterTest extend
1104       * invokeAll(t1, t2) throw exception if any task does
1105       */
1106      public void testAbnormalInvokeAll2() {
1107 <       ForkJoinTask a =  new CheckedFJTask() {
1108 <            public void realCompute() {
1109 <                CCF f = new LCCF(null, 8);
1110 <                FailingCCF g = new LFCCF(null, 9);
1107 >        ForkJoinTask a = new CheckedRecursiveAction() {
1108 >            protected void realCompute() {
1109 >                CCF f = new LCCF(8);
1110 >                FailingCCF g = new LFCCF(9);
1111                  try {
1112                      invokeAll(f, g);
1113                      shouldThrow();
# Line 1026 | Line 1122 | public class CountedCompleterTest extend
1122       * invokeAll(tasks) with 1 argument throws exception if task does
1123       */
1124      public void testAbnormalInvokeAll1() {
1125 <       ForkJoinTask a =  new CheckedFJTask() {
1126 <            public void realCompute() {
1127 <                FailingCCF g = new LFCCF(null, 9);
1125 >        ForkJoinTask a = new CheckedRecursiveAction() {
1126 >            protected void realCompute() {
1127 >                FailingCCF g = new LFCCF(9);
1128                  try {
1129                      invokeAll(g);
1130                      shouldThrow();
# Line 1043 | Line 1139 | public class CountedCompleterTest extend
1139       * invokeAll(tasks) with > 2 argument throws exception if any task does
1140       */
1141      public void testAbnormalInvokeAll3() {
1142 <       ForkJoinTask a =  new CheckedFJTask() {
1143 <            public void realCompute() {
1144 <                CCF f = new LCCF(null, 8);
1145 <                FailingCCF g = new LFCCF(null, 9);
1146 <                CCF h = new LCCF(null, 7);
1142 >        ForkJoinTask a = new CheckedRecursiveAction() {
1143 >            protected void realCompute() {
1144 >                CCF f = new LCCF(8);
1145 >                FailingCCF g = new LFCCF(9);
1146 >                CCF h = new LCCF(7);
1147                  try {
1148                      invokeAll(f, g, h);
1149                      shouldThrow();
# Line 1059 | Line 1155 | public class CountedCompleterTest extend
1155      }
1156  
1157      /**
1158 <     * invokeAll(collection)  throws exception if any task does
1158 >     * invokeAll(collection) throws exception if any task does
1159       */
1160      public void testAbnormalInvokeAllCollection() {
1161 <       ForkJoinTask a =  new CheckedFJTask() {
1162 <            public void realCompute() {
1163 <                FailingCCF f = new LFCCF(null, 8);
1164 <                CCF g = new LCCF(null, 9);
1165 <                CCF h = new LCCF(null, 7);
1161 >        ForkJoinTask a = new CheckedRecursiveAction() {
1162 >            protected void realCompute() {
1163 >                FailingCCF f = new LFCCF(8);
1164 >                CCF g = new LCCF(9);
1165 >                CCF h = new LCCF(7);
1166                  HashSet set = new HashSet();
1167                  set.add(f);
1168                  set.add(g);
# Line 1086 | Line 1182 | public class CountedCompleterTest extend
1182       * and suppresses execution
1183       */
1184      public void testTryUnfork() {
1185 <       ForkJoinTask a =  new CheckedFJTask() {
1186 <            public void realCompute() {
1187 <                CCF g = new LCCF(null, 9);
1185 >        ForkJoinTask a = new CheckedRecursiveAction() {
1186 >            protected void realCompute() {
1187 >                CCF g = new LCCF(9);
1188                  assertSame(g, g.fork());
1189 <                CCF f = new LCCF(null, 8);
1189 >                CCF f = new LCCF(8);
1190                  assertSame(f, f.fork());
1191                  assertTrue(f.tryUnfork());
1192                  helpQuiesce();
# Line 1105 | Line 1201 | public class CountedCompleterTest extend
1201       * there are more tasks than threads
1202       */
1203      public void testGetSurplusQueuedTaskCount() {
1204 <       ForkJoinTask a =  new CheckedFJTask() {
1205 <            public void realCompute() {
1206 <                CCF h = new LCCF(null, 7);
1204 >        ForkJoinTask a = new CheckedRecursiveAction() {
1205 >            protected void realCompute() {
1206 >                CCF h = new LCCF(7);
1207                  assertSame(h, h.fork());
1208 <                CCF g = new LCCF(null, 9);
1208 >                CCF g = new LCCF(9);
1209                  assertSame(g, g.fork());
1210 <                CCF f = new LCCF(null, 8);
1210 >                CCF f = new LCCF(8);
1211                  assertSame(f, f.fork());
1212                  assertTrue(getSurplusQueuedTaskCount() > 0);
1213                  helpQuiesce();
# Line 1127 | Line 1223 | public class CountedCompleterTest extend
1223       * peekNextLocalTask returns most recent unexecuted task.
1224       */
1225      public void testPeekNextLocalTask() {
1226 <       ForkJoinTask a =  new CheckedFJTask() {
1227 <            public void realCompute() {
1228 <                CCF g = new LCCF(null, 9);
1226 >        ForkJoinTask a = new CheckedRecursiveAction() {
1227 >            protected void realCompute() {
1228 >                CCF g = new LCCF(9);
1229                  assertSame(g, g.fork());
1230 <                CCF f = new LCCF(null, 8);
1230 >                CCF f = new LCCF(8);
1231                  assertSame(f, f.fork());
1232                  assertSame(f, peekNextLocalTask());
1233                  assertNull(f.join());
# Line 1147 | Line 1243 | public class CountedCompleterTest extend
1243       * executing it
1244       */
1245      public void testPollNextLocalTask() {
1246 <       ForkJoinTask a =  new CheckedFJTask() {
1247 <            public void realCompute() {
1248 <                CCF g = new LCCF(null, 9);
1246 >        ForkJoinTask a = new CheckedRecursiveAction() {
1247 >            protected void realCompute() {
1248 >                CCF g = new LCCF(9);
1249                  assertSame(g, g.fork());
1250 <                CCF f = new LCCF(null, 8);
1250 >                CCF f = new LCCF(8);
1251                  assertSame(f, f.fork());
1252                  assertSame(f, pollNextLocalTask());
1253                  helpQuiesce();
# Line 1166 | Line 1262 | public class CountedCompleterTest extend
1262       * pollTask returns an unexecuted task without executing it
1263       */
1264      public void testPollTask() {
1265 <       ForkJoinTask a =  new CheckedFJTask() {
1266 <            public void realCompute() {
1267 <                CCF g = new LCCF(null, 9);
1265 >        ForkJoinTask a = new CheckedRecursiveAction() {
1266 >            protected void realCompute() {
1267 >                CCF g = new LCCF(9);
1268                  assertSame(g, g.fork());
1269 <                CCF f = new LCCF(null, 8);
1269 >                CCF f = new LCCF(8);
1270                  assertSame(f, f.fork());
1271                  assertSame(f, pollTask());
1272                  helpQuiesce();
# Line 1184 | Line 1280 | public class CountedCompleterTest extend
1280       * peekNextLocalTask returns least recent unexecuted task in async mode
1281       */
1282      public void testPeekNextLocalTaskAsync() {
1283 <       ForkJoinTask a =  new CheckedFJTask() {
1284 <            public void realCompute() {
1285 <                CCF g = new LCCF(null, 9);
1283 >        ForkJoinTask a = new CheckedRecursiveAction() {
1284 >            protected void realCompute() {
1285 >                CCF g = new LCCF(9);
1286                  assertSame(g, g.fork());
1287 <                CCF f = new LCCF(null, 8);
1287 >                CCF f = new LCCF(8);
1288                  assertSame(f, f.fork());
1289                  assertSame(g, peekNextLocalTask());
1290                  assertNull(f.join());
# Line 1205 | Line 1301 | public class CountedCompleterTest extend
1301       * executing it, in async mode
1302       */
1303      public void testPollNextLocalTaskAsync() {
1304 <       ForkJoinTask a =  new CheckedFJTask() {
1305 <            public void realCompute() {
1306 <                CCF g = new LCCF(null, 9);
1304 >        ForkJoinTask a = new CheckedRecursiveAction() {
1305 >            protected void realCompute() {
1306 >                CCF g = new LCCF(9);
1307                  assertSame(g, g.fork());
1308 <                CCF f = new LCCF(null, 8);
1308 >                CCF f = new LCCF(8);
1309                  assertSame(f, f.fork());
1310                  assertSame(g, pollNextLocalTask());
1311                  helpQuiesce();
# Line 1225 | Line 1321 | public class CountedCompleterTest extend
1321       * async mode
1322       */
1323      public void testPollTaskAsync() {
1324 <       ForkJoinTask a =  new CheckedFJTask() {
1325 <            public void realCompute() {
1326 <                CCF g = new LCCF(null, 9);
1324 >        ForkJoinTask a = new CheckedRecursiveAction() {
1325 >            protected void realCompute() {
1326 >                CCF g = new LCCF(9);
1327                  assertSame(g, g.fork());
1328 <                CCF f = new LCCF(null, 8);
1328 >                CCF f = new LCCF(8);
1329                  assertSame(f, f.fork());
1330                  assertSame(g, pollTask());
1331                  helpQuiesce();
# Line 1248 | Line 1344 | public class CountedCompleterTest extend
1344       * completed tasks; getRawResult returns null.
1345       */
1346      public void testInvokeSingleton() {
1347 <       ForkJoinTask a =  new CheckedFJTask() {
1348 <            public void realCompute() {
1349 <                CCF f = new LCCF(null, 8);
1347 >        ForkJoinTask a = new CheckedRecursiveAction() {
1348 >            protected void realCompute() {
1349 >                CCF f = new LCCF(8);
1350                  assertNull(f.invoke());
1351                  assertEquals(21, f.number);
1352                  checkCompletedNormally(f);
# Line 1264 | Line 1360 | public class CountedCompleterTest extend
1360       * completed tasks
1361       */
1362      public void testQuietlyInvokeSingleton() {
1363 <       ForkJoinTask a =  new CheckedFJTask() {
1364 <            public void realCompute() {
1365 <                CCF f = new LCCF(null, 8);
1363 >        ForkJoinTask a = new CheckedRecursiveAction() {
1364 >            protected void realCompute() {
1365 >                CCF f = new LCCF(8);
1366                  f.quietlyInvoke();
1367                  assertEquals(21, f.number);
1368                  checkCompletedNormally(f);
# Line 1278 | Line 1374 | public class CountedCompleterTest extend
1374       * join of a forked task returns when task completes
1375       */
1376      public void testForkJoinSingleton() {
1377 <       ForkJoinTask a =  new CheckedFJTask() {
1378 <            public void realCompute() {
1379 <                CCF f = new LCCF(null, 8);
1377 >        ForkJoinTask a = new CheckedRecursiveAction() {
1378 >            protected void realCompute() {
1379 >                CCF f = new LCCF(8);
1380                  assertSame(f, f.fork());
1381                  assertNull(f.join());
1382                  assertEquals(21, f.number);
# Line 1293 | Line 1389 | public class CountedCompleterTest extend
1389       * get of a forked task returns when task completes
1390       */
1391      public void testForkGetSingleton() {
1392 <       ForkJoinTask a =  new CheckedFJTask() {
1393 <            public void realCompute() throws Exception {
1394 <                CCF f = new LCCF(null, 8);
1392 >        ForkJoinTask a = new CheckedRecursiveAction() {
1393 >            protected void realCompute() throws Exception {
1394 >                CCF f = new LCCF(8);
1395                  assertSame(f, f.fork());
1396                  assertNull(f.get());
1397                  assertEquals(21, f.number);
# Line 1308 | Line 1404 | public class CountedCompleterTest extend
1404       * timed get of a forked task returns when task completes
1405       */
1406      public void testForkTimedGetSingleton() {
1407 <       ForkJoinTask a =  new CheckedFJTask() {
1408 <            public void realCompute() throws Exception {
1409 <                CCF f = new LCCF(null, 8);
1407 >        ForkJoinTask a = new CheckedRecursiveAction() {
1408 >            protected void realCompute() throws Exception {
1409 >                CCF f = new LCCF(8);
1410                  assertSame(f, f.fork());
1411                  assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
1412                  assertEquals(21, f.number);
# Line 1323 | Line 1419 | public class CountedCompleterTest extend
1419       * timed get with null time unit throws NPE
1420       */
1421      public void testForkTimedGetNPESingleton() {
1422 <       ForkJoinTask a =  new CheckedFJTask() {
1423 <            public void realCompute() throws Exception {
1424 <                CCF f = new LCCF(null, 8);
1422 >        ForkJoinTask a = new CheckedRecursiveAction() {
1423 >            protected void realCompute() throws Exception {
1424 >                CCF f = new LCCF(8);
1425                  assertSame(f, f.fork());
1426                  try {
1427                      f.get(5L, null);
# Line 1339 | Line 1435 | public class CountedCompleterTest extend
1435       * quietlyJoin of a forked task returns when task completes
1436       */
1437      public void testForkQuietlyJoinSingleton() {
1438 <       ForkJoinTask a =  new CheckedFJTask() {
1439 <            public void realCompute() {
1440 <                CCF f = new LCCF(null, 8);
1438 >        ForkJoinTask a = new CheckedRecursiveAction() {
1439 >            protected void realCompute() {
1440 >                CCF f = new LCCF(8);
1441                  assertSame(f, f.fork());
1442                  f.quietlyJoin();
1443                  assertEquals(21, f.number);
# Line 1355 | Line 1451 | public class CountedCompleterTest extend
1451       * getQueuedTaskCount returns 0 when quiescent
1452       */
1453      public void testForkHelpQuiesceSingleton() {
1454 <       ForkJoinTask a =  new CheckedFJTask() {
1455 <            public void realCompute() {
1456 <                CCF f = new LCCF(null, 8);
1454 >        ForkJoinTask a = new CheckedRecursiveAction() {
1455 >            protected void realCompute() {
1456 >                CCF f = new LCCF(8);
1457                  assertSame(f, f.fork());
1458                  helpQuiesce();
1459                  assertEquals(0, getQueuedTaskCount());
# Line 1371 | Line 1467 | public class CountedCompleterTest extend
1467       * invoke task throws exception when task completes abnormally
1468       */
1469      public void testAbnormalInvokeSingleton() {
1470 <       ForkJoinTask a =  new CheckedFJTask() {
1471 <            public void realCompute() {
1472 <                FailingCCF f = new LFCCF(null, 8);
1470 >        ForkJoinTask a = new CheckedRecursiveAction() {
1471 >            protected void realCompute() {
1472 >                FailingCCF f = new LFCCF(8);
1473                  try {
1474                      f.invoke();
1475                      shouldThrow();
# Line 1388 | Line 1484 | public class CountedCompleterTest extend
1484       * quietlyInvoke task returns when task completes abnormally
1485       */
1486      public void testAbnormalQuietlyInvokeSingleton() {
1487 <       ForkJoinTask a =  new CheckedFJTask() {
1488 <            public void realCompute() {
1489 <                FailingCCF f = new LFCCF(null, 8);
1487 >        ForkJoinTask a = new CheckedRecursiveAction() {
1488 >            protected void realCompute() {
1489 >                FailingCCF f = new LFCCF(8);
1490                  f.quietlyInvoke();
1491                  assertTrue(f.getException() instanceof FJException);
1492                  checkCompletedAbnormally(f, f.getException());
# Line 1402 | Line 1498 | public class CountedCompleterTest extend
1498       * join of a forked task throws exception when task completes abnormally
1499       */
1500      public void testAbnormalForkJoinSingleton() {
1501 <       ForkJoinTask a =  new CheckedFJTask() {
1502 <            public void realCompute() {
1503 <                FailingCCF f = new LFCCF(null, 8);
1501 >        ForkJoinTask a = new CheckedRecursiveAction() {
1502 >            protected void realCompute() {
1503 >                FailingCCF f = new LFCCF(8);
1504                  assertSame(f, f.fork());
1505                  try {
1506                      f.join();
# Line 1420 | Line 1516 | public class CountedCompleterTest extend
1516       * get of a forked task throws exception when task completes abnormally
1517       */
1518      public void testAbnormalForkGetSingleton() {
1519 <       ForkJoinTask a =  new CheckedFJTask() {
1520 <            public void realCompute() throws Exception {
1521 <                FailingCCF f = new LFCCF(null, 8);
1519 >        ForkJoinTask a = new CheckedRecursiveAction() {
1520 >            protected void realCompute() throws Exception {
1521 >                FailingCCF f = new LFCCF(8);
1522                  assertSame(f, f.fork());
1523                  try {
1524                      f.get();
# Line 1440 | Line 1536 | public class CountedCompleterTest extend
1536       * timed get of a forked task throws exception when task completes abnormally
1537       */
1538      public void testAbnormalForkTimedGetSingleton() {
1539 <       ForkJoinTask a =  new CheckedFJTask() {
1540 <            public void realCompute() throws Exception {
1541 <                FailingCCF f = new LFCCF(null, 8);
1539 >        ForkJoinTask a = new CheckedRecursiveAction() {
1540 >            protected void realCompute() throws Exception {
1541 >                FailingCCF f = new LFCCF(8);
1542                  assertSame(f, f.fork());
1543                  try {
1544                      f.get(LONG_DELAY_MS, MILLISECONDS);
# Line 1460 | Line 1556 | public class CountedCompleterTest extend
1556       * quietlyJoin of a forked task returns when task completes abnormally
1557       */
1558      public void testAbnormalForkQuietlyJoinSingleton() {
1559 <       ForkJoinTask a =  new CheckedFJTask() {
1560 <            public void realCompute() {
1561 <                FailingCCF f = new LFCCF(null, 8);
1559 >        ForkJoinTask a = new CheckedRecursiveAction() {
1560 >            protected void realCompute() {
1561 >                FailingCCF f = new LFCCF(8);
1562                  assertSame(f, f.fork());
1563                  f.quietlyJoin();
1564                  assertTrue(f.getException() instanceof FJException);
# Line 1475 | Line 1571 | public class CountedCompleterTest extend
1571       * invoke task throws exception when task cancelled
1572       */
1573      public void testCancelledInvokeSingleton() {
1574 <       ForkJoinTask a =  new CheckedFJTask() {
1575 <            public void realCompute() {
1576 <                CCF f = new LCCF(null, 8);
1574 >        ForkJoinTask a = new CheckedRecursiveAction() {
1575 >            protected void realCompute() {
1576 >                CCF f = new LCCF(8);
1577                  assertTrue(f.cancel(true));
1578                  try {
1579                      f.invoke();
# Line 1493 | Line 1589 | public class CountedCompleterTest extend
1589       * join of a forked task throws exception when task cancelled
1590       */
1591      public void testCancelledForkJoinSingleton() {
1592 <       ForkJoinTask a =  new CheckedFJTask() {
1593 <            public void realCompute() {
1594 <                CCF f = new LCCF(null, 8);
1592 >        ForkJoinTask a = new CheckedRecursiveAction() {
1593 >            protected void realCompute() {
1594 >                CCF f = new LCCF(8);
1595                  assertTrue(f.cancel(true));
1596                  assertSame(f, f.fork());
1597                  try {
# Line 1512 | Line 1608 | public class CountedCompleterTest extend
1608       * get of a forked task throws exception when task cancelled
1609       */
1610      public void testCancelledForkGetSingleton() {
1611 <       ForkJoinTask a =  new CheckedFJTask() {
1612 <            public void realCompute() throws Exception {
1613 <                CCF f = new LCCF(null, 8);
1611 >        ForkJoinTask a = new CheckedRecursiveAction() {
1612 >            protected void realCompute() throws Exception {
1613 >                CCF f = new LCCF(8);
1614                  assertTrue(f.cancel(true));
1615                  assertSame(f, f.fork());
1616                  try {
# Line 1531 | Line 1627 | public class CountedCompleterTest extend
1627       * timed get of a forked task throws exception when task cancelled
1628       */
1629      public void testCancelledForkTimedGetSingleton() throws Exception {
1630 <       ForkJoinTask a =  new CheckedFJTask() {
1631 <            public void realCompute() throws Exception {
1632 <                CCF f = new LCCF(null, 8);
1630 >        ForkJoinTask a = new CheckedRecursiveAction() {
1631 >            protected void realCompute() throws Exception {
1632 >                CCF f = new LCCF(8);
1633                  assertTrue(f.cancel(true));
1634                  assertSame(f, f.fork());
1635                  try {
# Line 1550 | Line 1646 | public class CountedCompleterTest extend
1646       * quietlyJoin of a forked task returns when task cancelled
1647       */
1648      public void testCancelledForkQuietlyJoinSingleton() {
1649 <       ForkJoinTask a =  new CheckedFJTask() {
1650 <            public void realCompute() {
1651 <                CCF f = new LCCF(null, 8);
1649 >        ForkJoinTask a = new CheckedRecursiveAction() {
1650 >            protected void realCompute() {
1651 >                CCF f = new LCCF(8);
1652                  assertTrue(f.cancel(true));
1653                  assertSame(f, f.fork());
1654                  f.quietlyJoin();
# Line 1565 | Line 1661 | public class CountedCompleterTest extend
1661       * invoke task throws exception after invoking completeExceptionally
1662       */
1663      public void testCompleteExceptionallySingleton() {
1664 <       ForkJoinTask a =  new CheckedFJTask() {
1665 <            public void realCompute() {
1666 <                CCF f = new LCCF(null, 8);
1667 <                f.completeExceptionally(new FJException());
1668 <                try {
1669 <                    f.invoke();
1670 <                    shouldThrow();
1671 <                } catch (FJException success) {
1576 <                    checkCompletedAbnormally(f, success);
1577 <                }
1664 >        ForkJoinTask a = new CheckedRecursiveAction() {
1665 >            protected void realCompute() {
1666 >                CCF n = new LCCF(8);
1667 >                CCF f = new LCCF(n, 8);
1668 >                FJException ex = new FJException();
1669 >                f.completeExceptionally(ex);
1670 >                f.checkCompletedExceptionally(ex);
1671 >                n.checkCompletedExceptionally(ex);
1672              }};
1673          testInvokeOnPool(singletonPool(), a);
1674      }
# Line 1583 | Line 1677 | public class CountedCompleterTest extend
1677       * invokeAll(t1, t2) invokes all task arguments
1678       */
1679      public void testInvokeAll2Singleton() {
1680 <       ForkJoinTask a =  new CheckedFJTask() {
1681 <            public void realCompute() {
1682 <                CCF f = new LCCF(null, 8);
1683 <                CCF g = new LCCF(null, 9);
1680 >        ForkJoinTask a = new CheckedRecursiveAction() {
1681 >            protected void realCompute() {
1682 >                CCF f = new LCCF(8);
1683 >                CCF g = new LCCF(9);
1684                  invokeAll(f, g);
1685                  assertEquals(21, f.number);
1686                  assertEquals(34, g.number);
# Line 1600 | Line 1694 | public class CountedCompleterTest extend
1694       * invokeAll(tasks) with 1 argument invokes task
1695       */
1696      public void testInvokeAll1Singleton() {
1697 <       ForkJoinTask a =  new CheckedFJTask() {
1698 <            public void realCompute() {
1699 <                CCF f = new LCCF(null, 8);
1697 >        ForkJoinTask a = new CheckedRecursiveAction() {
1698 >            protected void realCompute() {
1699 >                CCF f = new LCCF(8);
1700                  invokeAll(f);
1701                  checkCompletedNormally(f);
1702                  assertEquals(21, f.number);
# Line 1614 | Line 1708 | public class CountedCompleterTest extend
1708       * invokeAll(tasks) with > 2 argument invokes tasks
1709       */
1710      public void testInvokeAll3Singleton() {
1711 <       ForkJoinTask a =  new CheckedFJTask() {
1712 <            public void realCompute() {
1713 <                CCF f = new LCCF(null, 8);
1714 <                CCF g = new LCCF(null, 9);
1715 <                CCF h = new LCCF(null, 7);
1711 >        ForkJoinTask a = new CheckedRecursiveAction() {
1712 >            protected void realCompute() {
1713 >                CCF f = new LCCF(8);
1714 >                CCF g = new LCCF(9);
1715 >                CCF h = new LCCF(7);
1716                  invokeAll(f, g, h);
1717                  assertEquals(21, f.number);
1718                  assertEquals(34, g.number);
# Line 1634 | Line 1728 | public class CountedCompleterTest extend
1728       * invokeAll(collection) invokes all tasks in the collection
1729       */
1730      public void testInvokeAllCollectionSingleton() {
1731 <       ForkJoinTask a =  new CheckedFJTask() {
1732 <            public void realCompute() {
1733 <                CCF f = new LCCF(null, 8);
1734 <                CCF g = new LCCF(null, 9);
1735 <                CCF h = new LCCF(null, 7);
1731 >        ForkJoinTask a = new CheckedRecursiveAction() {
1732 >            protected void realCompute() {
1733 >                CCF f = new LCCF(8);
1734 >                CCF g = new LCCF(9);
1735 >                CCF h = new LCCF(7);
1736                  HashSet set = new HashSet();
1737                  set.add(f);
1738                  set.add(g);
# Line 1658 | Line 1752 | public class CountedCompleterTest extend
1752       * invokeAll(tasks) with any null task throws NPE
1753       */
1754      public void testInvokeAllNPESingleton() {
1755 <       ForkJoinTask a =  new CheckedFJTask() {
1756 <            public void realCompute() {
1757 <                CCF f = new LCCF(null, 8);
1758 <                CCF g = new LCCF(null, 9);
1755 >        ForkJoinTask a = new CheckedRecursiveAction() {
1756 >            protected void realCompute() {
1757 >                CCF f = new LCCF(8);
1758 >                CCF g = new LCCF(9);
1759                  CCF h = null;
1760                  try {
1761                      invokeAll(f, g, h);
# Line 1675 | Line 1769 | public class CountedCompleterTest extend
1769       * invokeAll(t1, t2) throw exception if any task does
1770       */
1771      public void testAbnormalInvokeAll2Singleton() {
1772 <       ForkJoinTask a =  new CheckedFJTask() {
1773 <            public void realCompute() {
1774 <                CCF f = new LCCF(null, 8);
1775 <                FailingCCF g = new LFCCF(null, 9);
1772 >        ForkJoinTask a = new CheckedRecursiveAction() {
1773 >            protected void realCompute() {
1774 >                CCF f = new LCCF(8);
1775 >                FailingCCF g = new LFCCF(9);
1776                  try {
1777                      invokeAll(f, g);
1778                      shouldThrow();
# Line 1693 | Line 1787 | public class CountedCompleterTest extend
1787       * invokeAll(tasks) with 1 argument throws exception if task does
1788       */
1789      public void testAbnormalInvokeAll1Singleton() {
1790 <       ForkJoinTask a =  new CheckedFJTask() {
1791 <            public void realCompute() {
1792 <                FailingCCF g = new LFCCF(null, 9);
1790 >        ForkJoinTask a = new CheckedRecursiveAction() {
1791 >            protected void realCompute() {
1792 >                FailingCCF g = new LFCCF(9);
1793                  try {
1794                      invokeAll(g);
1795                      shouldThrow();
# Line 1710 | Line 1804 | public class CountedCompleterTest extend
1804       * invokeAll(tasks) with > 2 argument throws exception if any task does
1805       */
1806      public void testAbnormalInvokeAll3Singleton() {
1807 <       ForkJoinTask a =  new CheckedFJTask() {
1808 <            public void realCompute() {
1809 <                CCF f = new LCCF(null, 8);
1810 <                FailingCCF g = new LFCCF(null, 9);
1811 <                CCF h = new LCCF(null, 7);
1807 >        ForkJoinTask a = new CheckedRecursiveAction() {
1808 >            protected void realCompute() {
1809 >                CCF f = new LCCF(8);
1810 >                FailingCCF g = new LFCCF(9);
1811 >                CCF h = new LCCF(7);
1812                  try {
1813                      invokeAll(f, g, h);
1814                      shouldThrow();
# Line 1726 | Line 1820 | public class CountedCompleterTest extend
1820      }
1821  
1822      /**
1823 <     * invokeAll(collection)  throws exception if any task does
1823 >     * invokeAll(collection) throws exception if any task does
1824       */
1825      public void testAbnormalInvokeAllCollectionSingleton() {
1826 <       ForkJoinTask a =  new CheckedFJTask() {
1827 <            public void realCompute() {
1828 <                FailingCCF f = new LFCCF(null, 8);
1829 <                CCF g = new LCCF(null, 9);
1830 <                CCF h = new LCCF(null, 7);
1826 >        ForkJoinTask a = new CheckedRecursiveAction() {
1827 >            protected void realCompute() {
1828 >                FailingCCF f = new LFCCF(8);
1829 >                CCF g = new LCCF(9);
1830 >                CCF h = new LCCF(7);
1831                  HashSet set = new HashSet();
1832                  set.add(f);
1833                  set.add(g);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines