/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ui.synchronize;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.ResourceNode;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.commands.ActionHandler;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IBasicPropertyConstants;
import org.eclipse.jface.viewers.IElementComparer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.core.variants.IResourceVariant;
import org.eclipse.team.internal.core.mapping.ResourceVariantFileRevision;
import org.eclipse.team.internal.ui.IHelpContextIds;
import org.eclipse.team.internal.ui.Policy;
import org.eclipse.team.internal.ui.TeamUIMessages;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.history.FileRevisionEditorInput;
import org.eclipse.team.internal.ui.synchronize.actions.PasteAction;
import org.eclipse.team.internal.ui.synchronize.actions.PinParticipantAction;
import org.eclipse.team.internal.ui.synchronize.actions.RemoveSynchronizeParticipantAction;
import org.eclipse.team.internal.ui.synchronize.actions.SynchronizeAndRefreshAction;
import org.eclipse.team.internal.ui.synchronize.actions.SynchronizePageDropDownAction;
import org.eclipse.team.internal.ui.synchronize.actions.ToggleLinkingAction;
import org.eclipse.team.ui.TeamUI;
import org.eclipse.team.ui.synchronize.ISynchronizeManager;
import org.eclipse.team.ui.synchronize.ISynchronizePage;
import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipant;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipantListener;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipantReference;
import org.eclipse.team.ui.synchronize.ISynchronizeView;
import org.eclipse.team.ui.synchronize.ModelSynchronizeParticipant;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.ISaveablePart;
import org.eclipse.ui.ISaveablesLifecycleListener;
import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.OpenAndLinkWithEditorHelper;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.Saveable;
import org.eclipse.ui.SaveablesLifecycleEvent;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.part.IPageBookViewPage;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.MessagePage;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.part.PageBookView;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;

/**
 * Implements a Synchronize View that contains multiple synchronize participants.
 */
public class SynchronizeView extends PageBookView implements ISynchronizeView, ISynchronizeParticipantListener, IPropertyChangeListener, ISaveablesSource, ISaveablePart, IShowInTarget {

	/**
	 * Suggested maximum length of participant names when shown in certain menus and dialog.
	 */
	public final static int MAX_NAME_LENGTH = 100;

	/**
	 * The participant being displayed, or <code>null</code> if none
	 */
	private ISynchronizeParticipant activeParticipantRef = null;

	/**
	 * Map of participants to dummy participant parts (used to close pages)
	 */
	private Map<ISynchronizeParticipant, IWorkbenchPart> fParticipantToPart;

	/**
	 * Map of parts to participants
	 */
	private Map<IWorkbenchPart, ISynchronizeParticipant> fPartToParticipant;

	/**
	 * Drop down action to switch between participants
	 */
	private SynchronizePageDropDownAction fPageDropDown;

	/**
	 * Action to remove the selected participant
	 */
	private PinParticipantAction fPinAction;

	/**
	 * Action to remove the currently shown participant
	 */
	private RemoveSynchronizeParticipantAction fRemoveCurrentAction;

	/**
	 * Action to remove all non-pinned participants
	 */
	private RemoveSynchronizeParticipantAction fRemoveAllAction;

	private ToggleLinkingAction fToggleLinkingAction;

	/**
	 * Refresh action.
	 * @since 3.7
	 */
	private SynchronizeAndRefreshAction fRefreshAction;


	/**
	 * Action to paste patch into the view, starting a new synchronization.
	 */
	private PasteAction fPastePatchAction;
	private boolean fLinkingEnabled;
	private OpenAndLinkWithEditorHelper fOpenAndLinkWithEditorHelper;


	/**
	 * Preference key to save
	 */
	private static final String KEY_LAST_ACTIVE_PARTICIPANT_ID = "lastactiveparticipant_id"; //$NON-NLS-1$
	private static final String KEY_LAST_ACTIVE_PARTICIPANT_SECONDARY_ID = "lastactiveparticipant_sec_id"; //$NON-NLS-1$
	private static final String KEY_LINK_WITH_EDITOR = "linkWithEditor"; //$NON-NLS-1$
	private static final String KEY_SETTINGS_SECTION= "SynchronizeViewSettings"; //$NON-NLS-1$


