/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *******************************************************************************/
package org.eclipse.compare;

import java.lang.reflect.InvocationTargetException;
import java.util.ResourceBundle;

import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
import org.eclipse.compare.contentmergeviewer.IFlushable;
import org.eclipse.compare.internal.BinaryCompareViewer;
import org.eclipse.compare.internal.ChangePropertyAction;
import org.eclipse.compare.internal.CompareContentViewerSwitchingPane;
import org.eclipse.compare.internal.CompareEditorInputNavigator;
import org.eclipse.compare.internal.CompareMessages;
import org.eclipse.compare.internal.ComparePreferencePage;
import org.eclipse.compare.internal.CompareStructureViewerSwitchingPane;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.compare.internal.ICompareUIConstants;
import org.eclipse.compare.internal.IFlushable2;
import org.eclipse.compare.internal.OutlineViewerCreator;
import org.eclipse.compare.internal.Utilities;
import org.eclipse.compare.internal.ViewerDescriptor;
import org.eclipse.compare.structuremergeviewer.DiffTreeViewer;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener;
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IFindReplaceTarget;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.services.IServiceLocator;
import org.eclipse.ui.texteditor.ITextEditorExtension3;

/**
 * A compare operation which can present its results in a special editor.
 * Running the compare operation and presenting the results in a compare editor
 * are combined in one class because it allows a client to keep the implementation
 * all in one place while separating it from the innards of a specific UI implementation of compare/merge.
 * <p>
 * A <code>CompareEditorInput</code> defines methods for the following sequence steps:
 * <UL>
 * <LI>running a lengthy compare operation under progress monitor control,
 * <LI>creating a UI for displaying the model and initializing the some widgets with the compare result,
 * <LI>tracking the dirty state of the model in case of merge,
 * <LI>saving the model.
 * </UL>
 * The Compare plug-in's <code>openCompareEditor</code> method takes an <code>CompareEditorInput</code>
 * and starts sequencing through the above steps. If the compare result is not empty a new compare editor
 * is opened and takes over the sequence until eventually closed.
 * <p>
 * The <code>prepareInput</code> method should contain the
 * code of the compare operation. It is executed under control of a progress monitor
 * and can be canceled. If the result of the compare is not empty, that is if there are differences
 * that needs to be presented, the <code>ICompareInput</code> should hold onto them and return them with
 * the <code>getCompareResult</code> method.
 * If the value returned from <code>getCompareResult</code> is not <code>null</code>
 * a compare editor is opened on the <code>ICompareInput</code> with title and title image initialized by the
 * corresponding methods of the <code>ICompareInput</code>.
 * <p>
 * Creation of the editor's SWT controls is delegated to the <code>createContents</code> method.
 * Here the SWT controls must be created and initialized  with the result of the compare operation.
 * <p>
 * If merging is allowed, the modification state of the compared constituents must be tracked and the dirty
 * state returned from method <code>isSaveNeeded</code>. The value <code>true</code> triggers a subsequent call
 * to <code>save</code> where the modified resources can be saved.
 * <p>
 * The most important part of this implementation is the setup of the compare/merge UI.
 * The UI uses a simple browser metaphor to present compare results.
 * The top half of the layout shows the structural compare results (e.g. added, deleted, and changed files),
 * the bottom half the content compare results (e.g. textual differences between two files).
 * A selection in the top pane is fed to the bottom pane. If a content viewer is registered
 * for the type of the selected object, this viewer is installed in the pane.
 * In addition if a structure viewer is registered for the selection type the top pane
 * is split vertically to make room for another pane and the structure viewer is installed
 * in it. When comparing Java files this second structure viewer would show the structural
 * differences within a Java file, e.g. added, deleted or changed methods and fields.
 * <p>
 * Subclasses provide custom setups, e.g. for a Catch-up/Release operation
 * by passing a subclass of <code>CompareConfiguration</code> and by implementing the <code>prepareInput</code> method.
 * If a subclass cannot use the <code>DiffTreeViewer</code> which is installed by default in the
 * top left pane, method <code>createDiffViewer</code> can be overridden.
 * <p>
 * If subclasses of this class implement {@link ISaveablesSource}, the compare editor will
 * pass these models through to the workbench. The editor will still show the dirty indicator
 * if one of these underlying models is dirty. It is the responsibility of subclasses that
 * implement this interface to call {@link #setDirty(boolean)} when the dirty state of
 * any of the models managed by the subclass change dirty state.
 *
 * @see CompareUI
 * @see CompareEditorInput
 */
public abstract class CompareEditorInput extends PlatformObject implements IEditorInput, IPropertyChangeNotifier, IRunnableWithProgress, ICompareContainer {
	private static final boolean DEBUG= false;

	/**
	 * The name of the "dirty" property (value <code>"DIRTY_STATE"</code>).
	 */
	public static final String DIRTY_STATE= "DIRTY_STATE"; //$NON-NLS-1$

	/**
	 * The name of the "title" property. This property is fired when the title
	 * of the compare input changes. Clients should also re-obtain the tool tip
	 * when this property changes.
	 * @see #getTitle()
	 * @since 3.3
	 */
	public static final String PROP_TITLE= ICompareUIConstants.PROP_TITLE;

	/**
	 * The name of the "title image" property. This property is fired when the title
	 * image of the compare input changes.
	 * @see #getTitleImage()
	 * @since 3.3
	 */
	public static final String PROP_TITLE_IMAGE= ICompareUIConstants.PROP_TITLE_IMAGE;

	/**
	 * The name of the "selected edition" property. This property is fired when the selected
	 * edition of the compare input changes.
	 * @see #isEditionSelectionDialog()
	 * @see #getSelectedEdition()
	 * @since 3.3
	 */
	public static final String PROP_SELECTED_EDITION= ICompareUIConstants.PROP_SELECTED_EDITION;

	private static final String COMPARE_EDITOR_IMAGE_NAME= "eview16/compare_view.png"; //$NON-NLS-1$
	private static Image fgTitleImage;

