/**
   * Flush the modified content back to input elements via the content provider. The provided input
   * may be the current input of the viewer or it may be the previous input (i.e. this method may be
   * called to flush modified content during an input change).
   *
   * @param input the compare input
   * @param monitor a progress monitor or <code>null</code> if the method was call from a place
   *     where a progress monitor was not available.
   * @since 3.3
   */
  protected void flushContentOld(Object input, IProgressMonitor monitor) {

    // write back modified contents
    IMergeViewerContentProvider content = (IMergeViewerContentProvider) getContentProvider();
    if (content == null) {
      return;
    }

    boolean leftEmpty = content.getLeftContent(input) == null;
    boolean rightEmpty = content.getRightContent(input) == null;

    if (getCompareConfiguration().isLeftEditable() && isLeftDirty()) {
      byte[] bytes = getContents(true);
      if (rightEmpty && bytes != null && bytes.length == 0) bytes = null;
      setLeftDirty(false);
      content.saveLeftContent(input, bytes);
    }

    if (getCompareConfiguration().isRightEditable() && isRightDirty()) {
      byte[] bytes = getContents(false);
      if (leftEmpty && bytes != null && bytes.length == 0) bytes = null;
      setRightDirty(false);
      content.saveRightContent(input, bytes);
    }
  }
  /**
   * Updates the enabled state of the toolbar items.
   *
   * <p>This method is called whenever the state of the items needs updating.
   *
   * <p>Subclasses may extend this method, although this is generally not required.
   */
  protected void updateToolItems() {

    IMergeViewerContentProvider content = getMergeContentProvider();
    if (content == null) {
      return;
    }
    Object input = getInput();

    if (fCopyLeftToRightAction != null) {
      boolean enable = content.isRightEditable(input);
      // if (enable && input instanceof ICompareInput) {
      // ITypedElement e= ((ICompareInput) input).getLeft();
      // if (e == null)
      // enable= false;
      // }
      fCopyLeftToRightAction.setEnabled(enable);
    }

    if (fCopyRightToLeftAction != null) {
      boolean enable = content.isLeftEditable(input);
      // if (enable && input instanceof ICompareInput) {
      // ITypedElement e= ((ICompareInput) input).getRight();
      // if (e == null)
      // enable= false;
      // }
      fCopyRightToLeftAction.setEnabled(enable);
    }
  }
  void flushRightSide(Object input, IProgressMonitor monitor) {
    IMergeViewerContentProvider content = (IMergeViewerContentProvider) getContentProvider();
    if (content == null) {
      return;
    }

    boolean leftEmpty = content.getLeftContent(input) == null;

    if (getCompareConfiguration().isRightEditable() && isRightDirty()) {
      byte[] bytes = getContents(false);
      if (leftEmpty && bytes != null && bytes.length == 0) bytes = null;
      setRightDirty(false);
      content.saveRightContent(input, bytes);
    }
  }
  /**
   * Updates the headers of the three areas by querying the content provider for a name and image
   * for the three sides of the input object.
   *
   * <p>This method is called whenever the header must be updated.
   *
   * <p>Subclasses may extend this method, although this is generally not required.
   */
  protected void updateHeader() {

    IMergeViewerContentProvider content = getMergeContentProvider();
    if (content == null) {
      return;
    }
    Object input = getInput();

    // Only change a label if there is a new label available
    if (fAncestorLabel != null) {
      Image ancestorImage = content.getAncestorImage(input);
      if (ancestorImage != null) fAncestorLabel.setImage(ancestorImage);
      String ancestorLabel = content.getAncestorLabel(input);
      if (ancestorLabel != null) fAncestorLabel.setText(TextProcessor.process(ancestorLabel));
    }
    if (fLeftLabel != null) {
      Image leftImage = content.getLeftImage(input);
      if (leftImage != null) fLeftLabel.setImage(leftImage);
      String leftLabel = content.getLeftLabel(input);
      if (leftLabel != null) fLeftLabel.setText(TextProcessor.process(leftLabel));
    }
    if (fRightLabel != null) {
      Image rightImage = content.getRightImage(input);
      if (rightImage != null) fRightLabel.setImage(rightImage);
      String rightLabel = content.getRightLabel(input);
      if (rightLabel != null) fRightLabel.setText(TextProcessor.process(rightLabel));
    }
  }
  private void internalRefresh(Object input) {

    IMergeViewerContentProvider content = getMergeContentProvider();
    if (content == null) {
      return;
    }
    Object ancestor = content.getAncestorContent(input);
    boolean oldFlag = fIsThreeWay;
    if (Utilities.isHunk(input)) {
      fIsThreeWay = true;
    } else if (input instanceof ICompareInput)
      fIsThreeWay = (((ICompareInput) input).getKind() & Differencer.DIRECTION_MASK) != 0;
    else fIsThreeWay = ancestor != null;

    if (fAncestorItem != null) fAncestorItem.setVisible(fIsThreeWay);

    if (fAncestorVisible && oldFlag != fIsThreeWay) fComposite.layout(true);

    Object left = content.getLeftContent(input);
    Object right = content.getRightContent(input);
    updateContent(ancestor, left, right);

    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=453799
    // Content provider may be disposed after call to updateContent()
    content = getMergeContentProvider();
    if (content == null) {
      return;
    }

    updateHeader();
    ToolBarManager tbm = CompareViewerPane.getToolBarManager(fComposite.getParent());
    if (tbm != null) {
      updateToolItems();
      tbm.update(true);
      tbm.getControl().getParent().layout(true);
    }
  }