/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Alex Blewitt <alex.blewitt@gmail.com> - replace new Boolean with Boolean.valueOf - https://bugs.eclipse.org/470344
 *     Stefan Xenos <sxenos@gmail.com> (Google) - bug 448968 - Add diagnostic logging
 *     Conrad Groth - Bug 213780 - Compare With direction should be configurable
 *******************************************************************************/

package org.eclipse.compare.contentmergeviewer;

import java.io.IOException;
import java.util.ResourceBundle;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.CompareViewerPane;
import org.eclipse.compare.ICompareContainer;
import org.eclipse.compare.ICompareInputLabelProvider;
import org.eclipse.compare.IPropertyChangeNotifier;
import org.eclipse.compare.internal.ChangePropertyAction;
import org.eclipse.compare.internal.CompareEditor;
import org.eclipse.compare.internal.CompareHandlerService;
import org.eclipse.compare.internal.CompareMessages;
import org.eclipse.compare.internal.ComparePreferencePage;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.compare.internal.ICompareUIConstants;
import org.eclipse.compare.internal.IFlushable2;
import org.eclipse.compare.internal.ISavingSaveable;
import org.eclipse.compare.internal.MergeViewerContentProvider;
import org.eclipse.compare.internal.MirroredMergeViewerContentProvider;
import org.eclipse.compare.internal.Policy;
import org.eclipse.compare.internal.Utilities;
import org.eclipse.compare.internal.ViewerSwitchingCancelled;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.LegacyActionTools;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPersistentPreferenceStore;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ContentViewer;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.Saveable;


/**
 * An abstract compare and merge viewer with two side-by-side content areas and
 * an optional content area for the ancestor. The implementation makes no
 * assumptions about the content type.
 * <p>
 * <code>ContentMergeViewer</code>
 * </p>
 * <ul>
 * <li>implements the overall layout and defines hooks so that subclasses can
 * easily provide an implementation for a specific content type,
 * <li>implements the UI for making the areas resizable,
 * <li>has an action for controlling whether the ancestor area is visible or
 * not,
 * <li>has actions for copying one side of the input to the other side,
 * <li>tracks the dirty state of the left and right sides and send out
 * notification on state changes.
 * </ul>
 * <p>
 * A <code>ContentMergeViewer</code> accesses its model by means of a content
 * provider which must implement the <code>IMergeViewerContentProvider</code>
 * interface.
 * </p>
 * <p>
 * Clients may wish to use the standard concrete subclass
 * <code>TextMergeViewer</code>, or define their own subclass.
 * </p>
 *
 * @see IMergeViewerContentProvider
 * @see TextMergeViewer
 */
