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

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ui.IPreferenceIds;
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.registry.SynchronizeParticipantDescriptor;
import org.eclipse.team.internal.ui.registry.SynchronizeParticipantRegistry;
import org.eclipse.team.internal.ui.registry.SynchronizeWizardDescription;
import org.eclipse.team.internal.ui.registry.SynchronizeWizardRegistry;
import org.eclipse.team.ui.synchronize.ISynchronizeManager;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipant;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipantDescriptor;
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.IMemento;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.Saveable;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;

/**
 * Manages the registered synchronize participants. It handles notification of
 * participant lifecycles, creation of <code>static</code> participants, management
 * of dynamic participants, and the re-creation of persisted participants.
 * <p>
 * A participant is defined in a plugin manifest and can have several properties:
 * <ul>
 * <li>static: means that they always exist and don't have to be added to the manager
 * <li>dynamic: will be added to the manager at some later time
 * </ul>
 *
 * Part (title, id, icon, composite) - described in plugin.xml (IPartInstance)
 * Can have multiple parts of the same type at runtime -&gt; (IPart)
 * <ul>
 *   <li>must acquire a part (IPartInstance.createPart())
 *   <li>must released to part when done (IPartInstance.releasePart())
 * </ul>
 * Some parts can added dynamically to the registry and events are fired to listeners. Listeners can create the newly added part via
 * the #createPart() method.
 * Parts can be persisted/restored with some state
 *
 *
 * <p>
 * Lifecycle:
 * </p><p>
 * 	startup -&gt; registry read and stored in a participant instance
 *     createParticipant(id) -&gt;
 * 	releaseParticipant(IParticipantDescriptor) -&gt;
 *     getParticipantRegistry -&gt; return IParticipantDescriptors that describe the participants
 * 	shutdown -&gt; persist all settings
 * </p>
 *
 * @see ISynchronizeView
 * @see ISynchronizeParticipant
 * @since 3.0
 */
public class SynchronizeManager implements ISynchronizeManager {
	/**
	 * Synchronize participants listeners
	 */
	private ListenerList<ISynchronizeParticipantListener> fListeners = null;

	/**
	 * Contains the participant descriptions
	 */
	private SynchronizeParticipantRegistry participantRegistry = new SynchronizeParticipantRegistry();

	/**
	 * Contains the synchronize wizard descriptions
	 */
	private SynchronizeWizardRegistry wizardRegistry = new SynchronizeWizardRegistry();

	/**
	 * Contains a table of the state saved between sessions for a participant. The set is keyed
	 * as such {String key -&gt; ISynchronizeParticipantReference}.
	 */
	private Map<String, ISynchronizeParticipantReference> participantReferences = Collections.synchronizedMap(new HashMap<>(10));

	// change notification constants
	private final static int ADDED = 1;
	private final static int REMOVED = 2;

	// save context constants
	private final static String CTX_PARTICIPANTS = "syncparticipants"; //$NON-NLS-1$
	private final static String CTX_PARTICIPANT = "participant"; //$NON-NLS-1$
	private final static String CTX_ID = "id"; //$NON-NLS-1$
	private final static String CTX_SECONDARY_ID = "secondary_id"; //$NON-NLS-1$
	private final static String CTX_PARTICIPANT_DISPLAY_NAME = "displayName"; //$NON-NLS-1$
	private final static String CTX_PARTICIPANT_DATA = "data"; //$NON-NLS-1$
	private final static String FILENAME = "syncParticipants.xml"; //$NON-NLS-1$

	/**
	 * Notifies a participant listeners of additions or removals of participant references.
	 */
	class SynchronizeViewPageNotifier implements ISafeRunnable {

		private ISynchronizeParticipantListener fListener;
		private int fType;
		private ISynchronizeParticipant[] fChanged;

		@Override
		public void handleException(Throwable exception) {
			TeamUIPlugin.log(IStatus.ERROR, TeamUIMessages.SynchronizeManager_7, exception);
		}

		@Override
		public void run() throws Exception {
			switch (fType) {
				case ADDED :
					fListener.participantsAdded(fChanged);
					break;
				case REMOVED :
					fListener.participantsRemoved(fChanged);
					break;
			}
		}

		/**
		 * Notifies the given listener of the adds/removes
		 * @param participants the participants that changed
		 * @param update the type of change
		 */
		public void notify(ISynchronizeParticipant[] participants, int update) {
			if (fListeners == null) {
				return;
			}
			fChanged = participants;
			fType = update;
			Object[] copiedListeners = fListeners.getListeners();
			for (Object copiedListener : copiedListeners) {
				fListener = (ISynchronizeParticipantListener) copiedListener;
				SafeRunner.run(this);
			}
			fChanged = null;
			fListener = null;
		}
	}