	@Override
	public void propertyChange(PropertyChangeEvent event) {
		Object source = event.getSource();
		if (source instanceof ISynchronizeParticipant) {
			if (event.getProperty().equals(IBasicPropertyConstants.P_TEXT)) {
				if (source.equals(getParticipant())) {
					updateTitle();
				}
			} else if (event.getProperty().equals(ModelSynchronizeParticipant.PROP_DIRTY)) {
				Display.getDefault().asyncExec(() -> firePropertyChange(PROP_DIRTY));
			} else if (event.getProperty().equals(ModelSynchronizeParticipant.PROP_ACTIVE_SAVEABLE)) {
				Saveable oldSaveable = (Saveable)event.getOldValue();
				Saveable newSaveable = (Saveable)event.getNewValue();
				ISaveablesLifecycleListener listener = getSite().getPage().getWorkbenchWindow()
					.getService(ISaveablesLifecycleListener.class);
				if (listener != null && oldSaveable != null)
					listener.handleLifecycleEvent(new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_CLOSE, new Saveable[] { oldSaveable }, false));
				if (listener != null && newSaveable != null)
					listener.handleLifecycleEvent(new SaveablesLifecycleEvent(this, SaveablesLifecycleEvent.POST_OPEN, new Saveable[] { newSaveable }, false));
			} else if (event.getProperty().equals(ISynchronizeParticipant.P_CONTENT)) {
				final IWorkbenchSiteProgressService ps = getSite().getAdapter(IWorkbenchSiteProgressService.class);
				if (ps != null)
					Display.getDefault().asyncExec(() -> ps.warnOfContentChange());
			}
		}
		if (source instanceof ISynchronizePageConfiguration) {
			ISynchronizePageConfiguration configuration = (ISynchronizePageConfiguration) source;
			if (event.getProperty().equals(ISynchronizePageConfiguration.P_PAGE_DESCRIPTION)) {
				if (configuration.getParticipant().equals(getParticipant())) {
					updateTitle();
				}
			} else if (event.getProperty().equals(ISynchronizePageConfiguration.P_MODE)) {
				if (configuration.getParticipant().equals(getParticipant())) {
					updateTitle();
				}
			}
		}
	}

	@Override
	public void partClosed(IWorkbenchPart part) {
		super.partClosed(part);
	}

	@Override
	public ISynchronizeParticipant getParticipant() {
		return activeParticipantRef;
	}

	@Override
	protected void showPageRec(PageRec pageRec) {
		super.showPageRec(pageRec);
		activeParticipantRef = fPartToParticipant.get(pageRec.part);
		updateActionEnablements();
		updateTitle();
	}

	/*
	 * Updates the view title based on the active participant
	 */
	protected void updateTitle() {
		ISynchronizeParticipant participant = getParticipant();
		if (participant == null) {
			setContentDescription(""); //$NON-NLS-1$
		} else {
			SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart)fParticipantToPart.get(participant);
			ISynchronizePageConfiguration configuration = part.getConfiguration();
			String description = (String)configuration.getProperty(ISynchronizePageConfiguration.P_PAGE_DESCRIPTION);
			if (description == null)
				description = part.getParticipant().getName();
			// TODO: Get the description from the configuration
			// TODO: listen to the configuration for description changes
			setContentDescription(Utils.shortenText(MAX_NAME_LENGTH, description));
			setStatusLineMessage(description, configuration.getMode());
		}
	}

	@Override
	protected void doDestroyPage(IWorkbenchPart part, PageRec pageRecord) {
		IPage page = pageRecord.page;
		page.dispose();
		pageRecord.dispose();
		SynchronizeViewWorkbenchPart syncPart = (SynchronizeViewWorkbenchPart) part;
		ISynchronizeParticipant participant = syncPart.getParticipant();
		clearCrossReferenceCache(part, participant);
	}

	private void clearCrossReferenceCache(IWorkbenchPart part, ISynchronizeParticipant participant) {
		participant.removePropertyChangeListener(this);
		if (part == null)
			return;
		ISynchronizePageConfiguration configuration = ((SynchronizeViewWorkbenchPart)part).getConfiguration();
		if (configuration != null)
			configuration.removePropertyChangeListener(this);
		fPartToParticipant.remove(part);
		fParticipantToPart.remove(participant);
	}

	@Override
	protected PageRec doCreatePage(IWorkbenchPart dummyPart) {
		SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart)dummyPart;
		ISynchronizeParticipant participant = part.getParticipant();
		participant.addPropertyChangeListener(this);
		ISynchronizePageConfiguration configuration = participant.createPageConfiguration();
		part.setConfiguration(configuration);
		configuration.addPropertyChangeListener(this);
		IPageBookViewPage page = participant.createPage(configuration);
		if(page != null) {
			initPage(page);
			initPage(configuration, page);
			page.createControl(getPageBook());
			PageRec rec = new PageRec(dummyPart, page);
			return rec;
		}
		return null;
	}

	protected void initPage(ISynchronizePageConfiguration configuration, IPageBookViewPage page) {
		// A page site does not provide everything the page may need
		// Also provide the synchronize page site if the page is a synchronize view page
		((SynchronizePageConfiguration)configuration).setSite(new WorkbenchPartSynchronizePageSite(this, page.getSite(), getDialogSettings(configuration.getParticipant())));
		if (page instanceof ISynchronizePage) {
			try {
				((ISynchronizePage)page).init(configuration.getSite());
			} catch (PartInitException e) {
				TeamUIPlugin.log(IStatus.ERROR, e.getMessage(), e);
			}
		}
		page.getSite().getActionBars().setGlobalActionHandler(ActionFactory.REFRESH.getId(), fRefreshAction);
		page.getSite().getActionBars().updateActionBars();
	}

	@Override
	protected boolean isImportant(IWorkbenchPart part) {
		return part instanceof SynchronizeViewWorkbenchPart;
	}

	@Override
	public void dispose() {
		super.dispose();
		TeamUI.getSynchronizeManager().removeSynchronizeParticipantListener(this);
		// Pin action is hooked up to listeners, must call dispose to un-register.
		fPinAction.dispose();
		fPastePatchAction.dispose();
		// Remember the last active participant
		if(activeParticipantRef != null) {
			rememberCurrentParticipant();
		}
		fParticipantToPart = null;
		fPartToParticipant = null;
		// Remove 'Link with Editor' listener when closing the view
		getSite().getPage().removePartListener(fLinkWithEditorListener);
	}

	/**
	 *
	 */
	private void rememberCurrentParticipant() {
		IDialogSettings section = getDialogSettings();
		section.put(KEY_LAST_ACTIVE_PARTICIPANT_ID, activeParticipantRef.getId());
		section.put(KEY_LAST_ACTIVE_PARTICIPANT_SECONDARY_ID, activeParticipantRef.getSecondaryId());
	}

	@Override
	protected IPage createDefaultPage(PageBook book) {
		Page page = new MessagePage();
		page.createControl(getPageBook());
		initPage(page);
		return page;
	}

	@Override
	public void participantsAdded(final ISynchronizeParticipant[] participants) {
		for (ISynchronizeParticipant participant : participants) {
			if (isAvailable() && select(TeamUI.getSynchronizeManager().get(participant.getId(), participant.getSecondaryId()))) {
				SynchronizeViewWorkbenchPart part = new SynchronizeViewWorkbenchPart(participant, getSite());
				fParticipantToPart.put(participant, part);
				fPartToParticipant.put(part, participant);
			}
		}
		Display.getDefault().asyncExec(() -> firePropertyChange(PROP_DIRTY));
	}

	@Override
	public void participantsRemoved(final ISynchronizeParticipant[] participants) {
		if (isAvailable()) {
			Runnable r = () -> {
				for (ISynchronizeParticipant participant : participants) {
					if (isAvailable()) {
						SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart)fParticipantToPart.get(participant);
						if (part != null) {
							partClosed(part);
							clearCrossReferenceCache(part, participant);
						}
						// Remove any settings created for the participant
						removeDialogSettings(participant);
						if (getParticipant() == null) {
							ISynchronizeParticipantReference[] available = TeamUI.getSynchronizeManager().getSynchronizeParticipants();
							if (available.length > 0) {
								ISynchronizeParticipant p;
								try {
									p = available[available.length - 1].getParticipant();
								} catch (TeamException e) {
									return;
								}
								display(p);
							} else {
								/*
								 * Remove 'Link with Editor' listener if
								 * there are no more participants available.
								 */
								getSite().getPage().removePartListener(fLinkWithEditorListener);
							}
						}
					}
				}
				firePropertyChange(PROP_DIRTY);
			};
			asyncExec(r);
		}
	}

	/**
	 * Constructs a synchronize view
	 */
	public SynchronizeView() {
		super();
		fParticipantToPart = new HashMap<>();
		fPartToParticipant = new HashMap<>();
		updateTitle();
	}

	/**
	 * Create the default actions for the view. These will be shown regardless of the
	 * participant being displayed.
	 */
	protected void createActions() {
		fPageDropDown= new SynchronizePageDropDownAction(this);
		fRefreshAction= new SynchronizeAndRefreshAction(this);
		fPinAction = new PinParticipantAction();
		fToggleLinkingAction = new ToggleLinkingAction(this);
		fRemoveCurrentAction = new RemoveSynchronizeParticipantAction(this, false);
		fRemoveAllAction = new RemoveSynchronizeParticipantAction(this, true);
		fPastePatchAction = new PasteAction(this);
		updateActionEnablements();
	}

	private void updateActionEnablements() {
		if (fPinAction != null) {
			fPinAction.setParticipant(activeParticipantRef);
		}
		if (fToggleLinkingAction != null) {
			fToggleLinkingAction.setEnabled(getParticipant() != null);
		}
		if (fRemoveAllAction != null) {
			fRemoveAllAction.setEnabled(getParticipant() != null);
		}
		if (fRemoveCurrentAction != null) {
			fRemoveCurrentAction.setEnabled(getParticipant() != null);
		}
		if (fPastePatchAction != null) {
			// The action is always enabled
			fPastePatchAction.setEnabled(true);
		}
	}

	/**
	 * Add the actions to the toolbar
	 *
	 * @param bars the action bars
	 */
	protected void configureToolBar(IActionBars bars) {
		IToolBarManager mgr = bars.getToolBarManager();
		mgr.add(fPageDropDown);
		mgr.add(fPinAction);
		IMenuManager menu = bars.getMenuManager();
		menu.add(fPinAction);
		menu.add(fToggleLinkingAction);
		menu.add(fRemoveCurrentAction);
		menu.add(fRemoveAllAction);

		IHandlerService handlerService= this.getViewSite().getService(IHandlerService.class);
		handlerService.activateHandler(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR, new ActionHandler(fToggleLinkingAction));
		handlerService.activateHandler(ActionFactory.PASTE.getCommandId(), new ActionHandler(fPastePatchAction));
	}

	@Override
	public void display(ISynchronizeParticipant participant) {
		SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart)fParticipantToPart.get(participant);
		if (part != null) {
			partActivated(part);
			fPageDropDown.update();
			createOpenAndLinkWithEditorHelper(getViewer());
			rememberCurrentParticipant();
			PlatformUI.getWorkbench().getHelpSystem().setHelp(getPageBook().getParent(), participant.getHelpContextId());
		}
	}

	private void createOpenAndLinkWithEditorHelper(StructuredViewer viewer) {
		if (fOpenAndLinkWithEditorHelper != null)
			fOpenAndLinkWithEditorHelper.dispose();
		fOpenAndLinkWithEditorHelper= new OpenAndLinkWithEditorHelper(viewer) {
			@Override
			protected void activate(ISelection selection) {
				try {
					final Object selectedElement = getSingleElement(selection);
					if (isOpenInEditor(selectedElement) != null)
						if (selectedElement instanceof IFile)
							openInEditor((IFile) selectedElement, true);
				} catch (PartInitException ex) {
					// ignore if no editor input can be found
				}
			}

			@Override
			protected void linkToEditor(ISelection selection) {
				SynchronizeView.this.linkToEditor(selection);
			}

			@Override
			protected void open(ISelection selection, boolean activate) {
				// TODO: implement, bug 291211
			}
		};
		fOpenAndLinkWithEditorHelper.setLinkWithEditor(isLinkingEnabled());
		setLinkingEnabled(isLinkingEnabled());
	}

	@Override
	protected IWorkbenchPart getBootstrapPart() {
		return null;
	}

	/**
	 * Registers the given runnable with the display
	 * associated with this view's control, if any.
	 * @param runnable a runnable
	 */
	public void asyncExec(Runnable runnable) {
		if (isAvailable()) {
			getPageBook().getDisplay().asyncExec(runnable);
		}
	}

	/**
	 * Creates this view's underlying viewer and actions.
	 * Hooks a pop-up menu to the underlying viewer's control,
	 * as well as a key listener. When the delete key is pressed,
	 * the <code>REMOVE_ACTION</code> is invoked. Hooks help to
	 * this view. Subclasses must implement the following methods
	 * which are called in the following order when a view is
	 * created:<ul>
	 * <li><code>createViewer(Composite)</code> - the context
	 *   menu is hooked to the viewer's control.</li>
	 * <li><code>createActions()</code></li>
	 * <li><code>configureToolBar(IToolBarManager)</code></li>
	 * <li><code>getHelpContextId()</code></li>
	 * </ul>
	 * @see IWorkbenchPart#createPartControl(Composite)
	 */
	@Override
	public void createPartControl(Composite parent) {
		super.createPartControl(parent);
		restoreLinkingEnabled();
		createActions();
		configureToolBar(getViewSite().getActionBars());
		updateForExistingParticipants();
		getViewSite().getActionBars().updateActionBars();
		updateTitle();

		IWorkbenchSiteProgressService progress = getSite().getAdapter(IWorkbenchSiteProgressService.class);
		if(progress != null) {
			progress.showBusyForFamily(ISynchronizeManager.FAMILY_SYNCHRONIZE_OPERATION);
		}

		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IHelpContextIds.SYNC_VIEW);
	}

	/**
	 * Initialize for existing participants
	 */
	private void updateForExistingParticipants() {
		ISynchronizeManager manager = TeamUI.getSynchronizeManager();
		List participants = Arrays.asList(getParticipants());
		boolean errorOccurred = false;
		for (int i = 0; i < participants.size(); i++) {
			try {
				ISynchronizeParticipantReference ref = (ISynchronizeParticipantReference)participants.get(i);
				participantsAdded(new ISynchronizeParticipant[] {ref.getParticipant()});
			} catch (TeamException e) {
				errorOccurred = true;
				continue;
			}

		}
		if (errorOccurred) {
			participants = Arrays.asList(getParticipants());
		}
		try {
			// decide which participant to show	on startup
			if (participants.size() > 0) {
				ISynchronizeParticipantReference participantToSelect = (ISynchronizeParticipantReference)participants.get(0);
				IDialogSettings section = getDialogSettings();
				String selectedParticipantId = section.get(KEY_LAST_ACTIVE_PARTICIPANT_ID);
				String selectedParticipantSecId = section.get(KEY_LAST_ACTIVE_PARTICIPANT_SECONDARY_ID);
				if(selectedParticipantId != null) {
					ISynchronizeParticipantReference selectedParticipant = manager.get(selectedParticipantId, selectedParticipantSecId);
					if(selectedParticipant != null) {
						participantToSelect = selectedParticipant;
					}
				}
				display(participantToSelect.getParticipant());
			}

			// add as a listener to update when new participants are added
			manager.addSynchronizeParticipantListener(this);
		} catch (TeamException e) {
			Utils.handle(e);
		}
	}

	private ISynchronizeParticipantReference[] getParticipants() {
		ISynchronizeManager manager = TeamUI.getSynchronizeManager();
		// create pages
		List<ISynchronizeParticipantReference> participants = new ArrayList<>();
		ISynchronizeParticipantReference[] refs = manager.getSynchronizeParticipants();
		for (ISynchronizeParticipantReference ref : refs) {
			if(select(ref)) {
				participants.add(ref);
			}
		}
		return participants.toArray(new ISynchronizeParticipantReference[participants.size()]);
	}

	private boolean isAvailable() {
		return getPageBook() != null && !getPageBook().isDisposed();
	}

	/*
	 * Method used by test cases to access the page for a participant
	 */
	public IPage getPage(ISynchronizeParticipant participant) {
		IWorkbenchPart part = fParticipantToPart.get(participant);
		if (part == null) return null;
		try {
			return getPageRec(part).page;
		} catch (NullPointerException e) {
			// The PageRec class is not visible so we can't do a null check
			// before accessing the page.
			return null;
		}
	}

	protected boolean select(ISynchronizeParticipantReference ref) {
		return true;
	}

	/*
	 * Return the dialog settings for the view
	 */
	private IDialogSettings getDialogSettings() {
		IDialogSettings workbenchSettings = TeamUIPlugin.getPlugin().getDialogSettings();
		IDialogSettings syncViewSettings = workbenchSettings.getSection(KEY_SETTINGS_SECTION);
		if (syncViewSettings == null) {
			syncViewSettings = workbenchSettings.addNewSection(KEY_SETTINGS_SECTION);
		}
		return syncViewSettings;
	}

	private String getSettingsKey(ISynchronizeParticipant participant) {
		String id = participant.getId();
		String secondaryId = participant.getSecondaryId();
		return secondaryId == null ? id : id + '.' + secondaryId;
	}

	private IDialogSettings getDialogSettings(ISynchronizeParticipant participant) {
		String key = getSettingsKey(participant);
		IDialogSettings viewsSettings = getDialogSettings();
		IDialogSettings settings = viewsSettings.getSection(key);
		if (settings == null) {
			settings = viewsSettings.addNewSection(key);
		}
		return settings;
	}

	private void removeDialogSettings(ISynchronizeParticipant participant) {
		String key = getSettingsKey(participant);
		IDialogSettings settings = getDialogSettings();
		if (settings.getSection(key) != null) {
			// There isn't an explicit remove so just make sure
			// That the old settings are forgotten
			getDialogSettings().addSection(new DialogSettings(key));
		}
	}

	@Override
	public Saveable[] getSaveables() {
		Set<Saveable> result = new HashSet<>();
		for (Iterator iter = fPartToParticipant.keySet().iterator(); iter.hasNext();) {
			SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart) iter.next();
			Saveable saveable = getSaveable(part.getParticipant());
			if (saveable != null) {
				result.add(saveable);
			}
		}
		return result.toArray(new Saveable[result.size()]);
	}

	private Saveable getSaveable(ISynchronizeParticipant participant) {
		if (participant instanceof ModelSynchronizeParticipant) {
			ModelSynchronizeParticipant msp = (ModelSynchronizeParticipant) participant;
			return msp.getActiveSaveable();
		}
		return null;
	}

	@Override
	public Saveable[] getActiveSaveables() {
		ISynchronizeParticipant participant = getParticipant();
		Saveable s = getSaveable(participant);
		if (s != null)
			return new Saveable[] { s };
		return new Saveable[0];
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		Saveable[] saveables = getSaveables();
		if (saveables.length == 0)
			return;
		monitor.beginTask(null, 100* saveables.length);
		for (Saveable saveable : saveables) {
			try {
				saveable.doSave(Policy.subMonitorFor(monitor, 100));
			} catch (CoreException e) {
				ErrorDialog.openError(getSite().getShell(), null, e.getMessage(), e.getStatus());
			}
			Policy.checkCanceled(monitor);
		}
		monitor.done();
		firePropertyChange(PROP_DIRTY);
	}

	@Override
	public void doSaveAs() {
		// Not allowed
	}

	@Override
	public boolean isDirty() {
		Saveable[] saveables = getSaveables();
		for (Saveable saveable : saveables) {
			if (saveable.isDirty())
				return true;
		}
		return false;
	}

	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}

	@Override
	public boolean isSaveOnCloseNeeded() {
		return true;
	}

	private void setStatusLineMessage(String description, int mode) {
		String syncMode = null;
		ResourceBundle bundle = Policy.getActionBundle();
		switch (mode) {
		case ISynchronizePageConfiguration.INCOMING_MODE:
			syncMode = Utils.getString("action.directionFilterIncoming.tooltip", bundle); //$NON-NLS-1$
			break;
		case ISynchronizePageConfiguration.OUTGOING_MODE:
			syncMode = Utils.getString("action.directionFilterOutgoing.tooltip", bundle); //$NON-NLS-1$
			break;
		case ISynchronizePageConfiguration.BOTH_MODE:
			syncMode = Utils.getString("action.directionFilterBoth.tooltip", bundle); //$NON-NLS-1$
			break;
		case ISynchronizePageConfiguration.CONFLICTING_MODE:
			syncMode = Utils.getString("action.directionFilterConflicts.tooltip", bundle); //$NON-NLS-1$
			break;
		}

		IViewSite viewSite = getViewSite();
		if (viewSite != null && syncMode != null) {
			viewSite.getActionBars().getStatusLineManager().setMessage(
					NLS.bind(TeamUIMessages.SynchronizeView_statusLine,
							new String[] { description, syncMode }));
		}
	}

	// copy-pasted from org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart and modified

	private IPartListener2 fLinkWithEditorListener= new IPartListener2() {
		@Override
		public void partVisible(IWorkbenchPartReference partRef) {}
		@Override
		public void partBroughtToTop(IWorkbenchPartReference partRef) {}
		@Override
		public void partClosed(IWorkbenchPartReference partRef) {}
		@Override
		public void partDeactivated(IWorkbenchPartReference partRef) {}
		@Override
		public void partHidden(IWorkbenchPartReference partRef) {}
		@Override
		public void partOpened(IWorkbenchPartReference partRef) {}
		@Override
		public void partInputChanged(IWorkbenchPartReference partRef) {
			if (partRef instanceof IEditorReference) {
				editorActivated(((IEditorReference) partRef).getEditor(true));
			}
		}

		@Override
		public void partActivated(IWorkbenchPartReference partRef) {
			if (partRef instanceof IEditorReference) {
				editorActivated(((IEditorReference) partRef).getEditor(true));
			}
		}

	};

	public boolean isLinkingEnabled() {
		return fLinkingEnabled;
	}

	private static IElementComparer COMPARER = new IElementComparer() {

		private Object getContributedResourceOrResourceVariant(Object o) {
			IResource[] resources = Utils.getContributedResources(new Object[] {o});
			if (resources.length > 0)
				return resources[0];
			if (o instanceof SyncInfoModelElement) {
				SyncInfoModelElement sime = (SyncInfoModelElement) o;
				return sime.getSyncInfo().getRemote();
			}
			return null;
		}

		@Override
		public int hashCode(Object element) {
			Object r = getContributedResourceOrResourceVariant(element);
			if (r != null)
				return r.hashCode();
			return element.hashCode();
		}

		@Override
		public boolean equals(Object a, Object b) {
			// no need to check for null, CustomeHashtable cannot contain null keys
			if (a instanceof IResource || a instanceof IResourceVariant) {
				b = getContributedResourceOrResourceVariant(b);
			} else if (b instanceof IResource || b instanceof IResourceVariant) {
				a = getContributedResourceOrResourceVariant(a);
				return b.equals(a); // a may be null
			}
			return a.equals(b);
		}
	};

	public void setLinkingEnabled(boolean enabled) {
		fLinkingEnabled= enabled;
		IDialogSettings dialogSettings = getDialogSettings();
		dialogSettings.put(KEY_LINK_WITH_EDITOR, fLinkingEnabled);

		IWorkbenchPage page= getSite().getPage();
		if (enabled) {
			page.addPartListener(fLinkWithEditorListener);

			IEditorPart editor = page.getActiveEditor();
			if (editor != null)
				editorActivated(editor);
		} else {
			page.removePartListener(fLinkWithEditorListener);
		}
		fOpenAndLinkWithEditorHelper.setLinkWithEditor(enabled);

	}

	private void restoreLinkingEnabled() {
		fLinkingEnabled = getDialogSettings().getBoolean(KEY_LINK_WITH_EDITOR);
	}

	/**
	 * Links to editor (if option enabled)
	 * @param selection the selection
	 */
	private void linkToEditor(ISelection selection) {
		Object obj = getSingleElement(selection);
		if (obj != null) {
			IEditorPart part = isOpenInEditor(obj);
			if (part != null) {
				IWorkbenchPage page= getSite().getPage();
				page.bringToTop(part);
			}
		}
	}

	/**
	 * An editor has been activated. Set the selection in the Sync View
	 * to be the editor's input, if linking is enabled.
	 * @param editor the activated editor
	 */
	private void editorActivated(IEditorPart editor) {
		if (!isLinkingEnabled())
			return;

		IEditorInput editorInput= editor.getEditorInput();
		if (editorInput == null)
			return;
		Object input= getInputFromEditor(editorInput);
		if (input == null)
			return;
		if (!inputIsSelected(editorInput))
			showInput(input);
		else
			getViewer().getTree().showSelection();
	}

	boolean showInput(Object input) {
		Object element = input;
		if (element != null) {
			IElementComparer previousComparer = getViewer().getComparer();
			getViewer().setComparer(COMPARER);
			try {
				ISelection newSelection = new StructuredSelection(element);
				if (getViewer().getSelection().equals(newSelection)) {
					getViewer().reveal(element);
				} else {
					getViewer().setSelection(newSelection, true);

					while (element != null && getViewer().getSelection().isEmpty()) {
						// Try to select parent in case element is filtered
						element = getParent(element);
						if (element != null) {
							newSelection = new StructuredSelection(element);
							getViewer().setSelection(newSelection, true);
						} else {
							// Failed to find parent to select
							return false;
						}
					}
				}
				return true;
			} finally {
				getViewer().setComparer(previousComparer);
			}
		}
		return false;
	}

	/**
	 * Returns the element's parent.
	 * @param element the element
	 *
	 * @return the parent or <code>null</code> if there's no parent
	 */
	private Object getParent(Object element) {
		if (element instanceof IResource)
			return ((IResource)element).getParent();
		return null;
	}

	private TreeViewer getViewer() {
		IPage currentPage = getCurrentPage();
		if (currentPage instanceof ISynchronizePage) {
			return (TreeViewer) ((ISynchronizePage)currentPage).getViewer();
		}
		/*
		 * We should never get here. fLinkWithEditorListener is removed when no
		 * participants are available and the method should not be called
		 * afterwards. See participantsRemoved method for the listener's
		 * removal.
		 */
		Assert.isTrue(false);
		return null;
	}

	private boolean inputIsSelected(IEditorInput input) {
		IStructuredSelection selection= getViewer().getStructuredSelection();
		if (selection.size() != 1)
			return false;
		IEditorInput selectionAsInput= getEditorInput(selection.getFirstElement());
		return input.equals(selectionAsInput);
	}

	private static IEditorInput getEditorInput(Object input) {
		IResource[] resources = Utils.getContributedResources(new Object[] { input });
		if (resources.length > 0)
			input = resources[0];
		if (input instanceof IFile)
			return new FileEditorInput((IFile) input);
		return null;
	}

	private Object getInputFromEditor(IEditorInput editorInput) {
		Object input= editorInput.getAdapter(IFile.class);
		if (input == null && editorInput instanceof FileRevisionEditorInput) {
			IFileRevision fileRevision = ((FileRevisionEditorInput)editorInput).getFileRevision();
			if (fileRevision instanceof ResourceVariantFileRevision)
				return ((ResourceVariantFileRevision) fileRevision).getVariant();
		}
		if (input == null && editorInput instanceof IStorageEditorInput) {
			try {
				input= ((IStorageEditorInput) editorInput).getStorage();
			} catch (CoreException e) {
				// ignore
			}
		}
		return input;
	}

	// copy-pasted from org.eclipse.jdt.internal.ui.javaeditor.EditorUtility and modified

	private static IEditorPart isOpenInEditor(Object inputElement) {
		IEditorInput input = getEditorInput(inputElement);
		if (input != null) {
			IWorkbenchPage p = TeamUIPlugin.getActivePage();
			if (p != null) {
				IEditorPart editor = p.findEditor(input);
				if (editor == null) {
					IEditorReference[] er = p.getEditorReferences();
					for (IEditorReference e : er) {
						if (e.getId().equals("org.eclipse.compare.CompareEditor") && matches(e, input)) { //$NON-NLS-1$
							editor = e.getEditor(false);
						}
					}
				}
				return editor;
			}
		}
		return null;
	}

	private static boolean matches(IEditorReference editorRef,
			IEditorInput input) {
		if (input instanceof FileEditorInput) {
			IFile file = ((FileEditorInput) input).getFile();

			CompareEditorInput cei = (CompareEditorInput) ((EditorPart) editorRef
					.getPart(false)).getEditorInput();
			Object compareResult = cei.getCompareResult();

			if (compareResult instanceof IAdaptable) {
				IResource r = ((IAdaptable) compareResult).getAdapter(IResource.class);
				if (r != null)
					return file.equals(r);
			}
			if (compareResult instanceof ICompareInput) {
				ICompareInput compareInput = (ICompareInput) compareResult;
				ITypedElement left = compareInput.getLeft();
				if (left instanceof ResourceNode)
					if (file.equals(((ResourceNode) left).getResource()))
						return true;
				ITypedElement right = compareInput.getRight();
				if (right instanceof ResourceNode)
					if (file.equals(((ResourceNode) right).getResource()))
						return true;
			}
		}
		return false;
	}

	private static IEditorPart openInEditor(IFile file, boolean activate) throws PartInitException {
		if (file == null)
			throwPartInitException(TeamUIMessages.SynchronizeView_fileMustNotBeNull);

		IWorkbenchPage p = TeamUIPlugin.getActivePage();
		if (p == null)
			throwPartInitException(TeamUIMessages.SynchronizeView_noActiveWorkbenchPage);

		IEditorPart editorPart = IDE.openEditor(p, file, activate);
		return editorPart;
	}

	private static void throwPartInitException(String message) throws PartInitException {
		IStatus status = new Status(IStatus.ERROR, TeamUIPlugin.ID, IStatus.OK, message, null);
		throw new PartInitException(status);
	}

	// copy-pasted from org.eclipse.jdt.internal.ui.util.SelectionUtil and modified

	/**
	 * Returns the selected element if the selection consists of a single
	 * element only.
	 *
	 * @param s the selection
	 * @return the selected first element or null
	 */
	private static Object getSingleElement(ISelection s) {
		if (!(s instanceof IStructuredSelection))
			return null;
		IStructuredSelection selection = (IStructuredSelection) s;
		if (selection.size() != 1)
			return null;

		return selection.getFirstElement();
	}

	@Override
	public boolean show(ShowInContext context) {
		Object selection = getSingleElement(context.getSelection());
		if (selection != null) {
			// If can show the selection, do it.
			// Otherwise, fall through and attempt to show the input
			if (showInput(selection))
				return true;
		}
		Object input = context.getInput();
		if (input != null) {
			if (input instanceof IEditorInput) {
				return showInput(getInputFromEditor((IEditorInput) input));
			}
			return showInput(input);
		}
		return false;
	}

	public IAction getPastePatchAction() {
		return fPastePatchAction;
	}
}