	private Splitter fComposite;
	private CompareConfiguration fCompareConfiguration;
	private CompareViewerPane fStructureInputPane;
	private CompareViewerSwitchingPane fStructurePane1;
	private CompareViewerSwitchingPane fStructurePane2;
	private CompareViewerSwitchingPane fContentInputPane;
	private CompareViewerPane fFocusPane;
	private String fMessage;
	private Object fInput;
	private String fTitle;
	private ListenerList<IPropertyChangeListener> fListenerList= new ListenerList<>();
	private CompareNavigator fNavigator;
	private boolean fLeftDirty;
	private boolean fRightDirty;
	private IPropertyChangeListener fDirtyStateListener;

	boolean fStructureCompareOnSingleClick= true;

	private ICompareContainer fContainer;
	private boolean fContainerProvided;
	private String fHelpContextId;
	private InternalOutlineViewerCreator fOutlineView;
	private ViewerDescriptor fContentViewerDescriptor;
	private ViewerDescriptor fStructureViewerDescriptor;

	private class InternalOutlineViewerCreator extends OutlineViewerCreator {
		private OutlineViewerCreator getWrappedCreator() {
			if (fContentInputPane != null) {
				Viewer v = fContentInputPane.getViewer();
				if (v != null) {
					return Adapters.adapt(v, OutlineViewerCreator.class);
				}
			}
			return null;
		}

		@Override
		public Viewer findStructureViewer(Viewer oldViewer,	ICompareInput input, Composite parent,
				CompareConfiguration configuration) {
			OutlineViewerCreator creator = getWrappedCreator();
			if (creator != null)
				return creator.findStructureViewer(oldViewer, input, parent, configuration);
			return null;
		}

		@Override
		public boolean hasViewerFor(Object input) {
			OutlineViewerCreator creator = getWrappedCreator();
			return creator != null;
		}

		@Override
		public Object getInput() {
			OutlineViewerCreator creator = getWrappedCreator();
			if (creator != null)
				return creator.getInput();
			return null;
		}
	}

	/**
	 * Creates a <code>CompareEditorInput</code> which is initialized with the given
	 * compare configuration.
	 * The compare configuration is passed to subsequently created viewers.
	 *
	 * @param configuration the compare configuration
	 */
	public CompareEditorInput(CompareConfiguration configuration) {
		fCompareConfiguration= configuration;
		Assert.isNotNull(configuration);

		fDirtyStateListener= e -> {
			String propertyName= e.getProperty();
			if (CompareEditorInput.DIRTY_STATE.equals(propertyName)) {
				boolean changed= false;
				Object newValue= e.getNewValue();
				if (newValue instanceof Boolean)
					changed= ((Boolean) newValue).booleanValue();
				setDirty(e.getSource(), changed);
			}
		};

		IPreferenceStore ps= configuration.getPreferenceStore();
		if (ps != null)
			fStructureCompareOnSingleClick= ps.getBoolean(ComparePreferencePage.OPEN_STRUCTURE_COMPARE);

		fContainer = configuration.getContainer();
		configuration.setContainer(this);
	}

	private boolean structureCompareOnSingleClick() {
		return fStructureCompareOnSingleClick;
	}