	/**
	 * Represents a participant instance and allows lazy initialization of the instance
	 * only when the participant is required.
	 */
	private class ParticipantInstance implements ISynchronizeParticipantReference {
		private Map<String, ISynchronizeParticipant> participants;
		private IMemento savedState;
		private SynchronizeParticipantDescriptor descriptor;
		private String secondaryId;
		private String displayName;
		private boolean dead;

		public ParticipantInstance(SynchronizeParticipantDescriptor descriptor, String secondaryId, String displayName, IMemento savedState) {
			this.participants = new HashMap<>();
			this.secondaryId = secondaryId;
			this.savedState = savedState;
			this.descriptor = descriptor;
			this.displayName = displayName;
		}

		public void save(IMemento memento) {
			if (dead) return;
			String key = Utils.getKey(descriptor.getId(), getSecondaryId());
			ISynchronizeParticipant ref = participants.get(key);
			if(ref != null) {
				ref.saveState(memento);
			} else if(savedState != null) {
				memento.putMemento(savedState);
			}
		}

		@Override
		public boolean equals(Object other) {
			if(other == this) return true;
			if (! (other instanceof ISynchronizeParticipantReference)) return false;
			ISynchronizeParticipantReference otherRef = (ISynchronizeParticipantReference) other;
			String otherSecondaryId = otherRef.getSecondaryId();
			return otherRef.getId().equals(getId()) && Utils.equalObject(getSecondaryId(), otherSecondaryId);
		}

		@Override
		public String getId() {
			return descriptor.getId();
		}

		@Override
		public String getSecondaryId() {
			return secondaryId;
		}


		@Override
		public String getDisplayName() {
			String key = Utils.getKey(descriptor.getId(), getSecondaryId());
			ISynchronizeParticipant participant = participants.get(key);
			if(participant != null) {
				return participant.getName();
			}
			return displayName != null ? displayName : descriptor.getName();
		}

		public boolean isInstantiated() {
			String key = Utils.getKey(descriptor.getId(), getSecondaryId());
			return participants.get(key) != null;
		}

		@Override
		public ISynchronizeParticipant getParticipant() throws TeamException {
			if (dead) return null;
			String key = Utils.getKey(descriptor.getId(), getSecondaryId());
			try {
				ISynchronizeParticipant participant = participants.get(key);
				if (participant == null) {
					participant = instantiate();
					if(participant != null)
						participants.put(key, participant);
				}
				return participant;
			} catch (TeamException e) {
				TeamUIPlugin.log(e);
				participantReferences.remove(key);
				throw new TeamException(TeamUIMessages.SynchronizeManager_8, e);
			}
		}

		public void setParticipant(ISynchronizeParticipant participant) {
			String key = Utils.getKey(descriptor.getId(), getSecondaryId());
			participants.put(key, participant);
		}

		@Override
		public ISynchronizeParticipantDescriptor getDescriptor() {
			return descriptor;
		}

		private ISynchronizeParticipant instantiate() throws TeamException {
			try {
					ISynchronizeParticipant participant = (ISynchronizeParticipant) TeamUIPlugin.createExtension(descriptor.getConfigurationElement(), SynchronizeParticipantDescriptor.ATT_CLASS);
					participant.setInitializationData(descriptor.getConfigurationElement(), null, null);
					participant.init(getSecondaryId(), savedState);
					savedState = null;
					return participant;
				} catch (PartInitException e) {
					throw new TeamException(NLS.bind(TeamUIMessages.SynchronizeManager_11, new String[] { descriptor.getName() }), e);
				} catch (CoreException e) {
					throw TeamException.asTeamException(e);
				} catch(Exception e) {
					throw new TeamException(NLS.bind(TeamUIMessages.SynchronizeManager_11, new String[] { descriptor.getName() }), e);
				}
			}

		/**
		 * Dispose of the reference
		 */
		public void dispose() {
			try {
				ISynchronizeParticipant participant = getParticipant();
				if (participant != null)
					participant.dispose();
			} catch (TeamException e) {
				// Ignore since we are disposing anyway;
			} finally {
				dead = true;
			}
		}
	}

	public SynchronizeManager() {
		init();
	}

	@Override
	public void addSynchronizeParticipantListener(ISynchronizeParticipantListener listener) {
		if (fListeners == null) {
			fListeners = new ListenerList<>(ListenerList.IDENTITY);
		}
		fListeners.add(listener);
	}

