@Override
 public void run() {
   if (canceled) {
     return;
   }
   setCurrent(parent);
   try {
     cancellationHandler = task.doExecute(completionHandle);
   } catch (Throwable e) {
     completionHandle.setDoExecuteFailed("ExternalTask.doExecute", e);
     if (stackTrace != null && !parent.isRethrown(e)) {
       AsyncStackTrace merged = new AsyncStackTrace(stackTrace, e.getStackTrace(), 0);
       merged.setStartFrom(getParentTaskMethodName());
       e.setStackTrace(merged.getStackTrace());
     }
     parent.fail(this, e);
   } finally {
     setCurrent(null);
   }
 }
 @Override
 public void fail(final Throwable e) {
   if (failure != null) {
     throw new IllegalStateException(
         "Invalid ExternalTaskCompletionHandle as " + methodName + " failed with exception.",
         failure);
   }
   if (completed) {
     throw new IllegalStateException("Already completed");
   }
   if (stackTrace != null && !parent.isRethrown(e)) {
     AsyncStackTrace merged = new AsyncStackTrace(stackTrace, e.getStackTrace(), 0);
     merged.setStartFrom(getParentTaskMethodName());
     e.setStackTrace(merged.getStackTrace());
   }
   failure = e;
   if (!inCancellationHandler) {
     failToParent(e);
   }
 }
 @Override
 public void run() {
   if (state == State.CLOSED) {
     return;
   }
   if (state == State.CREATED) {
     state = State.TRYING;
   }
   setCurrent(this);
   Throwable f = failure;
   try {
     switch (state) {
       case TRYING:
         if (canceled) {
           return;
         }
         tryCatchFinally.doTry();
         break;
       case CATCHING:
         failure = null;
         tryCatchFinally.doCatch(f);
         break;
       case FINALIZING:
         tryCatchFinally.doFinally();
     }
   } catch (Throwable e) {
     if (stackTrace != null && e != f) {
       AsyncStackTrace merged = new AsyncStackTrace(stackTrace, e.getStackTrace(), 0);
       merged.setStartFrom(getParentTaskMethodName());
       e.setStackTrace(merged.getStackTrace());
     }
     failure = e;
     cancelHeirs();
   } finally {
     setCurrent(null);
     executed = true;
     updateState();
   }
 }