	private boolean isShowStructureInOutlineView() {
		Object object= getCompareConfiguration().getProperty(CompareConfiguration.USE_OUTLINE_VIEW);
		return object instanceof Boolean && ((Boolean)object).booleanValue();
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(Class<T> adapter) {
		if (ICompareNavigator.class.equals(adapter) || CompareNavigator.class.equals(adapter)) {
			return (T) getNavigator();
		}
		if (adapter == IShowInSource.class) {
			final IFile file = Adapters.adapt(this, IFile.class);
			if (file != null)
				return (T) (IShowInSource) () -> new ShowInContext(new FileEditorInput(file), StructuredSelection.EMPTY);
		}
		if (adapter == OutlineViewerCreator.class) {
			synchronized (this) {
				if (fOutlineView == null)
					fOutlineView = new InternalOutlineViewerCreator();
				return (T) fOutlineView;
			}
		}
		if (adapter == IFindReplaceTarget.class) {
			if (fContentInputPane != null) {
				Viewer v = fContentInputPane.getViewer();
				if (v != null) {
					return (T) Adapters.adapt(v, IFindReplaceTarget.class);
				}
			}
		}
		if (adapter == IEditorInput.class) {
			if (fContentInputPane != null) {
				Viewer v = fContentInputPane.getViewer();
				if (v != null) {
					return (T) Adapters.adapt(v, IEditorInput.class);
				}
			}
		}

		if (adapter == ITextEditorExtension3.class) {
			if (fContentInputPane != null) {
				Viewer v = fContentInputPane.getViewer();
				if (v != null) {
					return (T) Adapters.adapt(v, ITextEditorExtension3.class);
				}
			}
		}

		return super.getAdapter(adapter);
	}

	@Override
	public synchronized ICompareNavigator getNavigator() {
		if (fNavigator == null)
			fNavigator= new CompareEditorInputNavigator(
				new Object[] {
					fStructureInputPane,
					fStructurePane1,
					fStructurePane2,
					fContentInputPane
				}
			);
		return fNavigator;
	}

	@Override
	public ImageDescriptor getImageDescriptor() {
		return null;
	}

	@Override
	public String getToolTipText() {
		return getTitle();
	}

	@Override
	public String getName() {
		return getTitle();
	}

	/**
	 * Returns <code>null</code> since this editor cannot be persisted.
	 *
	 * @return <code>null</code> because this editor cannot be persisted
	 */
	@Override
	public IPersistableElement getPersistable() {
		return null;
	}

	/**
	 * Returns <code>false</code> to indicate that this input
	 * should not appear in the "File Most Recently Used" menu.
	 *
	 * @return <code>false</code>
	 */
	@Override
	public boolean exists() {
		return false;
	}

	/*
	 * FIXME!
	 */
	protected void setMessage(String message) {
		fMessage= message;
	}

	/*
	 * FIXME!
	 */
	public String getMessage() {
		return fMessage;
	}

	/**
	 * Returns the title which will be used in the compare editor's title bar.
	 * It can be set with <code>setTitle</code>.
	 *
	 * @return the title
	 */
	public String getTitle() {
		if (fTitle == null)
			return Utilities.getString("CompareEditorInput.defaultTitle"); //$NON-NLS-1$
		return fTitle;
	}

	/**
	 * Sets the title which will be used when presenting the compare result.
	 * This method must be called before the editor is opened.
	 *
	 * @param title the title to use for the CompareEditor
	 */
	public void setTitle(String title) {
		String oldTitle = fTitle;
		fTitle= title;
		Utilities.firePropertyChange(fListenerList, this, PROP_TITLE, oldTitle, title);
	}

	/**
	 * Returns the title image which will be used in the compare editor's title bar.
	 * Returns the title image which will be used when presenting the compare result.
	 * This implementation returns a generic compare icon.
	 * Subclasses can override.
	 *
	 * @return the title image, or <code>null</code> if none
	 */
	public Image getTitleImage() {
		if (fgTitleImage == null) {
			fgTitleImage= CompareUIPlugin.getImageDescriptor(COMPARE_EDITOR_IMAGE_NAME).createImage();
			CompareUI.disposeOnShutdown(fgTitleImage);
		}
		return fgTitleImage;
	}

	/**
	 * Returns the configuration object for the viewers within the compare editor.
	 * Returns the configuration which was passed to the constructor.
	 *
	 * @return the compare configuration
	 */
	public CompareConfiguration getCompareConfiguration() {
		return fCompareConfiguration;
	}

	/**
	 * Adds standard actions to the given <code>ToolBarManager</code>.
	 * <p>
	 * Subclasses may override to add their own actions.
	 * </p>
	 *
	 * @param toolBarManager the <code>ToolBarManager</code> to which to contribute
	 */
	public void contributeToToolBar(ToolBarManager toolBarManager) {
		ResourceBundle bundle= CompareUI.getResourceBundle();
		ChangePropertyAction ignoreWhitespace= ChangePropertyAction.createIgnoreWhiteSpaceAction(bundle, getCompareConfiguration());
		toolBarManager.getControl().addDisposeListener(ignoreWhitespace);
		ChangePropertyAction showPseudoConflicts= ChangePropertyAction.createShowPseudoConflictsAction(bundle, getCompareConfiguration());
		toolBarManager.getControl().addDisposeListener(showPseudoConflicts);
		toolBarManager.add(new Separator());
		toolBarManager.add(ignoreWhitespace);
		toolBarManager.add(showPseudoConflicts);
	}

	/**
	 * Runs the compare operation and stores the compare result.
	 *
	 * @param monitor the progress monitor to use to display progress and receive
	 *     requests for cancellation
	 * @throws InvocationTargetException if the <code>prepareInput</code> method must propagate a checked exception,
	 * 	   it should wrap it inside an <code>InvocationTargetException</code>; runtime exceptions are automatically
	 *     wrapped in an <code>InvocationTargetException</code> by the calling context
	 * @throws InterruptedException if the operation detects a request to cancel,
	 *     using <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing
	 *     <code>InterruptedException</code>
	 */
	@Override
	public void run(IProgressMonitor monitor) throws InterruptedException, InvocationTargetException {
		fInput= prepareInput(monitor);
	}

	/**
	 * Runs the compare operation and returns the compare result.
	 * If <code>null</code> is returned no differences were found and no compare editor needs to be opened.
	 * Progress should be reported to the given progress monitor.
	 * A request to cancel the operation should be honored and acknowledged
	 * by throwing <code>InterruptedException</code>.
	 * <p>
	 * Note: this method is typically called in a modal context thread which doesn't have a Display assigned.
	 * Implementors of this method shouldn't therefore allocated any SWT resources in this method.
	 * </p>
	 *
	 * @param monitor the progress monitor to use to display progress and receive
	 *   requests for cancellation
	 * @return the result of the compare operation, or <code>null</code> if there are no differences
	 * @exception InvocationTargetException if the <code>prepareInput</code> method must propagate a checked exception,
	 * 	it should wrap it inside an <code>InvocationTargetException</code>; runtime exceptions are automatically
	 *  wrapped in an <code>InvocationTargetException</code> by the calling context
	 * @exception InterruptedException if the operation detects a request to cancel,
	 *  using <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing
	 *  <code>InterruptedException</code>
	 */
	protected abstract Object prepareInput(IProgressMonitor monitor)
				throws InvocationTargetException, InterruptedException;

	/**
	 * Returns the compare result computed by the most recent call to the
	 * <code>run</code> method. Returns <code>null</code> if no
	 * differences were found.
	 *
	 * @return the compare result prepared in method <code>prepareInput</code>
	 *     or <code>null</code> if there were no differences
	 */
	public Object getCompareResult() {
		return fInput;
	}

	/**
	 * Creates the SWT controls that are used to display the result of the compare operation.
	 * Creates the SWT Controls and sets up the wiring between the individual panes.
	 * This implementation creates all four panes but makes only the necessary ones visible.
	 * Finally it feeds the compare result into the top left structure viewer
	 * and the content viewer.
	 * <p>
	 * Subclasses may override if they need to change the layout or wiring between panes.
	 *
	 * @param parent the parent control under which the control must be created
	 * @return the SWT control hierarchy for the compare editor
	 */
	public Control createContents(Composite parent) {
		fComposite= new Splitter(parent, SWT.VERTICAL);
		fComposite.setData(this);

		Control outline= createOutlineContents(fComposite, SWT.HORIZONTAL);

		fContentInputPane= createContentViewerSwitchingPane(fComposite, SWT.BORDER | SWT.FLAT, this);

		if (fFocusPane == null)
			fFocusPane= fContentInputPane;
		if (outline != null)
			fComposite.setVisible(outline, false);
		fComposite.setVisible(fContentInputPane, true);

		if (fStructureInputPane != null && fComposite.getChildren().length == 2)
			fComposite.setWeights(new int[] { 30, 70 });

		feedInput();
		parent.requestLayout();
		fComposite.addDisposeListener(e -> {
			/*
			 * When the UI associated with this compare editor input is
			 * disposed each composite being part of the UI releases its
			 * children first. A dispose listener is added to the last
			 * widget found in that structure. Therefore, compare editor
			 * input is disposed at the end making it possible to refer
			 * during widgets disposal.
			 */
			Composite composite = (Composite) e.widget;
			Control control = composite;
			while (composite.getChildren().length > 0) {
				control = composite.getChildren()[composite.getChildren().length - 1];
				if (control instanceof Composite) {
					composite = (Composite) control;
				} else {
					break;
				}
			}
			control.addDisposeListener(ev -> handleDispose());
		});
		if (fHelpContextId != null)
			PlatformUI.getWorkbench().getHelpSystem().setHelp(fComposite, fHelpContextId);
		contentsCreated();
		return fComposite;
	}

	/**
	 * @param parent the parent control under which the control must be created
	 * @param style  the style of widget to construct
	 * @param cei the compare editor input for the viewer
	 * @return the pane displaying content changes
	 * @nooverride This method is not intended to be re-implemented or extended by clients.
	 * @noreference This method is not intended to be referenced by clients.
	 */
	protected CompareViewerSwitchingPane createContentViewerSwitchingPane(Splitter parent, int style, CompareEditorInput cei) {
		return new CompareContentViewerSwitchingPane(parent, style, cei);
	}

	/**
	 * Callback that occurs when the UI associated with this compare editor
	 * input is disposed. This method will only be invoked if the UI has been
	 * created (i.e. after the call to {@link #createContents(Composite)}.
	 * Subclasses can extend this method but ensure that the overridden method
	 * is invoked.
	 *
	 * @since 3.3
	 */
	protected void handleDispose() {
		fContainerProvided = false;
		fContainer = null;
		fComposite = null;
		fStructureInputPane = null;
		fStructurePane1 = null;
		fStructurePane2 = null;
		fContentInputPane = null;
		fFocusPane = null;
		fNavigator = null;
		fCompareConfiguration.dispose();
	}

	/**
	 * Callback that occurs after the control for the input has
	 * been created. If this method gets invoked then {@link #handleDispose()}
	 * will be invoked when the control is disposed. Subclasses may extend this
	 * method to register any listeners that need to be de-registered when the
	 * input is disposed.
	 * @since 3.3
	 */
	protected void contentsCreated() {
		// Default is to do nothing
	}

	/**
	 * @param parent    the parent control under which the control must be created
	 * @param direction the layout direction of the contents, either
	 *                  <code>SWT.HORIZONTAL</code> or <code>SWT.VERTICAL</code>
	 * @return the SWT control hierarchy for the outline part of the compare editor
	 * @since 3.0
	 */
	public Control createOutlineContents(Composite parent, int direction) {
		final Splitter h= new Splitter(parent, direction);

		fStructureInputPane= createStructureInputPane(h);
		if (hasChildren(getCompareResult()))
			fFocusPane= fStructureInputPane;

		fStructurePane1= new CompareStructureViewerSwitchingPane(h, SWT.BORDER | SWT.FLAT, true, this);
		h.setVisible(fStructurePane1, false);

		fStructurePane2= new CompareStructureViewerSwitchingPane(h, SWT.BORDER | SWT.FLAT, true, this);
		h.setVisible(fStructurePane2, false);

		// setup the wiring for top left pane
		fStructureInputPane.addOpenListener(
			oe -> feed1(oe.getSelection())
		);
		fStructureInputPane.addSelectionChangedListener(
			new ISelectionChangedListener() {
				@Override
				public void selectionChanged(SelectionChangedEvent e) {
					ISelection s= e.getSelection();
					if (s == null || s.isEmpty())
						feed1(s);
					if (isEditionSelectionDialog())
						firePropertyChange(new PropertyChangeEvent(this, PROP_SELECTED_EDITION, null, getSelectedEdition()));
				}
			}
		);
		fStructureInputPane.addDoubleClickListener(
			event -> feedDefault1(event.getSelection())
		);

		fStructurePane1.addSelectionChangedListener(
			e -> feed2(e.getSelection())
		);

		fStructurePane2.addSelectionChangedListener(
			e -> feed3(e.getSelection())
		);

		return h;
	}

	/**
	 * Create the pane that will contain the structure input pane (upper left).
	 * By default, a {@link CompareViewerSwitchingPane} is returned. Subclasses
	 * may override to provide an alternate pane.
	 * @param parent the parent composite
	 * @return the structure input pane
	 * @since 3.3
	 */
	protected CompareViewerPane createStructureInputPane(final Composite parent) {
		return new CompareStructureViewerSwitchingPane(parent, SWT.BORDER | SWT.FLAT, true, this) {
			@Override
			protected Viewer getViewer(Viewer oldViewer, Object input) {
				if (CompareEditorInput.this.hasChildren(input)) {
					return createDiffViewer(this);
				}
				return super.getViewer(oldViewer, input);
			}
		};
	}

	boolean hasChildren(Object input) {
		if (input instanceof IDiffContainer) {
			IDiffContainer dn= (IDiffContainer) input;
			return dn.hasChildren();
		}
		return false;
	}

	private void feedInput() {
		if (fStructureInputPane != null
				&& (fInput instanceof ICompareInput
						|| isCustomStructureInputPane())) {
			if (hasChildren(fInput) || isCustomStructureInputPane()) {
				// The input has multiple entries so set the input of the structure input pane
				fStructureInputPane.setInput(fInput);
			} else if (!structureCompareOnSingleClick() || isShowStructureInOutlineView()) {
				// We want to avoid showing the structure in the editor if we can so first
				// we'll set the content pane to see if we need to provide a structure
				internalSetContentPaneInput(fInput);
				// If the content viewer is unusable
				if (hasUnusableContentViewer()
						|| (structureCompareOnSingleClick()
								&& isShowStructureInOutlineView()
								&& !hasOutlineViewer(fInput))) {
					fStructureInputPane.setInput(fInput);
				}
			} else {
				fStructureInputPane.setInput(fInput);
			}
			ISelection sel= fStructureInputPane.getSelection();
			if (sel == null || sel.isEmpty())
				feed1(sel);	// we only feed downstream viewers if the top left pane is empty
		}
	}

	private boolean hasOutlineViewer(Object input) {
		if (!isShowStructureInOutlineView())
			return false;
		OutlineViewerCreator creator = getAdapter(OutlineViewerCreator.class);
		if (creator != null)
			return creator.hasViewerFor(input);
		return false;
	}

	private boolean hasUnusableContentViewer() {
		return fContentInputPane.isEmpty() || fContentInputPane.getViewer() instanceof BinaryCompareViewer;
	}

	private boolean isCustomStructureInputPane() {
		return !(fStructureInputPane instanceof CompareViewerSwitchingPane);
	}

	private void feed1(final ISelection selection) {
		BusyIndicator.showWhile(fComposite.getDisplay(),
			() -> {
				if (selection == null || selection.isEmpty()) {
					Object input1= fStructureInputPane.getInput();
					if (input1 != null)
						internalSetContentPaneInput(input1);
					if (!Utilities.okToUse(fStructurePane1) || !Utilities.okToUse(fStructurePane2))
						return;
					fStructurePane2.setInput(null); // clear downstream pane
					fStructurePane1.setInput(null);
				} else {
					Object input2= getElement(selection);
					internalSetContentPaneInput(input2);
					if (!Utilities.okToUse(fStructurePane1) || !Utilities.okToUse(fStructurePane2))
						return;
					if (structureCompareOnSingleClick() || hasUnusableContentViewer())
						fStructurePane1.setInput(input2);
					fStructurePane2.setInput(null); // clear downstream pane
					if (fStructurePane1.getInput() != input2)
						fStructurePane1.setInput(null);
				}
			}
		);
	}

	private void feedDefault1(final ISelection selection) {
		BusyIndicator.showWhile(fComposite.getDisplay(),
			() -> {
				if (!selection.isEmpty())
					fStructurePane1.setInput(getElement(selection));
			}
		);
	}

	private void feed2(final ISelection selection) {
		BusyIndicator.showWhile(fComposite.getDisplay(),
			() -> {
				if (selection.isEmpty()) {
					Object input1= fStructurePane1.getInput();
					internalSetContentPaneInput(input1);
					fStructurePane2.setInput(null);
				} else {
					Object input2= getElement(selection);
					internalSetContentPaneInput(input2);
					fStructurePane2.setInput(input2);
				}
			}
		);
	}

	private void feed3(final ISelection selection) {
		BusyIndicator.showWhile(fComposite.getDisplay(),
			() -> {
				if (selection.isEmpty())
					internalSetContentPaneInput(fStructurePane2.getInput());
				else
					internalSetContentPaneInput(getElement(selection));
			}
		);

	}

	private void internalSetContentPaneInput(Object input) {
		Object oldInput = fContentInputPane.getInput();
		fContentInputPane.setInput(input);
		if (fOutlineView != null)
			fOutlineView.fireInputChange(oldInput, input);
	}

	/**
	 * Returns the first element of the given selection if the selection
	 * is a <code>IStructuredSelection</code> with exactly one element. Returns
	 * <code>null</code> otherwise.
	 *
	 * @param selection the selection
	 * @return the first element of the selection, or <code>null</code>
	 */
	private static Object getElement(ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			IStructuredSelection ss= (IStructuredSelection) selection;
			if (ss.size() == 1)
				return ss.getFirstElement();
		}
		return null;
	}