	@Override
	public void removeSynchronizeParticipantListener(ISynchronizeParticipantListener listener) {
		if (fListeners != null) {
			fListeners.remove(listener);
		}
	}

	/**
	 * Creates a new participant reference with of the provided type. If the secondayId is specified it
	 * is used as the qualifier for multiple instances of the same type.
	 * <p>
	 * The returned participant reference is a light weight handle describing the participant. The plug-in
	 * defining the participant is not loaded. To instantiate a participant a client must call
	 * {@link ISynchronizeParticipantReference#createParticipant()} and must call
	 * {@link ISynchronizeParticipantReference#releaseParticipant()} when finished with the participant.
	 * </p>
	 * @param type the type of the participant
	 * @param secondaryId a unique id for multiple instance support
	 * @return a reference to a participant
	 */
	private ParticipantInstance createParticipantReference(String type, String secondaryId, String displayName) throws PartInitException {
		SynchronizeParticipantDescriptor desc = participantRegistry.find(type);
		// ensure that the view id is valid
		if (desc == null)
			throw new PartInitException(NLS.bind(TeamUIMessages.SynchronizeManager_19, new String[] { type }));
		// ensure that multiple instances are allowed if a secondary id is given
		if (secondaryId != null) {
//		    if (!desc.isMultipleInstances()) {
//				throw new PartInitException(Policy.bind("SynchronizeManager.20", type)); //$NON-NLS-1$
//		    }
		}
		String key = Utils.getKey(type, secondaryId);
		ParticipantInstance ref = (ParticipantInstance) participantReferences.get(key);
		if (ref == null) {
			ref = new ParticipantInstance(desc, secondaryId, displayName, null);
		}
		return ref;
	}

	@Override
	public synchronized void addSynchronizeParticipants(ISynchronizeParticipant[] participants) {
		// renamed to createSynchronizeParticipant(id)
		List<ISynchronizeParticipant> added = new ArrayList<>(participants.length);
		for (ISynchronizeParticipant participant : participants) {
			String key = Utils.getKey(participant.getId(), participant.getSecondaryId());
			if(! participantReferences.containsKey(key)) {
				try {
					ParticipantInstance ref = createParticipantReference(participant.getId(), participant.getSecondaryId(), participant.getName());
					ref.setParticipant(participant);
					removeMatchingParticipant(participant.getId());
					participantReferences.put(key, ref);
					added.add(participant);
				} catch (PartInitException e) {
					TeamUIPlugin.log(e);
					continue;
				}
			}
		}
		if (!added.isEmpty()) {
			saveState();
			fireUpdate(added.toArray(new ISynchronizeParticipant[added.size()]), ADDED);
		}
	}

	private void removeMatchingParticipant(String id) {
		ISynchronizeParticipantReference[] refs = get(id);
		if (refs.length > 0) {
			// Find an un-pinned participant and replace it
			for (ISynchronizeParticipantReference reference : refs) {
				ISynchronizeParticipant p;
				try {
					p = reference.getParticipant();
					if (!p.isPinned() && !isDirty(p)) {
						removeSynchronizeParticipants(new ISynchronizeParticipant[]{p});
						break;
					}
				} catch (TeamException e) {
					continue;
				}
			}
		}
	}

	private boolean isDirty(ISynchronizeParticipant p) {
		if (p instanceof ModelSynchronizeParticipant) {
			ModelSynchronizeParticipant msp = (ModelSynchronizeParticipant) p;
			Saveable s = msp.getActiveSaveable();
			if (s != null && s.isDirty()) {
				return true;
			}
		}
		return false;
	}

	@Override
	public synchronized void removeSynchronizeParticipants(ISynchronizeParticipant[] participants) {
		List<ISynchronizeParticipant> removed = new ArrayList<>(participants.length);
		for (ISynchronizeParticipant participant : participants) {
			String key = Utils.getKey(participant.getId(), participant.getSecondaryId());
			if(participantReferences.containsKey(key)) {
				ParticipantInstance ref = (ParticipantInstance)participantReferences.remove(key);
				if(ref.isInstantiated()) {
					ref.dispose();
				}
				removed.add(participant);
			}
		}
		if (!removed.isEmpty()) {
			saveState();
			fireUpdate(removed.toArray(new ISynchronizeParticipant[removed.size()]), REMOVED);
		}
	}

	@Override
	public ISynchronizeParticipantReference get(String id, String secondaryId) {
		String key = Utils.getKey(id, secondaryId);
		return participantReferences.get(key);
	}

