code: void notifyAndClearListeners() {
      if (!canBeCancelled()) {
        return;
      }
      ArrayList<ExecutableListener> tmpListeners;
      synchronized (this) {
        if (listeners == null) {
          return;
        }
        tmpListeners = listeners;
        listeners = null;
      }
      // Deliver events to non-child context listeners before we notify child contexts. We do this
      // to cancel higher level units of work before child units. This allows for a better error
      // handling paradigm where the higher level unit of work knows it is cancelled and so can
      // ignore errors that bubble up as a result of cancellation of lower level units.
      for (int i = 0; i < tmpListeners.size(); i++) {
        if (!(tmpListeners.get(i).listener instanceof ParentListener)) {
          tmpListeners.get(i).deliver();
        }
      }
      for (int i = 0; i < tmpListeners.size(); i++) {
        if (tmpListeners.get(i).listener instanceof ParentListener) {
          tmpListeners.get(i).deliver();
        }
      }
      if (cancellableAncestor != null) {
        cancellableAncestor.removeListener(parentListener);
      }
    }
docs: Notify all listeners that this context has been cancelled and immediately release
  any reference to them so that they may be garbage collected.