	/**
	 * Asks this input to take focus within its container (editor).
	 *
	 * @noreference Clients should not call this method but they may override if
	 *              they implement a different layout with different visual
	 *              components. Clients are free to call the inherited method.
	 *
	 * @deprecated Please use {@link #setFocus2()} instead.
	 */
	@Deprecated
	public void setFocus() {
		setFocus2();
	}

	/**
	 * Asks this input to take focus within its container (editor).
	 *
	 * @noreference Clients should not call this method but they may override if
	 *              they implement a different layout with different visual
	 *              components. Clients are free to call the inherited method.
	 *
	 * @return <code>true</code> if the input got focus, and <code>false</code>
	 *         if it was unable to.
	 * @since 3.5
	 */
	public boolean setFocus2() {
		if (fFocusPane != null) {
			return fFocusPane.setFocus();
		} else if (fComposite != null)
			return fComposite.setFocus();
		return false;
	}

	/**
	 * Factory method for creating a differences viewer for the top left pane.
	 * It is called from <code>createContents</code> and returns a <code>DiffTreeViewer</code>.
	 * <p>
	 * Subclasses may override if they need a different viewer.
	 * </p>
	 *
	 * @param parent the SWT parent control under which to create the viewer's SWT controls
	 * @return a compare viewer for the top left pane
	 */
	public Viewer createDiffViewer(Composite parent) {
		return new DiffTreeViewer(parent, fCompareConfiguration);
	}