	@Override
	public ISynchronizeParticipantReference[] get(String id) {
		ISynchronizeParticipantReference[] refs = getSynchronizeParticipants();
		ArrayList<ISynchronizeParticipantReference> refsForId = new ArrayList<>();
		for (ISynchronizeParticipantReference reference : refs) {
			if(reference.getId().equals(id)) {
				refsForId.add(reference);
			}
		}
		return refsForId.toArray(new ISynchronizeParticipantReference[refsForId.size()]);
	}

	@Override
	public synchronized ISynchronizeParticipantReference[] getSynchronizeParticipants() {
		return participantReferences.values().toArray(new ISynchronizeParticipantReference[participantReferences.values().size()]);
	}

	@Override
	public ISynchronizeView showSynchronizeViewInActivePage() {
		IWorkbench workbench = PlatformUI.getWorkbench();
		IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();

		boolean switchPerspectives = promptForPerspectiveSwitch();
		IWorkbenchPage activePage = null;
		if(switchPerspectives) {
			try {
				String pId = TeamUIPlugin.getPlugin().getPreferenceStore().getString(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE);
				activePage = workbench.showPerspective(pId, window);
			} catch (WorkbenchException e) {
				Utils.handleError(window.getShell(), e, TeamUIMessages.SynchronizeView_14, e.getMessage());
			}
		}
		try {
			if (activePage == null) {
				activePage = TeamUIPlugin.getActivePage();
				if (activePage == null)
					return null;
			}
			//IViewPart part = activePage.showView(ISynchronizeView.VIEW_ID, Long.toString(System.currentTimeMillis()), IWorkbenchPage.VIEW_ACTIVATE);
			IViewPart part = activePage.showView(ISynchronizeView.VIEW_ID);
			try {
				return (ISynchronizeView) part;
			} catch (ClassCastException e) {
				// Strange that we cannot cast the part (see bug 53671)
				TeamUIPlugin.log(IStatus.ERROR, NLS.bind(TeamUIMessages.SynchronizeManager_18, new String[] { part.getClass().getName() }), e);
				return null;
			}
		} catch (PartInitException pe) {
			Utils.handleError(window.getShell(), pe, TeamUIMessages.SynchronizeView_16, pe.getMessage());
			return null;
		}
	}

	/**
	 * Decides what action to take when switching perspectives and showing the synchronize view. Basically there are a
	 * set of user preferences that control how perspective switching.
	 */
	private boolean promptForPerspectiveSwitch() {
		// Decide if a prompt is even required
		IPreferenceStore store = TeamUIPlugin.getPlugin().getPreferenceStore();
		String option = store.getString(IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE);
		if(option.equals(MessageDialogWithToggle.ALWAYS)) {
			return true;
		} else if(option.equals(MessageDialogWithToggle.NEVER)) {
			return false;
		}

		// Otherwise determine if a prompt is required
		IPerspectiveRegistry registry= PlatformUI.getWorkbench().getPerspectiveRegistry();
		String defaultSyncPerspectiveId = store.getString(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE);
		IPerspectiveDescriptor perspectiveDescriptor = registry.findPerspectiveWithId(defaultSyncPerspectiveId);
		IWorkbenchPage page = TeamUIPlugin.getActivePage();
		if(page != null) {
			IPerspectiveDescriptor p = page.getPerspective();
			if(p != null && p.getId().equals(defaultSyncPerspectiveId)) {
				// currently in default perspective
				return false;
			}
		}

		if(perspectiveDescriptor != null) {

			String message;;
			String desc = perspectiveDescriptor.getDescription();
			if (desc == null) {
				message = NLS.bind(TeamUIMessages.SynchronizeManager_30, new String[] { perspectiveDescriptor.getLabel() });
			} else {
				message = NLS.bind(TeamUIMessages.SynchronizeManager_32, new String[] { perspectiveDescriptor.getLabel(), desc });
			}
			MessageDialogWithToggle m = MessageDialogWithToggle.openYesNoQuestion(Utils.getShell(null),
						TeamUIMessages.SynchronizeManager_27,
						message,
						TeamUIMessages.SynchronizeManager_31,
						false /* toggle state */,
						store,
						IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE);

			int result = m.getReturnCode();
			switch (result) {
				// yes, ok
				case IDialogConstants.YES_ID:
				case IDialogConstants.OK_ID :
					return true;
				// no
				case IDialogConstants.NO_ID :
					return false;
			}
		}
		return false;
	}

