public final void dispose() {

    if (isDisposed()) {
      return;
    }

    // Store the current title, tooltip, etc. so that anyone that they can be returned to
    // anyone that held on to the disposed reference.
    partName = getPartName();
    contentDescription = getContentDescription();
    tooltip = getTitleToolTip();
    title = getTitle();

    if (state == STATE_CREATION_IN_PROGRESS) {
      IStatus result =
          WorkbenchPlugin.getStatus(
              new PartInitException(
                  NLS.bind(
                      "Warning: Blocked recursive attempt by part {0} to dispose itself during creation", //$NON-NLS-1$
                      getId())));
      WorkbenchPlugin.log(result);
      return;
    }

    doDisposeNestedParts();

    // Disposing the pane disposes the part's widgets. The part's widgets need to be disposed before
    // the part itself.
    if (pane != null) {
      // Remove the dispose listener since this is the correct place for the widgets to get disposed
      Control targetControl = getPane().getControl();
      if (targetControl != null) {
        targetControl.removeDisposeListener(prematureDisposeListener);
      }
      pane.dispose();
    }

    doDisposePart();

    if (pane != null) {
      pane.removeContributions();
    }

    clearListenerList(internalPropChangeListeners);
    clearListenerList(partChangeListeners);
    Image oldImage = image;
    ImageDescriptor oldDescriptor = imageDescriptor;
    image = null;

    state = STATE_DISPOSED;
    imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
    defaultImageDescriptor = ImageDescriptor.getMissingImageDescriptor();
    immediateFirePropertyChange(IWorkbenchPartConstants.PROP_TITLE);
    clearListenerList(propChangeListeners);

    if (oldImage != null) {
      JFaceResources.getResources().destroy(oldDescriptor);
    }
  }