	/**
	 * Implements the dynamic viewer switching for structure viewers.
	 * The method must return a compare viewer based on the old (or current) viewer
	 * and a new input object. If the old viewer is suitable for showing the new input the old viewer
	 * can be returned. Otherwise a new viewer must be created under the given parent composite or
	 * <code>null</code> can be returned to indicate that no viewer could be found.
	 * <p>
	 * This implementation forwards the request to <code>CompareUI.findStructureViewer</code>.
	 * <p>
	 * Subclasses may override to implement a different strategy.
	 * </p>
	 * @param oldViewer a new viewer is only created if this old viewer cannot show the given input
	 * @param input the input object for which to find a structure viewer
	 * @param parent the SWT parent composite under which the new viewer is created
	 * @return a compare viewer which is suitable for the given input object or <code>null</code>
	 */
	public Viewer findStructureViewer(Viewer oldViewer, ICompareInput input, Composite parent) {
		return fStructureViewerDescriptor != null ? fStructureViewerDescriptor.createViewer(oldViewer, parent,
				fCompareConfiguration) : CompareUI.findStructureViewer(oldViewer,
				input, parent, fCompareConfiguration);
	}

	/**
	 * Implements the dynamic viewer switching for content viewers.
	 * The method must return a compare viewer based on the old (or current) viewer
	 * and a new input object. If the old viewer is suitable for showing the new input the old viewer
	 * can be returned. Otherwise a new viewer must be created under the given parent composite or
	 * <code>null</code> can be returned to indicate that no viewer could be found.
	 * <p>
	 * This implementation forwards the request to <code>CompareUI.findContentViewer</code>.
	 * <p>
	 * Subclasses may override to implement a different strategy.
	 * </p>
	 * @param oldViewer a new viewer is only created if this old viewer cannot show the given input
	 * @param input the input object for which to find a structure viewer
	 * @param parent the SWT parent composite under which the new viewer is created
	 * @return a compare viewer which is suitable for the given input object or <code>null</code>
	 */
	public Viewer findContentViewer(Viewer oldViewer, ICompareInput input, Composite parent) {

		Viewer newViewer = fContentViewerDescriptor != null ? fContentViewerDescriptor.createViewer(oldViewer, parent,
				fCompareConfiguration) : CompareUI.findContentViewer(oldViewer,
				input, parent, fCompareConfiguration);

		boolean isNewViewer= newViewer != oldViewer;
		if (DEBUG) System.out.println("CompareEditorInput.findContentViewer: " + isNewViewer); //$NON-NLS-1$

		if (isNewViewer && newViewer instanceof IPropertyChangeNotifier) {
			final IPropertyChangeNotifier dsp= (IPropertyChangeNotifier) newViewer;
			dsp.addPropertyChangeListener(fDirtyStateListener);

			Control c= newViewer.getControl();
			c.addDisposeListener(
				e -> dsp.removePropertyChangeListener(fDirtyStateListener)
			);
		}

		return newViewer;
	}