public abstract class ContentMergeViewer extends ContentViewer
					implements IPropertyChangeNotifier, IFlushable, IFlushable2 {
	/* package */ static final int HORIZONTAL= 1;
	/* package */ static final int VERTICAL= 2;

	static final double HSPLIT= 0.5;
	static final double VSPLIT= 0.3;

	private class ContentMergeViewerLayout extends Layout {
		@Override
		public Point computeSize(Composite c, int w, int h, boolean force) {
			return new Point(100, 100);
		}

		@Override
		public void layout(Composite composite, boolean force) {
			if (fLeftLabel == null) {
				if (composite.isDisposed()) {
					CompareUIPlugin
							.log(new IllegalArgumentException("Attempted to perform a layout on a disposed composite")); //$NON-NLS-1$
				}
				if (Policy.debugContentMergeViewer) {
					logTrace("found bad label. Layout = " + System.identityHashCode(this) + ". composite = "  //$NON-NLS-1$//$NON-NLS-2$
							+ System.identityHashCode(composite) + ". fComposite = " //$NON-NLS-1$
							+ System.identityHashCode(fComposite) + ". fComposite.isDisposed() = " //$NON-NLS-1$
							+ fComposite.isDisposed());
					logStackTrace();
				}
				// Help to find out the cause for bug 449558
				NullPointerException npe= new NullPointerException("fLeftLabel is 'null';fLeftLabelSet is " + fLeftLabelSet + ";fComposite.isDisposed() is " + fComposite.isDisposed()); //$NON-NLS-1$ //$NON-NLS-2$

				// Allow to test whether doing nothing helps
				if (Boolean.getBoolean("ContentMergeViewer.DEBUG")) { //$NON-NLS-1$
					CompareUIPlugin.log(npe);
					return;
				}

				throw npe;
			}

			// determine some derived sizes
			int headerHeight= fLeftLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
			Rectangle r= composite.getClientArea();

			int centerWidth= getCenterWidth();
			int width1= (int) ((r.width - centerWidth) * getHorizontalSplitRatio());
			int width2= r.width - width1 - centerWidth;

			int height1= 0;
			int height2= 0;
			if (fIsThreeWay && fAncestorVisible) {
				height1= (int) ((r.height - (2 * headerHeight)) * fVSplit);
				height2= r.height - (2 * headerHeight) - height1;
			} else {
				height1= 0;
				height2= r.height - headerHeight;
			}

			int y= 0;

			if (fIsThreeWay && fAncestorVisible) {
				fAncestorLabel.setBounds(0, y, r.width, headerHeight);
				fAncestorLabel.setVisible(true);
				y+= headerHeight;
				handleResizeAncestor(0, y, r.width, height1);
				y+= height1;
			} else {
				fAncestorLabel.setVisible(false);
				handleResizeAncestor(0, 0, 0, 0);
			}

			fLeftLabel.getSize();	// without this resizing would not always work

			if (centerWidth > 3) {
				fLeftLabel.setBounds(0, y, width1 + 1, headerHeight);
				fDirectionLabel.setVisible(true);
				fDirectionLabel.setBounds(width1 + 1, y, centerWidth - 1, headerHeight);
				fRightLabel.setBounds(width1+centerWidth, y, width2, headerHeight);
			} else {
				fLeftLabel.setBounds(0, y, width1, headerHeight);
				fDirectionLabel.setVisible(false);
				fRightLabel.setBounds(width1, y, r.width - width1, headerHeight);
			}

			y+= headerHeight;

			if (fCenter != null && !fCenter.isDisposed())
				fCenter.setBounds(width1, y, centerWidth, height2);

			handleResizeLeftRight(0, y, width1, centerWidth, width2, height2);
		}

		private double getHorizontalSplitRatio() {
			if (fHSplit < 0) {
				Object input = getInput();
				if (input instanceof ICompareInput) {
					ICompareInput ci = (ICompareInput) input;
					if (ci.getLeft() == null)
						return 0.1;
					if (ci.getRight() == null)
						return 0.9;
				}
				return HSPLIT;
			}
			return fHSplit;
		}
	}

	class Resizer extends MouseAdapter implements MouseMoveListener {
		Control fControl;
		int fX, fY;
		int fWidth1, fWidth2;
		int fHeight1, fHeight2;
		int fDirection;
		boolean fLiveResize;
		boolean fIsDown;

		public Resizer(Control c, int dir) {
			fDirection= dir;
			fControl= c;
			fLiveResize= !(fControl instanceof Sash);
			updateCursor(c, dir);
			fControl.addMouseListener(this);
			fControl.addMouseMoveListener(this);
			fControl.addDisposeListener(
				e -> fControl= null
			);
		}

		@Override
		public void mouseDoubleClick(MouseEvent e) {
			if ((fDirection & HORIZONTAL) != 0)
				fHSplit= -1;
			if ((fDirection & VERTICAL) != 0)
				fVSplit= VSPLIT;
			fComposite.layout(true);
		}

		@Override
		public void mouseDown(MouseEvent e) {
			Composite parent= fControl.getParent();

			Point s= parent.getSize();
			Point as= fAncestorLabel.getSize();
			Point ys= fLeftLabel.getSize();
			Point ms= fRightLabel.getSize();

			fWidth1= ys.x;
			fWidth2= ms.x;
			fHeight1= fLeftLabel.getLocation().y - as.y;
			fHeight2= s.y - (fLeftLabel.getLocation().y + ys.y);

			fX= e.x;
			fY= e.y;
			fIsDown= true;
		}

		@Override
		public void mouseUp(MouseEvent e) {
			fIsDown= false;
			if (!fLiveResize)
				resize(e);
		}

		@Override
		public void mouseMove(MouseEvent e) {
			if (fIsDown && fLiveResize)
				resize(e);
		}

		private void resize(MouseEvent e) {
			int dx= e.x-fX;
			int dy= e.y-fY;

			int centerWidth= fCenter.getSize().x;

			if (fWidth1 + dx > centerWidth && fWidth2 - dx > centerWidth) {
				fWidth1 += dx;
				fWidth2 -= dx;
				if ((fDirection & HORIZONTAL) != 0)
					fHSplit= (double) fWidth1 / (double) (fWidth1 + fWidth2);
			}
			if (fHeight1 + dy > centerWidth && fHeight2 - dy > centerWidth) {
				fHeight1 += dy;
				fHeight2 -= dy;
				if ((fDirection & VERTICAL) != 0)
					fVSplit= (double) fHeight1 / (double) (fHeight1 + fHeight2);
			}

			fComposite.layout(true);
			fControl.getDisplay().update();
		}
	}

	/** Style bits for top level composite */
	private int fStyles;
	private ResourceBundle fBundle;
	private final CompareConfiguration fCompareConfiguration;
	private IPropertyChangeListener fPropertyChangeListener;
	private IPropertyChangeListener fPreferenceChangeListener;
	private ICompareInputChangeListener fCompareInputChangeListener;
	private ListenerList<IPropertyChangeListener> fListenerList;
	boolean fConfirmSave= true;

	private double fHSplit= -1;		// width ratio of left and right panes
	private double fVSplit= VSPLIT;		// height ratio of ancestor and bottom panes

	private boolean fIsThreeWay;		// whether their is an ancestor
	private boolean fAncestorVisible;	// whether the ancestor pane is visible
	private ActionContributionItem fAncestorItem;

	private ActionContributionItem copyLeftToRightItem;	// copy from left to right
	private ActionContributionItem copyRightToLeftItem;	// copy from right to left

	private boolean fIsLeftDirty;
	private boolean fIsRightDirty;

	private CompareHandlerService fHandlerService;

	private final MergeViewerContentProvider fDefaultContentProvider;
	private Action fSwitchLeftAndRight;

	// SWT widgets
	/* package */ Composite fComposite;
	private CLabel fAncestorLabel;
	private CLabel fLeftLabel;

	private boolean fLeftLabelSet= false; // needed for debug output for bug 449558
	private CLabel fRightLabel;
	/* package */ CLabel fDirectionLabel;
	/* package */ Control fCenter;

	//---- SWT resources to be disposed
	private Image fRightArrow;
	private Image fLeftArrow;
	private Image fBothArrow;
	private Cursor fNormalCursor;
	private Cursor fHSashCursor;
	private Cursor fVSashCursor;
	private Cursor fHVSashCursor;

	private ILabelProviderListener labelChangeListener = event -> {
		Object[] elements = event.getElements();
		for (int i = 0; i < elements.length; i++) {
			Object object = elements[i];
			if (object == getInput())
				updateHeader();
		}
	};

	//---- end

	/**
	 * Creates a new content merge viewer and initializes with a resource bundle and a
	 * configuration.
	 *
	 * @param style SWT style bits
	 * @param bundle the resource bundle
	 * @param cc the configuration object
	 */
	protected ContentMergeViewer(int style, ResourceBundle bundle, CompareConfiguration cc) {
		if (Policy.debugContentMergeViewer) {
			logTrace("constructed (fLeftLabel == null)"); //$NON-NLS-1$
			logStackTrace();
		}

		fStyles= style & ~(SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);	// remove BIDI direction bits
		fBundle= bundle;

		fAncestorVisible= Utilities.getBoolean(cc, ICompareUIConstants.PROP_ANCESTOR_VISIBLE, fAncestorVisible);
		fConfirmSave= Utilities.getBoolean(cc, CompareEditor.CONFIRM_SAVE_PROPERTY, fConfirmSave);

		fCompareInputChangeListener = (input) -> { if (input == getInput()) handleCompareInputChange(); };

		// Make sure the compare configuration is not null
		fCompareConfiguration = cc != null ? cc : new CompareConfiguration();
		fPropertyChangeListener = event -> handlePropertyChangeEvent(event);
		fCompareConfiguration.addPropertyChangeListener(fPropertyChangeListener);
		fPreferenceChangeListener = event -> {
			if (event.getProperty().equals(ComparePreferencePage.SWAPPED)) {
				getCompareConfiguration().setProperty(CompareConfiguration.MIRRORED, event.getNewValue());
				updateContentProvider();
				updateToolItems();
			}
		};
		cc.getPreferenceStore().addPropertyChangeListener(fPreferenceChangeListener);

		fDefaultContentProvider = new MergeViewerContentProvider(fCompareConfiguration);
		updateContentProvider();

		fIsLeftDirty = false;
		fIsRightDirty = false;
	}

	private void logStackTrace() {
		new Exception("<Fake exception> in " + getClass().getName()).printStackTrace(System.out); //$NON-NLS-1$
	}

	private void logTrace(String string) {
		System.out.println("ContentMergeViewer " + System.identityHashCode(this) + ": " + string);   //$NON-NLS-1$//$NON-NLS-2$
	}

	//---- hooks ---------------------


	/**
	 * Returns the viewer's name.
	 *
	 * @return the viewer's name
	 */
	public String getTitle() {
		return Utilities.getString(getResourceBundle(), "title"); //$NON-NLS-1$
	}

	/**
	 * Creates the SWT controls for the ancestor, left, and right
	 * content areas of this compare viewer.
	 * Implementations typically hold onto the controls
	 * so that they can be initialized with the input objects in method
	 * <code>updateContent</code>.
	 *
	 * @param composite the container for the three areas
	 */
	abstract protected void createControls(Composite composite);

	/**
	 * Lays out the ancestor area of the compare viewer.
	 * It is called whenever the viewer is resized or when the sashes between
	 * the areas are moved to adjust the size of the areas.
	 *
	 * @param x the horizontal position of the ancestor area within its container
	 * @param y the vertical position of the ancestor area within its container
	 * @param width the width of the ancestor area
	 * @param height the height of the ancestor area
	 */
	abstract protected void handleResizeAncestor(int x, int y, int width, int height);

	/**
	 * Lays out the left and right areas of the compare viewer.
	 * It is called whenever the viewer is resized or when the sashes between
	 * the areas are moved to adjust the size of the areas.
	 *
	 * @param x the horizontal position of the left area within its container
	 * @param y the vertical position of the left and right area within its container
	 * @param leftWidth the width of the left area
	 * @param centerWidth the width of the gap between the left and right areas
	 * @param rightWidth the width of the right area
	 * @param height the height of the left and right areas
	 */
	abstract protected void handleResizeLeftRight(int x, int y, int leftWidth, int centerWidth,
			int rightWidth, int height);

	/**
	 * Contributes items to the given <code>ToolBarManager</code>.
	 * It is called when this viewer is installed in its container and if the container
	 * has a <code>ToolBarManager</code>.
	 * The <code>ContentMergeViewer</code> implementation of this method does nothing.
	 * Subclasses may reimplement.
	 *
	 * @param toolBarManager the toolbar manager to contribute to
	 */
	protected void createToolItems(ToolBarManager toolBarManager) {
		// empty implementation
	}

	/**
	 * Initializes the controls of the three content areas with the given input objects.
	 *
	 * @param ancestor the input for the ancestor area
	 * @param left the input for the left area
	 * @param right the input for the right area
	 */
	abstract protected void updateContent(Object ancestor, Object left, Object right);

	/**
	 * Copies the content of one side to the other side.
	 * Called from the (internal) actions for copying the sides of the viewer's input object.
	 *
	 * @param leftToRight if <code>true</code>, the left side is copied to the right side;
	 * if <code>false</code>, the right side is copied to the left side
	 */
	abstract protected void copy(boolean leftToRight);

	/**
	 * Returns the byte contents of the left or right side. If the viewer
	 * has no editable content <code>null</code> can be returned.
	 *
	 * @param left if <code>true</code>, the byte contents of the left area is returned;
	 * 	if <code>false</code>, the byte contents of the right area
	 * @return the content as an array of bytes, or <code>null</code>
	 */
	abstract protected byte[] getContents(boolean left);

	//----------------------------

	/**
	 * Returns the resource bundle of this viewer.
	 *
	 * @return the resource bundle
	 */
	protected ResourceBundle getResourceBundle() {
		return fBundle;
	}

	/**
	 * Returns the compare configuration of this viewer.
	 *
	 * @return the compare configuration, never <code>null</code>
	 */
	protected CompareConfiguration getCompareConfiguration() {
		return fCompareConfiguration;
	}

	/**
	 * The <code>ContentMergeViewer</code> implementation of this
	 * <code>ContentViewer</code> method
	 * checks to ensure that the content provider is an <code>IMergeViewerContentProvider</code>.
	 * @param contentProvider the content provider to set. Must implement IMergeViewerContentProvider.
	 */
	@Override
	public void setContentProvider(IContentProvider contentProvider) {
		Assert.isTrue(contentProvider instanceof IMergeViewerContentProvider);
		super.setContentProvider(contentProvider);
	}

	private void updateContentProvider() {
		setContentProvider(getCompareConfiguration().isMirrored()
				? new MirroredMergeViewerContentProvider(getCompareConfiguration(), fDefaultContentProvider)
				: fDefaultContentProvider);
	}

	/* package */ IMergeViewerContentProvider getMergeContentProvider() {
		return (IMergeViewerContentProvider) getContentProvider();
	}

	/**
	 * The <code>ContentMergeViewer</code> implementation of this
	 * <code>Viewer</code> method returns the empty selection. Subclasses may override.
	 * @return empty selection.
	 */
	@Override
	public ISelection getSelection() {
		return () -> true;
	}

	/**
	 * The <code>ContentMergeViewer</code> implementation of this
	 * <code>Viewer</code> method does nothing. Subclasses may reimplement.
	 * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean)
	 */
	@Override
	public void setSelection(ISelection selection, boolean reveal) {
		// Empty implementation.
	}

	/**
	 * Callback that is invoked when a property in the compare configuration
	 * ({@link #getCompareConfiguration()} changes.
	 * @param event the property change event
	 * @since 3.3
	 */
	protected void handlePropertyChangeEvent(PropertyChangeEvent event) {
		String key= event.getProperty();

		if (key.equals(ICompareUIConstants.PROP_ANCESTOR_VISIBLE)) {
			fAncestorVisible= Utilities.getBoolean(getCompareConfiguration(), ICompareUIConstants.PROP_ANCESTOR_VISIBLE, fAncestorVisible);
			fComposite.layout(true);

			updateCursor(fLeftLabel, VERTICAL);
			updateCursor(fDirectionLabel, HORIZONTAL | VERTICAL);
			updateCursor(fRightLabel, VERTICAL);

			return;
		}

		if (key.equals(ICompareUIConstants.PROP_IGNORE_ANCESTOR)) {
			setAncestorVisibility(false, !Utilities.getBoolean(getCompareConfiguration(), ICompareUIConstants.PROP_IGNORE_ANCESTOR, false));
			return;
		}
	}

	void updateCursor(Control c, int dir) {
		if (!(c instanceof Sash)) {
			Cursor cursor= null;
			switch (dir) {
			case VERTICAL:
				if (fAncestorVisible) {
					if (fVSashCursor == null)
						fVSashCursor=c.getDisplay().getSystemCursor(SWT.CURSOR_SIZENS);
					cursor= fVSashCursor;
				} else {
					if (fNormalCursor == null)
						fNormalCursor= c.getDisplay().getSystemCursor(SWT.CURSOR_ARROW);
					cursor= fNormalCursor;
				}
				break;
			case HORIZONTAL:
				if (fHSashCursor == null)
					fHSashCursor= c.getDisplay().getSystemCursor(SWT.CURSOR_SIZEWE);
				cursor= fHSashCursor;
				break;
			case VERTICAL + HORIZONTAL:
				if (fAncestorVisible) {
					if (fHVSashCursor == null)
						fHVSashCursor= c.getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL);
					cursor= fHVSashCursor;
				} else {
					if (fHSashCursor == null)
						fHSashCursor= c.getDisplay().getSystemCursor(SWT.CURSOR_SIZEWE);
					cursor= fHSashCursor;
				}
				break;
			}
			if (cursor != null)
				c.setCursor(cursor);
		}
	}

	private void setAncestorVisibility(boolean visible, boolean enabled) {
		if (fAncestorItem != null) {
			Action action= (Action) fAncestorItem.getAction();
			if (action != null) {
				action.setChecked(visible);
				action.setEnabled(enabled);
			}
		}
		getCompareConfiguration().setProperty(ICompareUIConstants.PROP_ANCESTOR_VISIBLE, Boolean.valueOf(visible));
	}

	//---- input

	/**
	 * Return whether the input is a three-way comparison.
	 * @return whether the input is a three-way comparison
	 * @since 3.3
	 */
	protected boolean isThreeWay() {
		return fIsThreeWay;
	}

	/**
	 * 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
	 */
	@Override
	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);
	}

	/**
	 * This method is called from the <code>Viewer</code> method <code>inputChanged</code>
	 * to save any unsaved changes of the old input.
	 * <p>
	 * The <code>ContentMergeViewer</code> implementation of this
	 * method calls <code>saveContent(...)</code>. If confirmation has been turned on
	 * with <code>setConfirmSave(true)</code>, a confirmation alert is posted before saving.
	 * </p>
	 * Clients can override this method and are free to decide whether
	 * they want to call the inherited method.
	 * @param newInput 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
	 * @return <code>true</code> if saving was successful, or if the user didn't want to save (by pressing 'NO' in the confirmation dialog).
	 * @since 2.0
	 */
	protected boolean doSave(Object newInput, Object oldInput) {
		// before setting the new input we have to save the old
		if (isLeftDirty() || isRightDirty()) {
			if (Utilities.RUNNING_TESTS) {
				if (Utilities.TESTING_FLUSH_ON_COMPARE_INPUT_CHANGE) {
					flushContent(oldInput, null);
				}
			} else if (fConfirmSave) {
				// post alert
				Shell shell= fComposite.getShell();

				MessageDialog dialog= new MessageDialog(shell,
						Utilities.getString(getResourceBundle(), "saveDialog.title"), //$NON-NLS-1$
						null, 	// accept the default window icon
						Utilities.getString(getResourceBundle(), "saveDialog.message"), //$NON-NLS-1$
						MessageDialog.QUESTION,
						new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, },
						0);		// default button index

				switch (dialog.open()) {	// open returns index of pressed button
				case 0:
					flushContent(oldInput, null);
					break;
				case 1:
					setLeftDirty(false);
					setRightDirty(false);
					break;
				case 2:
					throw new ViewerSwitchingCancelled();
				}
			} else {
				flushContent(oldInput, null);
			}
			return true;
		}
		return false;
	}

	/**
	 * Controls whether <code>doSave(Object, Object)</code> asks for confirmation before saving
	 * the old input with <code>saveContent(Object)</code>.
	 * @param enable a value of <code>true</code> enables confirmation
	 * @since 2.0
	 */
	public void setConfirmSave(boolean enable) {
		fConfirmSave= enable;
	}

	@Override
	public void refresh() {
		internalRefresh(getInput());
	}

	private void internalRefresh(Object input) {
		IMergeViewerContentProvider content= getMergeContentProvider();
		if (content != null) {
			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);

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

	@Override
	protected void hookControl(Control control) {
		if (Policy.debugContentMergeViewer) {
			logTrace("Attached dispose listener to control " + System.identityHashCode(control)); //$NON-NLS-1$
		}
		super.hookControl(control);
	}

	//---- layout & SWT control creation

	/**
	 * Builds the SWT controls for the three areas of a compare/merge viewer.
	 * <p>
	 * Calls the hooks <code>createControls</code> and <code>createToolItems</code>
	 * to let subclasses build the specific content areas and to add items to
	 * an enclosing toolbar.
	 * <p>
	 * This method must only be called in the constructor of subclasses.
	 *
	 * @param parent the parent control
	 * @return the new control
	 */
	protected final Control buildControl(Composite parent) {
		fComposite= new Composite(parent, fStyles | SWT.LEFT_TO_RIGHT) { // We force a specific direction
			@Override
			public boolean setFocus() {
				return ContentMergeViewer.this.handleSetFocus();
			}
		};
		fComposite.setData(CompareUI.COMPARE_VIEWER_TITLE, getTitle());

		hookControl(fComposite);	// Hook help & dispose listener.

		fComposite.setLayout(new ContentMergeViewerLayout());
		if (Policy.debugContentMergeViewer) {
			logTrace("Created composite " + System.identityHashCode(fComposite) + " with layout "  //$NON-NLS-1$//$NON-NLS-2$
					+ System.identityHashCode(fComposite.getLayout()));
			logStackTrace();
		}

		int style= SWT.SHADOW_OUT;
		fAncestorLabel= new CLabel(fComposite, style | Window.getDefaultOrientation());

		fLeftLabel= new CLabel(fComposite, style | Window.getDefaultOrientation());
		if (Policy.debugContentMergeViewer) {
			logTrace("fLeftLabel initialized"); //$NON-NLS-1$
			logStackTrace();
		}

		fLeftLabelSet= true;
		new Resizer(fLeftLabel, VERTICAL);

		fDirectionLabel= new CLabel(fComposite, style);
		fDirectionLabel.setAlignment(SWT.CENTER);
		new Resizer(fDirectionLabel, HORIZONTAL | VERTICAL);

		fRightLabel= new CLabel(fComposite, style | Window.getDefaultOrientation());
		new Resizer(fRightLabel, VERTICAL);

		if (fCenter == null || fCenter.isDisposed())
			fCenter= createCenterControl(fComposite);

		createControls(fComposite);

		fHandlerService= CompareHandlerService.createFor(getCompareConfiguration().getContainer(), fComposite.getShell());

		initializeToolbars(parent);

		return fComposite;
	}

	/**
	 * Returns the toolbar manager for this viewer.
	 *
	 * Subclasses may extend this method and use either the toolbar manager
	 * provided by the inherited method by calling
	 * super.getToolBarManager(parent) or provide an alternate toolbar manager.
	 *
	 * @param parent
	 *            a <code>Composite</code> or <code>null</code>
	 * @return a <code>IToolBarManager</code>
	 * @since 3.4
	 */
	protected IToolBarManager getToolBarManager(Composite parent) {
		return CompareViewerPane.getToolBarManager(parent);
	}

	private void initializeToolbars(Composite parent) {
		ToolBarManager tbm = (ToolBarManager) getToolBarManager(parent);
		if (tbm != null) {
			tbm.removeAll();

			// Define groups.
			tbm.add(new Separator("modes"));	//$NON-NLS-1$
			tbm.add(new Separator("merge"));	//$NON-NLS-1$
			tbm.add(new Separator("navigation"));	//$NON-NLS-1$

			copyLeftToRightItem= createCopyAction(true);
			Utilities.initAction(copyLeftToRightItem.getAction(), getResourceBundle(), "action.CopyLeftToRight."); //$NON-NLS-1$
			tbm.appendToGroup("merge", copyLeftToRightItem); //$NON-NLS-1$
			fHandlerService.registerAction(copyLeftToRightItem.getAction(), "org.eclipse.compare.copyAllLeftToRight"); //$NON-NLS-1$

			copyRightToLeftItem= createCopyAction(false);
			Utilities.initAction(copyRightToLeftItem.getAction(), getResourceBundle(), "action.CopyRightToLeft."); //$NON-NLS-1$
			tbm.appendToGroup("merge", copyRightToLeftItem); //$NON-NLS-1$
			fHandlerService.registerAction(copyRightToLeftItem.getAction(), "org.eclipse.compare.copyAllRightToLeft"); //$NON-NLS-1$

			fSwitchLeftAndRight = new Action() {
				@Override
				public void run() {
					IPreferenceStore preferences = getCompareConfiguration().getPreferenceStore();
					preferences.setValue(ComparePreferencePage.SWAPPED, !getCompareConfiguration().isMirrored());
					if (preferences instanceof IPersistentPreferenceStore) {
						try {
							((IPersistentPreferenceStore) preferences).save();
						} catch (IOException e) {
							CompareUIPlugin.log(e);
						}
					}
				}
			};
			Utilities.initAction(fSwitchLeftAndRight, getResourceBundle(), "action.SwitchLeftAndRight."); //$NON-NLS-1$
			tbm.appendToGroup("modes", fSwitchLeftAndRight); //$NON-NLS-1$

			final ChangePropertyAction a= new ChangePropertyAction(fBundle, getCompareConfiguration(), "action.EnableAncestor.", ICompareUIConstants.PROP_ANCESTOR_VISIBLE); //$NON-NLS-1$
			a.setChecked(fAncestorVisible);
			fAncestorItem= new ActionContributionItem(a);
			fAncestorItem.setVisible(false);
			tbm.appendToGroup("modes", fAncestorItem); //$NON-NLS-1$
			tbm.getControl().addDisposeListener(a);

			createToolItems(tbm);
			updateToolItems();

			tbm.update(true);
		}
	}

	private ActionContributionItem createCopyAction(boolean leftToRight) {
		return new ActionContributionItem(new Action() {
			@Override
			public void run() {
				copy(leftToRight);
			}
		});
	}

	/**
	 * Callback that is invoked when the control of this merge viewer is given focus.
	 * This method should return <code>true</code> if a particular widget was given focus
	 * and false otherwise. By default, <code>false</code> is returned. Subclasses may override.
	 * @return whether  particular widget was given focus
	 * @since 3.3
	 */
	protected boolean handleSetFocus() {
		return false;
	}

	/**
	 * Return the desired width of the center control. This width is used
	 * to calculate the values used to layout the ancestor, left and right sides.
	 * @return the desired width of the center control
	 * @see #handleResizeLeftRight(int, int, int, int, int, int)
	 * @see #handleResizeAncestor(int, int, int, int)
	 * @since 3.3
	 */
	protected int getCenterWidth() {
		return 3;
	}

	/**
	 * Return whether the ancestor pane is visible or not.
	 * @return whether the ancestor pane is visible or not
	 * @since 3.3
	 */
	protected boolean isAncestorVisible() {
		return fAncestorVisible;
	}

	/**
	 * Create the control that divides the left and right sides of the merge viewer.
	 * @param parent the parent composite
	 * @return the center control
	 * @since 3.3
	 */
	protected Control createCenterControl(Composite parent) {
		Sash sash= new Sash(parent, SWT.VERTICAL);
		new Resizer(sash, HORIZONTAL);
		return sash;
	}

	/**
	 * Return the center control that divides the left and right sides of the merge viewer.
	 * This method returns the control that was created by calling {@link #createCenterControl(Composite)}.
	 * @see #createCenterControl(Composite)
	 * @return the center control
	 * @since 3.3
	 */
	protected Control getCenterControl() {
		return fCenter;
	}

	@Override
	public Control getControl() {
		return fComposite;
	}

	/**
	 * 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)
	 */
	@Override
	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;
		}

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

		fAncestorLabel= null;
		fLeftLabel= null;
		if (Policy.debugContentMergeViewer) {
			logTrace("handleDispose(...) - fLeftLabel = null. event.widget = " + System.identityHashCode(event.widget)); //$NON-NLS-1$
			logStackTrace();
		}
		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;
		}

		super.handleDispose(event);
	}

	/**
	 * 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();

		Object input= getInput();

		if (copyLeftToRightItem != null) {
			boolean rightEditable = content.isRightEditable(input);
			copyLeftToRightItem.setVisible(rightEditable);
			copyLeftToRightItem.getAction().setEnabled(rightEditable);
		}

		if (copyRightToLeftItem != null) {
			boolean leftEditable = content.isLeftEditable(input);
			copyRightToLeftItem.setVisible(leftEditable);
			copyRightToLeftItem.getAction().setEnabled(leftEditable);
		}

		if (fSwitchLeftAndRight != null) {
			fSwitchLeftAndRight.setChecked(getCompareConfiguration().isMirrored());
		}
	}

	/**
	 * 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();
		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(LegacyActionTools.escapeMnemonics(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(LegacyActionTools.escapeMnemonics(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(LegacyActionTools.escapeMnemonics(rightLabel));
		}
	}

	/**
	 * Calculates the height of the header.
	 */
	/* package */ int getHeaderHeight() {
		int headerHeight= fLeftLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
		headerHeight= Math.max(headerHeight, fDirectionLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y);
		return headerHeight;
	}

	//---- dirty state & saving state

	@Override
	public void addPropertyChangeListener(IPropertyChangeListener listener) {
		if (fListenerList == null)
			fListenerList= new ListenerList<>();
		fListenerList.add(listener);
	}

	@Override
	public void removePropertyChangeListener(IPropertyChangeListener listener) {
		if (fListenerList != null) {
			fListenerList.remove(listener);
			if (fListenerList.isEmpty())
				fListenerList= null;
		}
	}

	private void fireDirtyState(boolean state) {
		Utilities.firePropertyChange(fListenerList, this, CompareEditorInput.DIRTY_STATE, null, Boolean.valueOf(state));
	}

	/**
	 * Sets the dirty state of the left side of this viewer.
	 * If the new value differs from the old
	 * all registered listener are notified with
	 * a <code>PropertyChangeEvent</code> with the
	 * property name <code>CompareEditorInput.DIRTY_STATE</code>.
	 *
	 * @param dirty the state of the left side dirty flag
	 */
	protected void setLeftDirty(boolean dirty) {
		if (isLeftDirty() != dirty) {
			fIsLeftDirty = dirty;
			// Always fire the event if the dirty state has changed
			fireDirtyState(dirty);
		}
	}

	/**
	 * Sets the dirty state of the right side of this viewer.
	 * If the new value differs from the old
	 * all registered listener are notified with
	 * a <code>PropertyChangeEvent</code> with the
	 * property name <code>CompareEditorInput.DIRTY_STATE</code>.
	 *
	 * @param dirty the state of the right side dirty flag
	 */
	protected void setRightDirty(boolean dirty) {
		if (isRightDirty() != dirty) {
			fIsRightDirty = dirty;
			// Always fire the event if the dirty state has changed
			fireDirtyState(dirty);
		}
	}

	/**
	 * Method from the old internal <code>ISavable</code> interface
	 * Save the viewers's content.
	 * Note: this method is for internal use only. Clients should not call this method.
	 *
	 * @param monitor a progress monitor
	 * @throws CoreException
	 * @deprecated use {@link IFlushable#flush(IProgressMonitor)}.
	 */
	@Deprecated
	public void save(IProgressMonitor monitor) throws CoreException {
		flush(monitor);
	}

	/**
	 * Flush any modifications made in the viewer into the compare input. This method
	 * calls {@link #flushContent(Object, IProgressMonitor)} with the compare input
	 * of the viewer as the first parameter.
	 *
	 * @param monitor a progress monitor
	 * @see org.eclipse.compare.contentmergeviewer.IFlushable#flush(org.eclipse.core.runtime.IProgressMonitor)
	 * @since 3.3
	 */
	@Override
	public final void flush(IProgressMonitor monitor) {
		flushContent(getInput(), monitor);
	}

	/**
	 * Flushes 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 flushContent(Object input, IProgressMonitor monitor) {
		flushLeftSide(input, monitor);
		flushRightSide(input, monitor);
	}

	void flushLeftSide(Object input, IProgressMonitor monitor) {
		IMergeViewerContentProvider content = (IMergeViewerContentProvider) getContentProvider();

		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);
		}
	}

	void flushRightSide(Object input, IProgressMonitor monitor) {
		IMergeViewerContentProvider content = (IMergeViewerContentProvider) getContentProvider();

		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);
		}
	}

	/**
	 * @param monitor The progress monitor to report progress.
	 * @noreference This method is not intended to be referenced by clients.
	 */
	@Override
	public void flushLeft(IProgressMonitor monitor) {
		flushLeftSide(getInput(), monitor);
	}

	/**
	 * @param monitor The progress monitor to report progress.
	 * @noreference This method is not intended to be referenced by clients.
	 */
	@Override
	public void flushRight(IProgressMonitor monitor) {
		flushRightSide(getInput(), monitor);
	}

	/**
	 * Return the dirty state of the right side of this viewer.
	 * @return the dirty state of the right side of this viewer
	 * @since 3.3
	 */
	protected boolean isRightDirty() {
		return fIsRightDirty;
	}

	/**
	 * @return the dirty state of the right side of this viewer
	 * @since 3.7
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public boolean internalIsRightDirty() {
		return isRightDirty();
	}

	/**
	 * Return the dirty state of the left side of this viewer.
	 * @return the dirty state of the left side of this viewer
	 * @since 3.3
	 */
	protected boolean isLeftDirty() {
		return fIsLeftDirty;
	}

	/**
	 * @return the dirty state of the left side of this viewer
	 * @since 3.7
	 * @noreference This method is not intended to be referenced by clients.
	 */
	public boolean internalIsLeftDirty() {
		return isLeftDirty();
	}

	/**
	 * Handle a change to the given input reported from an {@link org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener}.
	 * This class registers a listener with its input and reports any change events through
	 * this method. By default, this method prompts for any unsaved changes and then refreshes
	 * the viewer. Subclasses may override.
	 * @since 3.3
	 */
	protected void handleCompareInputChange() {
		// Before setting the new input we have to save the old.
		Object input = getInput();
		if (!isSaving() && (isLeftDirty() || isRightDirty())) {

			if (Utilities.RUNNING_TESTS) {
				if (Utilities.TESTING_FLUSH_ON_COMPARE_INPUT_CHANGE) {
					flushContent(input, null);
				}
			} else {
				// post alert
				Shell shell= fComposite.getShell();

				MessageDialog dialog= new MessageDialog(shell,
					CompareMessages.ContentMergeViewer_resource_changed_title,
					null, 	// accept the default window icon
					CompareMessages.ContentMergeViewer_resource_changed_description,
					MessageDialog.QUESTION,
					new String[] {
						IDialogConstants.YES_LABEL, // 0
						IDialogConstants.NO_LABEL, // 1
					},
					0);		// default button index

				switch (dialog.open()) {	// open returns index of pressed button
				case 0:
					flushContent(input, null);
					break;
				case 1:
					setLeftDirty(false);
					setRightDirty(false);
					break;
				}
			}
		}
		if (isSaving() && (isLeftDirty() || isRightDirty())) {
			return; // Do not refresh until saving both sides is complete.
		}
		refresh();
	}

	CompareHandlerService getCompareHandlerService() {
		return fHandlerService;
	}

	/**
	 * @return true if any of the Saveables is being saved
	 */
	private boolean isSaving() {
		ICompareContainer container = fCompareConfiguration.getContainer();
		ISaveablesSource source = null;
		if (container instanceof ISaveablesSource) {
			source = (ISaveablesSource) container;
		} else {
			IWorkbenchPart part = container.getWorkbenchPart();
			if (part instanceof ISaveablesSource) {
				source = (ISaveablesSource) part;
			}
		}
		if (source != null) {
			Saveable[] saveables = source.getSaveables();
			for (int i = 0; i < saveables.length; i++) {
				if (saveables[i] instanceof ISavingSaveable) {
					ISavingSaveable saveable = (ISavingSaveable) saveables[i];
					if (saveable.isSaving())
						return true;
				}
			}
		}
		return false;
	}

	/**
	 * If the inputs are mirrored, this asks the right model value.
	 *
	 * @return true if the left viewer is editable
	 * @since 3.7
	 */
	protected boolean isLeftEditable() {
		return fCompareConfiguration.isMirrored() ? fCompareConfiguration.isRightEditable() : fCompareConfiguration.isLeftEditable();
	}

	/**
	 * If the inputs are mirrored, this asks the left model value.
	 *
	 * @return true if the right viewer is editable
	 * @since 3.7
	 */
	protected boolean isRightEditable() {
		return fCompareConfiguration.isMirrored() ? fCompareConfiguration.isLeftEditable() : fCompareConfiguration.isRightEditable();
	}
}
