/**
  * Overrides AbstractTask version to include checks for early exits while splitting or computing.
  */
 @Override
 public void compute() {
   Spliterator<P_IN> rs = spliterator, ls;
   long sizeEstimate = rs.estimateSize();
   long sizeThreshold = getTargetSize(sizeEstimate);
   boolean forkRight = false;
   @SuppressWarnings("unchecked")
   K task = (K) this;
   AtomicReference<R> sr = sharedResult;
   R result;
   while ((result = sr.get()) == null) {
     if (task.taskCanceled()) {
       result = task.getEmptyResult();
       break;
     }
     if (sizeEstimate <= sizeThreshold || (ls = rs.trySplit()) == null) {
       result = task.doLeaf();
       break;
     }
     K leftChild, rightChild, taskToFork;
     task.leftChild = leftChild = task.makeChild(ls);
     task.rightChild = rightChild = task.makeChild(rs);
     task.setPendingCount(1);
     if (forkRight) {
       forkRight = false;
       rs = ls;
       task = leftChild;
       taskToFork = rightChild;
     } else {
       forkRight = true;
       task = rightChild;
       taskToFork = leftChild;
     }
     taskToFork.fork();
     sizeEstimate = rs.estimateSize();
   }
   task.setLocalResult(result);
   task.tryComplete();
 }