	/**
	 * @param vd
	 *            the content viewer descriptor
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended
	 *             by clients.
	 */
	public void setContentViewerDescriptor(ViewerDescriptor vd) {
		this.fContentViewerDescriptor = vd;
	}

	/**
	 * @return the content viewer descriptor set for the input
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended
	 *             by clients.
	 */
	public ViewerDescriptor getContentViewerDescriptor() {
		return this.fContentViewerDescriptor;
	}

	/**
	 * @param vd
	 *            the structure viewer descriptor
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended
	 *             by clients.
	 */
	public void setStructureViewerDescriptor(ViewerDescriptor vd) {
		this.fStructureViewerDescriptor = vd;
	}

	/**
	 * @return the structure viewer descriptor set for the input
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended
	 *             by clients.
	 */
	public ViewerDescriptor getStructureViewerDescriptor() {
		return this.fStructureViewerDescriptor;
	}

	/**
	 * Returns <code>true</code> if there are unsaved changes in either left or
	 * right side. The value returned is the value of the
	 * <code>DIRTY_STATE</code> property of this input object.
	 *
	 * Returns <code>true</code> if left or right side has unsaved changes
	 * Subclasses don't have to override if the functionality provided by
	 * <code>setDirty</code> is sufficient.
	 *
	 * @return <code>true</code> if there are changes that need to be saved
	 */
	public boolean isSaveNeeded() {
		return isLeftSaveNeeded() || isRightSaveNeeded();
	}

	/**
	 * Returns <code>true</code> if there are unsaved changes for left side.
	 *
	 * @return <code>true</code> if there are changes that need to be saved
	 * @noreference This method is not intended to be referenced by clients.
	 */
	protected boolean isLeftSaveNeeded() {
		return fLeftDirty;
	}

	/**
	 * Returns <code>true</code> if there are unsaved changes for right side.
	 *
	 * @return <code>true</code> if there are changes that need to be saved
	 * @noreference This method is not intended to be referenced by clients.
	 */
	protected boolean isRightSaveNeeded() {
		return fRightDirty;
	}

	/**
	 * Returns <code>true</code> if there are unsaved changes.
	 * The method should be called by any parts or dialogs
	 * that contain the input.
	 * By default, this method calls {@link #isSaveNeeded()}
	 * but subclasses may extend.
	 * @return <code>true</code> if there are unsaved changes
	 * @since 3.3
	 */
	public boolean isDirty() {
		return isSaveNeeded();
	}

	/**
	 * Sets the dirty state of this input to the given value and sends out a
	 * <code>PropertyChangeEvent</code> if the new value differs from the old
	 * value. Direct calling this method with parameter dirty equal to
	 * <code>false</code> when there are unsaved changes in viewers, results in
	 * inconsistent state. The dirty state of compare input should be based only
	 * on the information if there are changes in viewers for left or right
	 * side.
	 *
	 * @param dirty
	 *            the dirty state for this compare input
	 */
	public void setDirty(boolean dirty) {
		boolean oldDirty = isSaveNeeded();
		fLeftDirty = dirty;
		fRightDirty = dirty;

		if (oldDirty != isSaveNeeded()) {
			Utilities.firePropertyChange(fListenerList, this, DIRTY_STATE, Boolean.valueOf(oldDirty), Boolean.valueOf(isSaveNeeded()));
		}
	}

	/**
	 * Sets the dirty state of left site of this input to the given value and
	 * sends out a <code>PropertyChangeEvent</code> if the new value for whole
	 * input differs from the old value. Direct calling this method with
	 * parameter dirty equal to <code>false</code> when there are unsaved
	 * changes in left viewer, results in inconsistent state. The dirty state of
	 * compare input should be based only on the information if there are
	 * changes in viewers for left side.
	 *
	 * @param dirty
	 *            the dirty state for this compare input
	 * @since 3.7
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended
	 *             by clients.
	 */
	protected void setLeftDirty(boolean dirty) {
		boolean oldDirty = isSaveNeeded();
		fLeftDirty = dirty;

		if (oldDirty != isSaveNeeded()) {
			Utilities.firePropertyChange(fListenerList, this, DIRTY_STATE,
					Boolean.valueOf(oldDirty), Boolean.valueOf(isSaveNeeded()));
		}
	}

	/**
	 * Sets the dirty state of right site of this input to the given value and
	 * sends out a <code>PropertyChangeEvent</code> if the new value for whole
	 * input differs from the old value. Direct calling this method with
	 * parameter dirty equal to <code>false</code> when there are unsaved
	 * changes in right viewer, results in inconsistent state. The dirty state
	 * of compare input should be based only on the information if there are
	 * changes in viewers for right side.
	 *
	 * @param dirty
	 *            the dirty state for this compare input
	 * @since 3.7
	 * @noreference This method is not intended to be referenced by clients.
	 * @nooverride This method is not intended to be re-implemented or extended
	 *             by clients.
	 */
	protected void setRightDirty(boolean dirty) {
		boolean oldDirty = isSaveNeeded();
		fRightDirty = dirty;

		if (oldDirty != isSaveNeeded()) {
			Utilities.firePropertyChange(fListenerList, this, DIRTY_STATE,
					Boolean.valueOf(oldDirty), Boolean.valueOf(isSaveNeeded()));
		}
	}

