public void remove(AsyncContextBase async) {
   checkClosed();
   heirs.remove(async);
   if (!async.isDaemon()) {
     nonDaemonHeirsCount--;
     assert nonDaemonHeirsCount >= 0;
   }
   updateState();
 }
 public void fail(AsyncContextBase async, Throwable e) {
   checkClosed();
   boolean cancellationException = e instanceof CancellationException;
   // Explicit cancellation through cancel() call leads to CancellationException being
   // thrown from the cancelled component. At the same time cancellation caused by the
   // daemon flag is ignored.
   if (!cancellationException || (failure == null && !daemondCausedCancellation)) {
     failure = e;
   }
   boolean removed = heirs.remove(async);
   assert removed;
   if (!async.isDaemon()) {
     nonDaemonHeirsCount--;
     assert nonDaemonHeirsCount >= 0;
   }
   cancelHeirs();
   updateState();
 }
  @Override
  public void add(final AsyncContextBase async, Promise<?> waitFor) {
    checkClosed();
    heirs.add(async);
    if (!async.isDaemon()) {
      nonDaemonHeirsCount++;
    }
    if (waitFor == null) {
      executor.execute(async);
    } else {
      waitFor.addCallback(
          new Runnable() {

            @Override
            public void run() {
              executor.execute(async);
            }
          });
    }
  }