@Override
  public void dispose() {
    ThreadingAssertions.assertEventDispatchThread();

    if (myDisposed) {
      return;
    }
    myDisposed = true;

    if (myState == State.SHOWN) {
      LOG.debug("shown popup must be cancelled");
      cancel();
    }
    if (myState == State.DISPOSE) {
      return;
    }

    debugState("dispose popup", State.INIT, State.CANCEL);
    myState = State.DISPOSE;

    if (LOG.isDebugEnabled()) {
      LOG.debug("start disposing " + myContent);
    }

    Disposer.dispose(this, false);

    if (myPopup != null) {
      cancel(myDisposeEvent);
    }

    if (myContent != null) {
      Container parent = myContent.getParent();
      if (parent != null) parent.remove(myContent);
      myContent.removeAll();
      myContent.removeKeyListener(mySpeedSearch);
    }
    myContent = null;
    myPreferredFocusedComponent = null;
    myComponent = null;
    mySpeedSearchFoundInRootComponent = null;
    myCallBack = null;
    myListeners.clear();

    removeMouseOutCanceller();

    if (myFinalRunnable != null) {
      Runnable finalRunnable = myFinalRunnable;
      getFocusManager().doWhenFocusSettlesDown(() -> {
        try (AccessToken ignore = SlowOperations.startSection(SlowOperations.ACTION_PERFORM)) {
          finalRunnable.run();
        }
      });
      myFinalRunnable = null;
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug("stop disposing content");
    }
  }
@Override
  public void dispose()