	/**
	 * Method adds or removes viewers that changed left or right side of this
	 * compare input. Any modification of any of the list of viewers may result
	 * in dirty state change.
	 *
	 * @param source
	 *            the object that fired <code>PropertyChangeEvent</code>
	 *            modifying the dirty state
	 * @param dirty
	 *            value that describes if the changes were added or removed
	 */
	private void setDirty(Object source, boolean dirty) {
		Assert.isNotNull(source);
		boolean oldDirty = isSaveNeeded();

		if (source instanceof ContentMergeViewer) {
			ContentMergeViewer cmv = (ContentMergeViewer) source;

			if (dirty == cmv.internalIsLeftDirty()) {
				fLeftDirty = cmv.internalIsLeftDirty();
			}

			if (dirty == cmv.internalIsRightDirty()) {
				fRightDirty = cmv.internalIsRightDirty();
			}
		} else {
			fLeftDirty = dirty;
		}

		boolean newDirty = isSaveNeeded();
		if (DEBUG) {
			System.out.println("setDirty(" + source + ", " + dirty + "): " + newDirty); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		if (oldDirty != newDirty) {
			Utilities.firePropertyChange(fListenerList, this, DIRTY_STATE, Boolean.valueOf(oldDirty), Boolean.valueOf(newDirty));
		}
	}

	@Override
	public void addPropertyChangeListener(IPropertyChangeListener listener) {
		if (listener != null)
			fListenerList.add(listener);
	}

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

	/**
	 * Saves any unsaved changes.
	 * Empty implementation.
	 * Subclasses must override to save any changes.
	 *
	 * @param pm an <code>IProgressMonitor</code> that the implementation of save may use to show progress
	 * @deprecated Override method saveChanges instead.
	 */
	@Deprecated
	public void save(IProgressMonitor pm) {
		// empty default implementation
	}

	/**
	 * Saves any unsaved changes. Subclasses must override to save any changes. This
	 * implementation tries to flush changes in all viewers by calling
	 * <code>ISavable.save</code> on them.
	 *
	 * @param monitor an <code>IProgressMonitor</code> that the implementation of
	 *                save may use to show progress
	 * @throws CoreException If save fails.
	 * @since 2.0
	 */
	public void saveChanges(IProgressMonitor monitor) throws CoreException {
		flushViewers(monitor);

		save(monitor);
	}

	/**
	 * Flushes the viewer contents into the input.
	 * @param monitor a progress monitor
	 * @since 3.3
	 */
	protected void flushViewers(IProgressMonitor monitor) {
		// flush changes in any dirty viewer
		flushViewer(fStructureInputPane, monitor);
		flushViewer(fStructurePane1, monitor);
		flushViewer(fStructurePane2, monitor);
		flushViewer(fContentInputPane, monitor);
	}

	/**
	 * @param monitor a progress monitor
	 * @noreference This method is not intended to be referenced by clients.
	 */
	protected void flushLeftViewers(IProgressMonitor monitor) {
		// flush changes in left dirty viewer
		flushViewer(fStructureInputPane, monitor);
		flushViewer(fStructurePane1, monitor);
		flushViewer(fStructurePane2, monitor);
		flushLeftViewer(fContentInputPane, monitor);
	}

	/**
	 * @param monitor a progress monitor
	 * @noreference This method is not intended to be referenced by clients.
	 */
	protected void flushRightViewers(IProgressMonitor monitor) {
		// flush changes in right dirty viewer
		flushViewer(fStructureInputPane, monitor);
		flushViewer(fStructurePane1, monitor);
		flushViewer(fStructurePane2, monitor);
		flushRightViewer(fContentInputPane, monitor);
	}

	private static void flushViewer(CompareViewerPane pane, IProgressMonitor pm) {
		if (pane != null) {
			IFlushable flushable = Adapters.adapt(pane, IFlushable.class);
			if (flushable != null)
				flushable.flush(pm);
		}
	}

	private static void flushLeftViewer(CompareViewerPane pane, IProgressMonitor pm) {
		if (pane != null) {
			IFlushable2 flushable = Adapters.adapt(pane, IFlushable2.class);
			if (flushable != null)
				flushable.flushLeft(pm);
		}
	}

	private static void flushRightViewer(CompareViewerPane pane, IProgressMonitor pm) {
		if (pane != null) {
			IFlushable2 flushable = Adapters.adapt(pane, IFlushable2.class);
			if (flushable != null)
				flushable.flushRight(pm);
		}
	}

	@Override
	public void addCompareInputChangeListener(ICompareInput input,
			ICompareInputChangeListener listener) {
		if (fContainer == null) {
			input.addCompareInputChangeListener(listener);
		} else {
			fContainer.addCompareInputChangeListener(input, listener);
		}
	}

	@Override
	public void removeCompareInputChangeListener(ICompareInput input,
			ICompareInputChangeListener listener) {
		if (fContainer == null) {
			input.removeCompareInputChangeListener(listener);
		} else {
			fContainer.removeCompareInputChangeListener(input, listener);
		}
	}

	@Override
	public void registerContextMenu(MenuManager menu, ISelectionProvider selectionProvider) {
		if (fContainer != null)
			fContainer.registerContextMenu(menu, selectionProvider);
	}

	@Override
	public void setStatusMessage(String message) {
		if (!fContainerProvided) {
			// Try the action bars directly
			IActionBars actionBars= getActionBars();
			if (actionBars != null) {
				IStatusLineManager slm= actionBars.getStatusLineManager();
				if (slm != null) {
					slm.setMessage(message);
				}
			}
		} else if (fContainer != null) {
			fContainer.setStatusMessage(message);
		}
	}

	@Override
	public IActionBars getActionBars() {
		if (fContainer != null) {
			IActionBars actionBars = fContainer.getActionBars();
			if (actionBars == null && !fContainerProvided) {
				// The old way to find the action bars
				return Utilities.findActionBars(fComposite);
			}
			return actionBars;
		}
		return null;
	}

	@Override
	public IServiceLocator getServiceLocator() {
		IServiceLocator serviceLocator = fContainer.getServiceLocator();
		if (serviceLocator == null && !fContainerProvided) {
			// The old way to find the service locator
			return Utilities.findSite(fComposite);
		}
		return serviceLocator;
	}

	@Override
	public IWorkbenchPart getWorkbenchPart() {
		if (fContainer != null)
			return fContainer.getWorkbenchPart();
		return null;
	}

	@Override
	public void run(boolean fork, boolean cancelable,
			IRunnableWithProgress runnable) throws InvocationTargetException,
			InterruptedException {
		if (fContainer != null)
			fContainer.run(fork, cancelable, runnable);
	}

	@Override
	public void runAsynchronously(IRunnableWithProgress runnable) {
		if (fContainer != null)
			fContainer.runAsynchronously(runnable);
	}

	/**
	 * Sets the container of this input to the given container
	 * @param container the container
	 * @since 3.3
	 */
	public void setContainer(ICompareContainer container) {
		Assert.isNotNull(container);
		this.fContainer = container;
		fContainerProvided = true;
	}

	/**
	 * Returns the container of this input or <code>null</code> if there is no container
	 * set.
	 * @return the container of this input or <code>null</code>
	 * @since 3.3
	 */
	public final ICompareContainer getContainer() {
		return fContainer;
	}

	/**
	 * Fires the given property change event to all listeners
	 * registered with this compare editor input.
	 * @param event the property change event
	 * @since 3.3
	 */
	protected void firePropertyChange(PropertyChangeEvent event) {
		Utilities.firePropertyChange(fListenerList, event);
	}

	/**
	 * Returns whether this compare editor input can be run as a job.
	 * By default, <code>false</code> is returned since traditionally inputs
	 * were prepared in the foreground (i.e the UI was blocked when the
	 * {@link #run(IProgressMonitor)} method (and indirectly the
	 * {@link #prepareInput(IProgressMonitor)} method) was invoked. Subclasses
	 * may override.
	 * @return whether this compare editor input can be run in the background
	 * @since 3.3
	 */
	public boolean canRunAsJob() {
		return false;
	}

	/**
	 * Returns whether this input belongs to the given family
	 * when it is run as a job.
	 * @see #canRunAsJob()
	 * @see Job#belongsTo(Object)
	 * @param family the job family
	 * @return whether this input belongs to the given family
	 * @since 3.3
	 */
	public boolean belongsTo(Object family) {
		return family == this;
	}

	/**
	 * Returns whether this input is intended to be used to select
	 * a particular edition of an element in a dialog. The result
	 * of this method is only consider if neither sides of the
	 * input are editable. By default, <code>false</code> is returned.
	 * @return whether this input is intended to be used to select
	 * a particular edition of an element in a dialog
	 * @see #getOKButtonLabel()
	 * @see #okPressed()
	 * @see #getSelectedEdition()
	 * @since 3.3
	 */
	public boolean isEditionSelectionDialog() {
		return false;
	}

	/**
	 * Returns the label to be used for the <code>OK</code>
	 * button when this input is displayed in a dialog.
	 * By default, different labels are used depending on
	 * whether the input is editable or is for edition selection
	 * (see {@link #isEditionSelectionDialog()}.
	 * @return the label to be used for the <code>OK</code>
	 * button when this input is displayed in a dialog
	 * @since 3.3
	 */
	public String getOKButtonLabel() {
		if (isEditable())
			return CompareMessages.CompareDialog_commit_button;
		if (isEditionSelectionDialog())
			return CompareMessages.CompareEditorInput_0;
		return IDialogConstants.OK_LABEL;
	}

	/**
	 * Returns the label used for the <code>CANCEL</code>
	 * button when this input is shown in a compare dialog
	 * using {@link CompareUI#openCompareDialog(CompareEditorInput)}.
	 * @return the label used for the <code>CANCEL</code> button
	 * @since 3.3
	 */
	public String getCancelButtonLabel() {
		return IDialogConstants.CANCEL_LABEL;
	}

	private boolean isEditable() {
		return getCompareConfiguration().isLeftEditable()
			|| getCompareConfiguration().isRightEditable();
	}

	/**
	 * The <code>OK</code> button was pressed in a dialog. If one or both of
	 * the sides of the input is editable then any changes will be saved. If the
	 * input is for edition selection (see {@link #isEditionSelectionDialog()}),
	 * it is up to subclasses to override this method in order to perform the
	 * appropriate operation on the selected edition.
	 *
	 * @return whether the dialog should be closed or not.
	 * @since 3.3
	 */
	public boolean okPressed() {
		if (isEditable()) {
			if (!saveChanges())
				return false;
		}
		return true;
	}

	/**
	 * The <code>CANCEL</code> button was pressed in a dialog.
	 * By default, nothing is done. Subclasses may override.
	 * @since 3.3
	 */
	public void cancelPressed() {
		// Do nothing
	}

	private boolean saveChanges() {
		try {
			PlatformUI.getWorkbench().getProgressService().run(true, true, monitor -> {
				try {
					saveChanges(monitor);
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				}
			});
			return true;
		} catch (InterruptedException | OperationCanceledException x) {
			// Ignore
		} catch (InvocationTargetException x) {
			ErrorDialog.openError(fComposite.getShell(), CompareMessages.CompareDialog_error_title, null,
				new Status(IStatus.ERROR, CompareUIPlugin.PLUGIN_ID, 0,
					NLS.bind(CompareMessages.CompareDialog_error_message, x.getTargetException().getMessage()), x.getTargetException()));
		}
		return false;
	}

	/**
	 * Returns the selected edition or <code>null</code> if no edition is selected.
	 * The result of this method should only be considered if {@link #isEditionSelectionDialog()}
	 * returns <code>true</code>.
	 * @return the selected edition or <code>null</code>
	 * @since 3.3
	 */
	public Object getSelectedEdition() {
		if (fStructureInputPane != null) {
			ISelection selection = fStructureInputPane.getSelection();
			if (selection instanceof IStructuredSelection) {
				IStructuredSelection ss = (IStructuredSelection) selection;
				if (!ss.isEmpty())
					return ss.getFirstElement();

			}
		}
		return null;
	}

	/**
	 * Sets the help context id for this input.
	 * @param helpContextId the help context id.
	 * @since 3.3
	 */
	public void setHelpContextId(String helpContextId) {
		this.fHelpContextId = helpContextId;
	}
}
