/**
   * Internal hook method called when the input to this viewer is initially set or subsequently
   * changed.
   *
   * <p>The <code>ContentMergeViewer</code> implementation of this <code>Viewer</code> method tries
   * to save the old input by calling <code>doSave(...)</code> and then calls <code>
   * internalRefresh(...)</code> .
   *
   * @param input the new input of this viewer, or <code>null</code> if there is no new input
   * @param oldInput the old input element, or <code>null</code> if there was previously no input
   */
  protected final void inputChanged(Object input, Object oldInput) {

    if (input != oldInput && oldInput != null) {
      ICompareInputLabelProvider lp = getCompareConfiguration().getLabelProvider();
      if (lp != null) lp.removeListener(labelChangeListener);
    }

    if (input != oldInput && oldInput instanceof ICompareInput) {
      ICompareContainer container = getCompareConfiguration().getContainer();
      container.removeCompareInputChangeListener(
          (ICompareInput) oldInput, fCompareInputChangeListener);
    }

    boolean success = doSave(input, oldInput);

    if (input != oldInput && input instanceof ICompareInput) {
      ICompareContainer container = getCompareConfiguration().getContainer();
      container.addCompareInputChangeListener((ICompareInput) input, fCompareInputChangeListener);
    }

    if (input != oldInput && input != null) {
      ICompareInputLabelProvider lp = getCompareConfiguration().getLabelProvider();
      if (lp != null) lp.addListener(labelChangeListener);
    }

    if (success) {
      setLeftDirty(false);
      setRightDirty(false);
    }

    if (input != oldInput) internalRefresh(input);
  }
  /**
   * Called on the viewer disposal. Unregisters from the compare configuration. Clients may extend
   * if they have to do additional cleanup.
   *
   * @see org.eclipse.jface.viewers.ContentViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
   */
  protected void handleDispose(DisposeEvent event) {

    if (fHandlerService != null) fHandlerService.dispose();

    Object input = getInput();
    if (input instanceof ICompareInput) {
      ICompareContainer container = getCompareConfiguration().getContainer();
      container.removeCompareInputChangeListener(
          (ICompareInput) input, fCompareInputChangeListener);
    }
    if (input != null) {
      ICompareInputLabelProvider lp = getCompareConfiguration().getLabelProvider();
      if (lp != null) lp.removeListener(labelChangeListener);
    }

    if (fPropertyChangeListener != null) {
      fCompareConfiguration.removePropertyChangeListener(fPropertyChangeListener);
      fPropertyChangeListener = null;
    }

    fAncestorLabel = null;
    fLeftLabel = null;
    fDirectionLabel = null;
    fRightLabel = null;
    fCenter = null;

    if (fRightArrow != null) {
      fRightArrow.dispose();
      fRightArrow = null;
    }
    if (fLeftArrow != null) {
      fLeftArrow.dispose();
      fLeftArrow = null;
    }
    if (fBothArrow != null) {
      fBothArrow.dispose();
      fBothArrow = null;
    }

    if (fNormalCursor != null) {
      fNormalCursor.dispose();
      fNormalCursor = null;
    }
    if (fHSashCursor != null) {
      fHSashCursor.dispose();
      fHSashCursor = null;
    }
    if (fVSashCursor != null) {
      fVSashCursor.dispose();
      fVSashCursor = null;
    }
    if (fHVSashCursor != null) {
      fHVSashCursor.dispose();
      fHVSashCursor = null;
    }

    super.handleDispose(event);
  }