/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * 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.viewers.LabelProviderChangedEvent;
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.DisposeListener;
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>
 * <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>
 * 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.
 *
 * @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(
				new DisposeListener() {
					@Override
					public void widgetDisposed(DisposeEvent 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 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;
	Cursor fNormalCursor;
	private Cursor fHSashCursor;
	private Cursor fVSashCursor;
	private Cursor fHVSashCursor;

	private ILabelProviderListener labelChangeListener = new ILabelProviderListener() {
		@Override
		public void labelProviderChanged(LabelProviderChangedEvent 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);

		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 new ISelection() {
			@Override
			public boolean isEmpty() {
				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;
		}

		if (key.equals(ComparePreferencePage.SWAPPED)) {
			getCompareConfiguration().setProperty(CompareConfiguration.MIRRORED, event.getNewValue());
			updateContentProvider();
			updateToolItems();
			return;
		}
	}

	void updateCursor(Control c, int dir) {
		if (!(c instanceof Sash)) {
			Cursor cursor= null;
			switch (dir) {
			case VERTICAL:
				if (fAncestorVisible) {
					if (fVSashCursor == null)
						fVSashCursor= new Cursor(c.getDisplay(), SWT.CURSOR_SIZENS);
					cursor= fVSashCursor;
				} else {
					if (fNormalCursor == null)
						fNormalCursor= new Cursor(c.getDisplay(), SWT.CURSOR_ARROW);
					cursor= fNormalCursor;
				}
				break;
			case HORIZONTAL:
				if (fHSashCursor == null)
					fHSashCursor= new Cursor(c.getDisplay(), SWT.CURSOR_SIZEWE);
				cursor= fHSashCursor;
				break;
			case VERTICAL + HORIZONTAL:
				if (fAncestorVisible) {
					if (fHVSashCursor == null)
						fHVSashCursor= new Cursor(c.getDisplay(), SWT.CURSOR_SIZEALL);
					cursor= fHVSashCursor;
				} else {
					if (fHSashCursor == null)
						fHSashCursor= new Cursor(c.getDisplay(), 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;
		}

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

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

	/**
	 * 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
	 * @noreference This method is not intended to be referenced by clients.
	 */
	@Override
	public void flushLeft(IProgressMonitor monitor) {
		flushLeftSide(getInput(), monitor);
	}

	/**
	 * @param monitor
	 * @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();
	}
}
