private void expireWithDisposables(@NotNull Set<? extends Disposable> disposables) {
      for (Disposable parent : disposables) {
        if (parent instanceof Project ? ((Project)parent).isDisposed() : Disposer.isDisposed(parent)) {
          cancel();
          break;
        }
        Disposable child = new CheckedDisposable() {
          private volatile boolean disposed;
          @Override
          public boolean isDisposed() {
            return disposed;
          }

          @Override
          public void dispose() {
            disposed = true;
            // NB: We call here `super.cancel()` directly instead of `cancel()`
            // The reason is that `Job` is needed to cover the scheduling of `myUiThreadAction`,
            // so its lifetime is bigger than the lifetime of computation in NBRA, hence `Job` should not be cancelled in `dispose`.
            Submission.super.cancel();
          }
        };
        //noinspection TestOnlyProblems
        Disposable parentDisposable =
          parent instanceof ProjectImpl && ((ProjectEx)parent).isLight() ? ((ProjectImpl)parent).getEarlyDisposable() : parent;
        if (!Disposer.tryRegister(parentDisposable, child)) {
          cancel();
          break;
        }
        myExpirationDisposables.add(child);
      }
    }
private void expireWithDisposables(@NotNull Set<? extends Disposable> disposables)