	/**
	 * Creates the participant registry and restore any saved participants.
	 * Will also instantiate any static participants.
	 */
	public void init() {
		try {
			// Initialize the participant registry - reads all participant extension descriptions.
			participantRegistry.readRegistry(Platform.getExtensionRegistry(), TeamUIPlugin.ID, SynchronizeParticipantRegistry.PT_SYNCPARTICIPANTS);
			// Initialize the wizard registry
			wizardRegistry.readRegistry(Platform.getExtensionRegistry(), TeamUIPlugin.ID, SynchronizeWizardRegistry.PT_SYNCHRONIZE_WIZARDS);

			// Instantiate and register any dynamic participants saved from a
			// previous session.
			restoreSavedParticipants();
		} catch (CoreException e) {
			TeamUIPlugin.log(new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, TeamUIMessages.SynchronizeManager_8, e));
		}
	}

	/**
	 * Allow participant instances to clean-up.
	 */
	public void dispose() {
		// save state and settings for existing participants.
		saveState();
		for (Iterator it = participantReferences.values().iterator(); it.hasNext();) {
			ParticipantInstance ref = (ParticipantInstance) it.next();
			if((ref).isInstantiated()) {
				try {
					ref.getParticipant().dispose();
				} catch (TeamException e) {
					continue;
				}
			}
		}
		participantReferences = null;
	}

	/**
	 * Restores participants that have been saved between sessions.
	 */
	private void restoreSavedParticipants() throws CoreException {
		File file = getStateFile();
		Reader reader;
		try {
			reader = new BufferedReader(new FileReader(file));
		} catch (FileNotFoundException e) {
			return;
		}
		IMemento memento = XMLMemento.createReadRoot(reader);
		IMemento[] participantNodes = memento.getChildren(CTX_PARTICIPANT);
		for (IMemento memento2 : participantNodes) {
			String id = memento2.getString(CTX_ID);
			String secondayId = memento2.getString(CTX_SECONDARY_ID);
			if (secondayId != null) {
				String displayName = memento2.getString(CTX_PARTICIPANT_DISPLAY_NAME);
				SynchronizeParticipantDescriptor desc = participantRegistry.find(id);
				if (desc != null) {
					String key = Utils.getKey(id, secondayId);
					participantReferences.put(key, new ParticipantInstance(desc, secondayId, displayName, memento2.getChild(CTX_PARTICIPANT_DATA)));
				} else {
					TeamUIPlugin.log(new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, NLS.bind(TeamUIMessages.SynchronizeManager_9, new String[] { id }), null));
				}
			}
		}
	}

	/**
	 * Saves a file containing the list of participant ids that are registered
	 * with this manager. Each initialized participant is also given the chance to save
	 * it's state.
	 */
	private void saveState() {
		XMLMemento xmlMemento = XMLMemento.createWriteRoot(CTX_PARTICIPANTS);
		for (Iterator it = participantReferences.values().iterator(); it.hasNext(); ) {
			ParticipantInstance ref = (ParticipantInstance) it.next();
			// Participants can opt out of being saved between sessions
			if(! ref.getDescriptor().isPersistent()) continue;
			// Create the state placeholder for a participant
			IMemento participantNode = xmlMemento.createChild(CTX_PARTICIPANT);
			participantNode.putString(CTX_ID, ref.getId());
			String secondaryId = ref.getSecondaryId();
			if(secondaryId != null) {
				participantNode.putString(CTX_SECONDARY_ID,secondaryId);
			}
			participantNode.putString(CTX_PARTICIPANT_DISPLAY_NAME, ref.getDisplayName());
			IMemento participantData = participantNode.createChild(CTX_PARTICIPANT_DATA);
			ref.save(participantData);
		}
		try {
			try (Writer writer = new BufferedWriter(new FileWriter(getStateFile()))) {
				xmlMemento.save(writer);
			}
		} catch (IOException e) {
			TeamUIPlugin.log(new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, TeamUIMessages.SynchronizeManager_10, e));
		}
	}

	private File getStateFile() {
		IPath pluginStateLocation = TeamUIPlugin.getPlugin().getStateLocation();
		return pluginStateLocation.append(FILENAME).toFile();
	}

	/**
	 * Fires notification.
	 *
	 * @param participants
	 *            participants added/removed
	 * @param type
	 *            ADDED or REMOVED
	 * @see SynchronizeManager#ADDED
	 * @see SynchronizeManager#REMOVED
	 */
	private void fireUpdate(ISynchronizeParticipant[] participants, int type) {
		new SynchronizeViewPageNotifier().notify(participants, type);
	}

	@Override
	public ISynchronizeParticipantDescriptor getParticipantDescriptor(String id) {
		return participantRegistry.find(id);
	}

	public SynchronizeWizardDescription[] getWizardDescriptors() {
		return wizardRegistry.getSynchronizeWizards();
	}
}
