/*******************************************************************************
 * 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.team.ui.synchronize;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.core.resources.mapping.IModelProviderDescriptor;
import org.eclipse.core.resources.mapping.ModelProvider;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.resources.mapping.ResourceMappingContext;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.preference.PreferenceStore;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.mapping.IMergeContext;
import org.eclipse.team.core.mapping.ISynchronizationContext;
import org.eclipse.team.core.mapping.ISynchronizationScope;
import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
import org.eclipse.team.core.mapping.provider.MergeContext;
import org.eclipse.team.core.mapping.provider.SynchronizationContext;
import org.eclipse.team.core.mapping.provider.SynchronizationScopeManager;
import org.eclipse.team.internal.core.subscribers.SubscriberDiffTreeEventHandler;
import org.eclipse.team.internal.ui.IPreferenceIds;
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.mapping.ModelEnablementPreferencePage;
import org.eclipse.team.internal.ui.mapping.ModelSynchronizePage;
import org.eclipse.team.internal.ui.preferences.SyncViewerPreferencePage;
import org.eclipse.team.internal.ui.synchronize.IRefreshSubscriberListener;
import org.eclipse.team.internal.ui.synchronize.IRefreshable;
import org.eclipse.team.internal.ui.synchronize.RefreshModelParticipantJob;
import org.eclipse.team.internal.ui.synchronize.RefreshParticipantJob;
import org.eclipse.team.internal.ui.synchronize.RefreshUserNotificationPolicy;
import org.eclipse.team.internal.ui.synchronize.StartupPreferencePage;
import org.eclipse.team.internal.ui.synchronize.SubscriberRefreshSchedule;
import org.eclipse.team.ui.TeamUI;
import org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter;
import org.eclipse.team.ui.mapping.ISynchronizationCompareInput;
import org.eclipse.team.ui.mapping.ITeamContentProviderDescriptor;
import org.eclipse.team.ui.mapping.ITeamContentProviderManager;
import org.eclipse.team.ui.mapping.SaveableComparison;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.IPageBookViewPage;
import org.eclipse.ui.progress.IProgressConstants2;

/**
 * Synchronize participant that obtains it's synchronization state from
 * a {@link ISynchronizationContext}.
 * <p>
 * This class may be subclassed by clients.
 *
 * @since 3.2
 */
