private @Nullable ApplierCompleter<T> execAndForkSubTasks() {
    int hi = this.hi;
    ApplierCompleter<T> right = null;
    Throwable throwable = null;

    try {
      for (int i = lo; i < hi; ++i) {
        ProgressManager.checkCanceled();
        if (hi - i >= 2) {
          int availableParallelism = JobSchedulerImpl.getJobPoolParallelism() - Math.max(0,getSurplusQueuedTaskCount());
          if (availableParallelism > 1) {
            // fork off several sub-tasks at once to reduce rampup
            for (int n=0; n<availableParallelism; n++) {
              int mid = i + hi >>> 1;
              if (mid == i || mid == hi) break;
              right = new ApplierCompleter<>(this, runInReadAction, failFastOnAcquireReadAction, progressIndicator, array, processor,
                                             mid, hi, failedSubTasks, right);
              //children.add(right);
              addToPendingCount(1);
              right.fork();
              hi = mid;
            }
          }
        }
        if (!processor.process(array.get(i))) {
          throw new ComputationAbortedException();
        }
      }

      // traverse the list looking for a task available for stealing
      if (right != null) {
        // tries to unfork, execute and re-link subtasks
        ApplierCompleter<T> cur = right;
        Throwable result = right.throwable;
        while (cur != null) {
          ProgressManager.checkCanceled();
          if (cur.tryUnfork()) {
            cur.execAndForkSubTasks();
            result = moreImportant(result, cur.throwable);
          }
          cur = cur.next;
        }
        throwable = result;
      }
    }
    catch (Throwable e) {
      cancelProgress();
      throwable = e;
    }
    finally {
      doComplete(moreImportant(throwable, this.throwable));
    }
    return right;
  }
private @Nullable ApplierCompleter<T> execAndForkSubTasks()