public class ModelSynchronizeParticipant extends
		AbstractSynchronizeParticipant {

	/**
	 * Property constant used to store and retrieve the id of the active
	 * {@link ModelProvider} from an {@link ISynchronizePageConfiguration}. The
	 * active model provider will be the only one visible in the page. If
	 * <code>null</code> or <code>ALL_MODEL_PROVIDERS_ACTIVE</code> is
	 * returned, all model providers are considered active and are visible.
	 */
	public static final String P_VISIBLE_MODEL_PROVIDER = TeamUIPlugin.ID + ".activeModelProvider"; //$NON-NLS-1$

	/**
	 * Constant used with the <code>P_ACTIVE_MODEL_PROVIDER</code> property to indicate
	 * that all enabled model providers are active.
	 */
	public static final String ALL_MODEL_PROVIDERS_VISIBLE = TeamUIPlugin.ID + ".activeModelProvider"; //$NON-NLS-1$

	/**
	 * Property constant used during property change notification to indicate
	 * that the enabled model providers for this participant have changed.
	 */
	public static final String PROP_ENABLED_MODEL_PROVIDERS = TeamUIPlugin.ID + ".ENABLED_MODEL_PROVIDERS"; //$NON-NLS-1$

	/**
	 * Property constant used during property change notification to indicate
	 * that the active model of this participant has changed.
	 */
	public static final String PROP_ACTIVE_SAVEABLE = TeamUIPlugin.ID + ".ACTIVE_SAVEABLE"; //$NON-NLS-1$

	/**
	 * Property constant used during property change notification to indicate
	 * that the dirty state for the active saveable model of this participant has changed.
	 */
	public static final String PROP_DIRTY = TeamUIPlugin.ID + ".DIRTY"; //$NON-NLS-1$

	/*
	 * Key for settings in memento
	 */
	private static final String CTX_PARTICIPANT_SETTINGS = TeamUIPlugin.ID + ".MODEL_PARTICIPANT_SETTINGS"; //$NON-NLS-1$

	/*
	 * Key for schedule in memento
	 */
	private static final String CTX_REFRESH_SCHEDULE_SETTINGS = TeamUIPlugin.ID + ".MODEL_PARTICIPANT_REFRESH_SCHEDULE"; //$NON-NLS-1$

	/*
	 * Key for description in memento
	 */
	private static final String CTX_DESCRIPTION = TeamUIPlugin.ID + ".MODEL_PARTICIPANT_DESCRIPTION"; //$NON-NLS-1$

	/*
	 * Constants used to save and restore this scope
	 */
	private static final String CTX_PARTICIPANT_MAPPINGS = TeamUIPlugin.ID + ".MODEL_PARTICIPANT_MAPPINGS"; //$NON-NLS-1$
	private static final String CTX_MODEL_PROVIDER_ID = "modelProviderId"; //$NON-NLS-1$
	private static final String CTX_MODEL_PROVIDER_MAPPINGS = "mappings"; //$NON-NLS-1$
	private static final String CTX_STARTUP_ACTION = "startupAction"; //$NON-NLS-1$

	private SynchronizationContext context;
	private boolean mergingEnabled = true;
	private SubscriberRefreshSchedule refreshSchedule;
	private String description;
	private SaveableComparison activeSaveable;
	private PreferenceStore preferences = new PreferenceStore() {
		@Override
		public void save() throws IOException {
			// Nothing to do. Preference will be saved with participant.
		}
	};

	private IPropertyListener dirtyListener = (source, propId) -> {
		if (source instanceof SaveableComparison && propId == SaveableComparison.PROP_DIRTY) {
			SaveableComparison scm = (SaveableComparison) source;
			boolean isDirty = scm.isDirty();
			firePropertyChange(ModelSynchronizeParticipant.this, PROP_DIRTY, Boolean.valueOf(!isDirty), Boolean.valueOf(isDirty));
		}
	};

	/**
	 * Create a participant for the given context and name
	 * @param context the synchronization context
	 * @param name the name of the participant
	 * @return a participant for the given context
	 */
	public static ModelSynchronizeParticipant createParticipant(SynchronizationContext context, String name) {
		return new ModelSynchronizeParticipant(context, name);
	}

	/*
	 * Create a participant for the given context
	 * @param context the synchronization context
	 * @param name the name of the participant
	 */
	private ModelSynchronizeParticipant(SynchronizationContext context, String name) {
		initializeContext(context);
		try {
			setInitializationData(TeamUI.getSynchronizeManager().getParticipantDescriptor("org.eclipse.team.ui.synchronization_context_synchronize_participant")); //$NON-NLS-1$
		} catch (CoreException e) {
			TeamUIPlugin.log(e);
		}
		setSecondaryId(Long.toString(System.currentTimeMillis()));
		setName(name);
		refreshSchedule = new SubscriberRefreshSchedule(createRefreshable());
	}

	/**
	 * Create a participant for the given context
	 * @param context the synchronization context
	 */
	public ModelSynchronizeParticipant(SynchronizationContext context) {
		initializeContext(context);
		refreshSchedule = new SubscriberRefreshSchedule(createRefreshable());
	}

	/**
	 * Create a participant in order to restore it from saved state.
	 */
	public ModelSynchronizeParticipant() {
	}

	@Override
	public String getName() {
		String name = super.getName();
		if (description == null)
			description = Utils.getScopeDescription(getContext().getScope());
		return NLS.bind(TeamUIMessages.SubscriberParticipant_namePattern, new String[] { name, description });
	}

	/**
	 * Return the name of the participant as specified in the plugin manifest file.
	 * This method is provided to give access to this name since it is masked by
	 * the <code>getName()</code> method defined in this class.
	 * @return the name of the participant as specified in the plugin manifest file
	 * @since 3.1
	 */
	protected final String getShortName() {
		return super.getName();
	}

	@Override
	protected void initializeConfiguration(
			ISynchronizePageConfiguration configuration) {
		if (isMergingEnabled()) {
			// The context menu groups are defined by the org.eclipse.ui.navigator.viewer extension
			configuration.addMenuGroup(ISynchronizePageConfiguration.P_TOOLBAR_MENU, ModelSynchronizeParticipantActionGroup.MERGE_ACTION_GROUP);
			configuration.addActionContribution(createMergeActionGroup());
		}
		configuration.setSupportedModes(ISynchronizePageConfiguration.ALL_MODES);
		configuration.setMode(ISynchronizePageConfiguration.BOTH_MODE);
		configuration.setProperty(ITeamContentProviderManager.P_SYNCHRONIZATION_CONTEXT, getContext());
		configuration.setProperty(ITeamContentProviderManager.P_SYNCHRONIZATION_SCOPE, getContext().getScope());
		if (getHandler() != null)
			configuration.setProperty(StartupPreferencePage.STARTUP_PREFERENCES, preferences);
	}

	/**
	 * Create the merge action group for this participant.
	 * Subclasses can override in order to provide a
	 * merge action group that configures certain aspects
	 * of the merge actions.
	 * @return the merge action group for this participant
	 */
	protected ModelSynchronizeParticipantActionGroup createMergeActionGroup() {
		return new ModelSynchronizeParticipantActionGroup();
	}

	@Override
	public final IPageBookViewPage createPage(
			ISynchronizePageConfiguration configuration) {
		return new ModelSynchronizePage(configuration);
	}

	@Override
	public void run(IWorkbenchPart part) {
		refresh(part != null ? part.getSite() : null, context.getScope().getMappings());
	}

	/**
	 * Refresh a participant in the background the result of the refresh are shown in the progress view. Refreshing
	 * can also be considered synchronizing, or refreshing the synchronization state. Basically this is a long
	 * running operation that will update the participant's context with new changes detected on the
	 * server.
	 *
	 * @param site the workbench site the synchronize is running from. This can be used to notify the site
	 * that a job is running.
	 * @param mappings the resource mappings to be refreshed
	 */
	public final void refresh(IWorkbenchSite site, ResourceMapping[] mappings) {
		IRefreshSubscriberListener listener = new RefreshUserNotificationPolicy(this);
		internalRefresh(mappings, null, null, site, listener);
	}

	@Override
	public void dispose() {
		context.dispose();
		Job.getJobManager().cancel(this);
		refreshSchedule.dispose();
	}

	/**
	 * Set the context of this participant. This method must be invoked
	 * before a page is obtained from the participant.
	 * @param context the context for this participant
	 */
	protected void initializeContext(SynchronizationContext context) {
		this.context = context;
		mergingEnabled = context instanceof IMergeContext;
		SubscriberDiffTreeEventHandler handler = getHandler();
		if (handler != null) {
			preferences.setDefault(StartupPreferencePage.PROP_STARTUP_ACTION, StartupPreferencePage.STARTUP_ACTION_NONE);
			if (isSynchronizeOnStartup()) {
				run(null); // TODO: Would like to get the Sync view part if possible
			} else if (isPopulateOnStartup()) {
				handler.initializeIfNeeded();
			}
		}
	}

	private boolean isPopulateOnStartup() {
		String pref = preferences.getString(StartupPreferencePage.PROP_STARTUP_ACTION);
		return pref != null && pref.equals(StartupPreferencePage.STARTUP_ACTION_POPULATE);
	}

	private boolean isSynchronizeOnStartup() {
		String pref = preferences.getString(StartupPreferencePage.PROP_STARTUP_ACTION);
		return pref != null && pref.equals(StartupPreferencePage.STARTUP_ACTION_SYNCHRONIZE);
	}

	/**
	 * Return the synchronization context for this participant.
	 * @return the synchronization context for this participant
	 */
	public ISynchronizationContext getContext() {
		return context;
	}

	/**
	 * Return a compare input for the given model object or <code>null</code>
	 * if the object is not eligible for comparison.
	 * @param object the model object
	 * @return a compare input for the model object or <code>null</code>
	 */
	public ICompareInput asCompareInput(Object object) {
		if (object instanceof ICompareInput) {
			return (ICompareInput) object;
		}
		// Get a compare input from the model provider's compare adapter
		ISynchronizationCompareAdapter adapter = Utils.getCompareAdapter(object);
		if (adapter != null)
			return adapter.asCompareInput(getContext(), object);
		return null;
	}

	/**
	 * Return whether their is a compare input associated with the given object.
	 * In other words, return <code>true</code> if {@link #asCompareInput(Object) }
	 * would return a value and <code>false</code> if it would return <code>null</code>.
	 * @param object the object.
	 * @return whether their is a compare input associated with the given object
	 */
	public boolean hasCompareInputFor(Object object) {
		// Get a content viewer from the model provider's compare adapter
		ISynchronizationCompareAdapter adapter = Utils.getCompareAdapter(object);
		if (adapter != null)
			return adapter.hasCompareInput(getContext(), object);
		return false;
	}

	/**
	 * Return whether merge capabilities are enabled for this participant.
	 * If merging is enabled, merge actions can be shown. If merging is disabled, no
	 * merge actions should be surfaced.
	 * @return whether merge capabilities should be enabled for this participant
	 */
	public boolean isMergingEnabled() {
		return mergingEnabled;
	}

	/**
	 * Set whether merge capabilities should be enabled for this participant.
	 * @param mergingEnabled whether merge capabilities should be enabled for this participant
	 */
	public void setMergingEnabled(boolean mergingEnabled) {
		this.mergingEnabled = mergingEnabled;
	}

	private void internalRefresh(ResourceMapping[] mappings, String jobName, String taskName, IWorkbenchSite site, IRefreshSubscriberListener listener) {
		if (jobName == null)
			jobName = getShortTaskName();
		if (taskName == null)
			taskName = getLongTaskName(mappings);
		Job.getJobManager().cancel(this);
		RefreshParticipantJob job = new RefreshModelParticipantJob(this, jobName, taskName, mappings, listener);
		job.setUser(true);
		job.setProperty(IProgressConstants2.SHOW_IN_TASKBAR_ICON_PROPERTY, Boolean.TRUE);
		Utils.schedule(job, site);

		// Remember the last participant synchronized
		TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT, getId());
		TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT_SEC_ID, getSecondaryId());
	}

	/**
	 * Returns the short task name (e.g. no more than 25 characters) to describe
	 * the behavior of the refresh operation to the user. This is typically
	 * shown in the status line when this participant is refreshed in the
	 * background. When refreshed in the foreground, only the long task name is
	 * shown.
	 *
	 * @return the short task name to show in the status line.
	 */
	protected String getShortTaskName() {
		return NLS.bind(TeamUIMessages.Participant_synchronizingDetails, getShortName());
	}

	/**
	 * Returns the long task name to describe the behavior of the refresh
	 * operation to the user. This is typically shown in the status line when
	 * this subscriber is refreshed in the background.
	 *
	 * @param mappings the mappings being refreshed
	 * @return the long task name
	 * @since 3.1
	 */
	protected String getLongTaskName(ResourceMapping[] mappings) {
		if (mappings == null) {
			// If the mappings are null, assume we are refreshing everything
			mappings = getContext().getScope().getMappings();
		}
		int mappingCount = mappings.length;
		if (mappingCount == getContext().getScope().getMappings().length) {
			// Assume we are refreshing everything and only use the input mapping count
			mappings = getContext().getScope().getInputMappings();
			mappingCount = mappings.length;
		}
		if (mappingCount == 1) {
			return NLS.bind(TeamUIMessages.Participant_synchronizingMoreDetails, new String[] { getShortName(), Utils.getLabel(mappings[0]) });
		}
		return NLS.bind(TeamUIMessages.Participant_synchronizingResources, new String[] { getShortName(), Integer.toString(mappingCount) });
	}

	private IRefreshable createRefreshable() {
		return new IRefreshable() {

			@Override
			public RefreshParticipantJob createJob(String interval) {
				String jobName = NLS.bind(TeamUIMessages.RefreshSchedule_15, new String[] { ModelSynchronizeParticipant.this.getName(), interval });
				return new RefreshModelParticipantJob(ModelSynchronizeParticipant.this,
						jobName,
						jobName,
						context.getScope().getMappings(),
						new RefreshUserNotificationPolicy(ModelSynchronizeParticipant.this));
			}
			@Override
			public ISynchronizeParticipant getParticipant() {
				return ModelSynchronizeParticipant.this;
			}
			@Override
			public void setRefreshSchedule(SubscriberRefreshSchedule schedule) {
				ModelSynchronizeParticipant.this.setRefreshSchedule(schedule);
			}
			@Override
			public SubscriberRefreshSchedule getRefreshSchedule() {
				return refreshSchedule;
			}

		};
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if (adapter == IRefreshable.class && refreshSchedule != null) {
			return (T) refreshSchedule.getRefreshable();

		}
		if (adapter == SubscriberRefreshSchedule.class) {
			return (T) refreshSchedule;
		}
		return super.getAdapter(adapter);
	}

	@Override
	public void saveState(IMemento memento) {
		super.saveState(memento);
		IMemento settings = memento.createChild(CTX_PARTICIPANT_SETTINGS);
		if (description != null)
			settings.putString(CTX_DESCRIPTION, description);
		refreshSchedule.saveState(settings.createChild(CTX_REFRESH_SCHEDULE_SETTINGS));
		saveMappings(settings);
		settings.putString(CTX_STARTUP_ACTION, preferences.getString(StartupPreferencePage.PROP_STARTUP_ACTION));
	}

	private void saveMappings(IMemento settings) {
		ISynchronizationScope inputScope = getContext().getScope().asInputScope();
		ModelProvider[] providers = inputScope.getModelProviders();
		for (int i = 0; i < providers.length; i++) {
			ModelProvider provider = providers[i];
			ISynchronizationCompareAdapter adapter = Utils.getCompareAdapter(provider);
			if (adapter != null) {
				IMemento child = settings.createChild(CTX_PARTICIPANT_MAPPINGS);
				String id = provider.getDescriptor().getId();
				child.putString(CTX_MODEL_PROVIDER_ID, id);
				adapter.save(inputScope.getMappings(id), child.createChild(CTX_MODEL_PROVIDER_MAPPINGS));
			}
		}
	}

	@Override
	public void init(String secondaryId, IMemento memento) throws PartInitException {
		super.init(secondaryId, memento);
		if(memento != null) {
			IMemento settings = memento.getChild(CTX_PARTICIPANT_SETTINGS);
			String startupAction = settings.getString(StartupPreferencePage.PROP_STARTUP_ACTION);
			if (startupAction != null)
				preferences.putValue(StartupPreferencePage.PROP_STARTUP_ACTION, startupAction);
			ResourceMapping[] mappings = loadMappings(settings);
			if (mappings.length == 0)
				throw new PartInitException(NLS.bind(TeamUIMessages.ModelSynchronizeParticipant_0, getId()));
			initializeContext(mappings);
			if(settings != null) {
				SubscriberRefreshSchedule schedule = SubscriberRefreshSchedule.init(settings.getChild(CTX_REFRESH_SCHEDULE_SETTINGS), createRefreshable());
				description = settings.getString(CTX_DESCRIPTION);
				setRefreshSchedule(schedule);
				if(schedule.isEnabled()) {
					schedule.startJob();
				}
			}
		}
	}

	private ResourceMapping[] loadMappings(IMemento settings) throws PartInitException {
		List<ResourceMapping> result = new ArrayList<>();
		IMemento[] children = settings.getChildren(CTX_PARTICIPANT_MAPPINGS);
		for (int i = 0; i < children.length; i++) {
			IMemento memento = children[i];
			String id = memento.getString(CTX_MODEL_PROVIDER_ID);
			if (id != null) {
				IModelProviderDescriptor desc = ModelProvider.getModelProviderDescriptor(id);
				try {
					ModelProvider provider = desc.getModelProvider();
					ISynchronizationCompareAdapter adapter = Utils.getCompareAdapter(provider);
					if (adapter != null) {
						ResourceMapping[] mappings = adapter.restore(memento.getChild(CTX_MODEL_PROVIDER_MAPPINGS));
						for (int j = 0; j < mappings.length; j++) {
							ResourceMapping mapping = mappings[j];
							result.add(mapping);
						}
					}
				} catch (CoreException e) {
					TeamUIPlugin.log(e);
				}
			}
		}
		return result.toArray(new ResourceMapping[result.size()]);
	}

	private void initializeContext(ResourceMapping[] mappings) throws PartInitException {
		try {
			ISynchronizationScopeManager manager = createScopeManager(mappings);
			MergeContext context = restoreContext(manager);
			initializeContext(context);
		} catch (CoreException e) {
			TeamUIPlugin.log(e);
			throw new PartInitException(e.getStatus());
		}
	}

	/**
	 * Recreate the context for this participant. This method is invoked when
	 * the participant is restored after a restart. Although it is provided
	 * with a progress monitor, long running operations should be avoided.
	 * @param manager the restored scope
	 * @return the context for this participant
	 * @throws CoreException
	 */
	protected MergeContext restoreContext(ISynchronizationScopeManager manager) throws CoreException {
		throw new PartInitException(NLS.bind(TeamUIMessages.ModelSynchronizeParticipant_1, getId()));
	}

	/**
	 * Create and return a scope manager that can be used to build the scope of this
	 * participant when it is restored after a restart. By default, this method
	 * returns a scope manager that uses the local content.
	 * This method can be overridden by subclasses.
	 *
	 * @param mappings the restored mappings
	 * @return a scope manager that can be used to build the scope of this
	 * participant when it is restored after a restart
	 */
	protected ISynchronizationScopeManager createScopeManager(ResourceMapping[] mappings) {
		return new SynchronizationScopeManager(super.getName(), mappings, ResourceMappingContext.LOCAL_CONTEXT, true);
	}

	/* private */ void setRefreshSchedule(SubscriberRefreshSchedule schedule) {
		if (refreshSchedule != schedule) {
			if (refreshSchedule != null) {
				refreshSchedule.dispose();
			}
			this.refreshSchedule = schedule;
		}
		// Always fir the event since the schedule may have been changed
		firePropertyChange(this, AbstractSynchronizeParticipant.P_SCHEDULED, schedule, schedule);
	}

	/**
	 * Return the active saveable for this participant.
	 * There is at most one saveable active at any
	 * time.
	 * @return the active saveable for this participant
	 * or <code>null</code>
	 */
	public SaveableComparison getActiveSaveable() {
		return activeSaveable;
	}

	/**
	 * Set the active saveable of this participant.
	 * @param activeSaveable the active saveable (may be <code>null</code>)
	 */
	public void setActiveSaveable(SaveableComparison activeSaveable) {
		boolean wasDirty = false;
		SaveableComparison oldModel = this.activeSaveable;
		if (oldModel != null) {
			oldModel.removePropertyListener(dirtyListener);
			wasDirty = oldModel.isDirty();
		}
		this.activeSaveable = activeSaveable;
		firePropertyChange(this, PROP_ACTIVE_SAVEABLE, oldModel, activeSaveable);
		boolean isDirty = false;
		if (activeSaveable != null) {
			activeSaveable.addPropertyListener(dirtyListener);
			isDirty = activeSaveable.isDirty();
		}
		if (isDirty != wasDirty)
			firePropertyChange(this, PROP_DIRTY, Boolean.valueOf(wasDirty), Boolean.valueOf(isDirty));
	}

	/**
	 * Convenience method for switching the active saveable of this participant
	 * to the saveable of the given input.
	 * @param shell a shell
	 * @param input the compare input about to be displayed
	 * @param cancelAllowed whether the display of the compare input can be canceled
	 * @param monitor a progress monitor or <code>null</code> if progress reporting is not required
	 * @return whether the user choose to continue with the display of the given compare input
	 * @throws CoreException
	 */
	public boolean checkForBufferChange(Shell shell, ISynchronizationCompareInput input, boolean cancelAllowed, IProgressMonitor monitor) throws CoreException {
		SaveableComparison currentBuffer = getActiveSaveable();
		SaveableComparison targetBuffer = input.getSaveable();
		if (monitor == null)
			monitor = new NullProgressMonitor();
		try {
			ModelParticipantAction.handleTargetSaveableChange(shell, targetBuffer, currentBuffer, cancelAllowed, Policy.subMonitorFor(monitor, 10));
		} catch (InterruptedException e) {
			return false;
		}
		setActiveSaveable(targetBuffer);
		return true;
	}

	/**
	 * Return the list of model providers that are enabled for the participant.
	 * By default, the list is those model providers that contain mappings
	 * in the scope. Subclasses may override to add additional model providers.
	 * @return the list of model providers that are active for the participant
	 */
	public ModelProvider[] getEnabledModelProviders() {
		return getContext().getScope().getModelProviders();
	}

	@Override
	public PreferencePage[] getPreferencePages() {
		List<PreferencePage> pages = new ArrayList<>();
		SyncViewerPreferencePage syncViewerPreferencePage = new SyncViewerPreferencePage();
		syncViewerPreferencePage.setIncludeDefaultLayout(false);
		pages.add(syncViewerPreferencePage);
		pages.add(new ModelEnablementPreferencePage());
		ITeamContentProviderDescriptor[] descriptors = TeamUI.getTeamContentProviderManager().getDescriptors();
		for (int i = 0; i < descriptors.length; i++) {
			ITeamContentProviderDescriptor descriptor = descriptors[i];
			if (isIncluded(descriptor)) {
				try {
					PreferencePage page = (PreferencePage)descriptor.createPreferencePage();
					if (page != null) {
						pages.add(page);
					}
				} catch (CoreException e) {
					TeamUIPlugin.log(e);
				}
			}
		}
		if (getHandler() != null) {
			pages.add(new StartupPreferencePage(preferences));
		}
		return pages.toArray(new PreferencePage[pages.size()]);
	}

	private boolean isIncluded(ITeamContentProviderDescriptor descriptor) {
		ModelProvider[] providers = getEnabledModelProviders();
		for (int i = 0; i < providers.length; i++) {
			ModelProvider provider = providers[i];
			if (provider.getId().equals(descriptor.getModelProviderId())) {
				return true;
			}
		}
		return false;
	}

	private SubscriberDiffTreeEventHandler getHandler() {
		return Adapters.adapt(context, SubscriberDiffTreeEventHandler.class);
	}

}
