/*******************************************************************************
 * Copyright (c) 2014, 2016 Obeo and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Obeo - initial API and implementation
 *     Philip Langer - bugs 461713, 465331, 470268, 476363, 476417, 486940, refactorings
 *     Alexandra Buzila - bugs 470332, 478620
 *     Stefan Dirix - bug 507050
 *******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.logical;

import static com.google.common.base.Predicates.alwaysFalse;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Conflict;
import org.eclipse.emf.compare.ConflictKind;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.EMFCompare.Builder;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
import org.eclipse.emf.compare.ide.ui.internal.preferences.EMFCompareUIPreferences;
import org.eclipse.emf.compare.ide.ui.logical.IModelMinimizer;
import org.eclipse.emf.compare.ide.ui.logical.SynchronizationModel;
import org.eclipse.emf.compare.ide.utils.ResourceUtil;
import org.eclipse.emf.compare.ide.utils.StorageTraversal;
import org.eclipse.emf.compare.merge.BatchMerger;
import org.eclipse.emf.compare.merge.ComputeDiffsToMerge;
import org.eclipse.emf.compare.merge.IBatchMerger;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.merge.IMerger.Registry2;
import org.eclipse.emf.compare.merge.MergeBlockedByConflictException;
import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
import org.eclipse.emf.compare.rcp.internal.extension.impl.EMFCompareBuilderConfigurator;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.mapping.IMergeContext;
import org.eclipse.team.core.mapping.IResourceMappingMerger;
import org.eclipse.team.core.mapping.provider.MergeStatus;

/*
 * Illegally implements IResourceMappingMerger, but we need none of the behavior from the abstract
 * ResourceMappingMerger. Filtered in the API filters.
 */
/**
 * A customized merger for the {@link EMFResourceMapping}s. This will use EMF Compare to recompute the logical
 * model of the mappings it needs to merge, then merge everything to the left model if there are no conflicts,
 * stopping dead if there is any conflict.
 * <p>
 * Mapping mergers are usually retrieved through an adapter registered on the ModelProvider. In this case,
 * {@code org.eclipse.core.runtime.Platform.getAdapterManager().getAdapter(emfModelProvider, IResourceMappingMerger.class)}
 * .
 * </p>
 * 
 * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
 * @see EMFLogicalModelAdapterFactory
 */
public class EMFResourceMappingMerger implements IResourceMappingMerger {

	/** The merger registry. */
	protected static final Registry2 MERGER_REGISTRY = (Registry2)EMFCompareRCPPlugin.getDefault()
			.getMergerRegistry();

	/** {@inheritDoc} */
	public IStatus merge(IMergeContext mergeContext, IProgressMonitor monitor) throws CoreException {
		final ResourceMapping[] emfMappings = getEMFMappings(mergeContext);
		log(IStatus.OK, "EMFResourceMappingMerger.startingModelMerge", emfMappings); //$NON-NLS-1$
		IStatus shortcutStatus = Status.OK_STATUS;
		if (emfMappings.length <= 0) {
			shortcutStatus = new Status(IStatus.ERROR, EMFCompareIDEUIPlugin.PLUGIN_ID,
					EMFCompareIDEUIMessages.getString("EMFResourceMappingMerger.mergeFailedGeneric")); //$NON-NLS-1$
		} else {
			shortcutStatus = validateMappings(emfMappings);
		}
		if (shortcutStatus.getSeverity() != IStatus.OK) {
			return shortcutStatus;
		}

		// Use a sub-monitor with 10 ticks per child
		// For the time being, Cancel is not supported here because reverting changes is problematic
		SubMonitor subMonitor = SubMonitor.convert(monitor, emfMappings.length);
		try {
			final Set<ResourceMapping> failingMappings = new HashSet<ResourceMapping>();
			for (ResourceMapping mapping : emfMappings) {
				mergeMapping(mapping, mergeContext, failingMappings, subMonitor.newChild(1));
			}

			IStatus status = Status.OK_STATUS;
			if (!failingMappings.isEmpty()) {
				final ResourceMapping[] failingArray = failingMappings
						.toArray(new ResourceMapping[failingMappings.size()]);
				status = new MergeStatus(EMFCompareIDEUIPlugin.PLUGIN_ID,
						EMFCompareIDEUIMessages.getString("EMFResourceMappingMerger.mergeFailedConflicts"), //$NON-NLS-1$
						failingArray);
			} else {
				log(IStatus.OK, "EMFResourceMappingMerger.successfulModelMerge", emfMappings); //$NON-NLS-1$
			}
			return status;
		} finally {
			if (monitor != null) {
				monitor.done();
			}
		}
	}

	/**
	 * Logs the EMFCompareIDEUIPlugin message for the given {@code key} with the given severity
	 * {@code statusCode} and {@code emfMappings}.
	 * 
	 * @param statusCode
	 *            Status code must be one of {@link IStatus}.
	 * @param key
	 *            Message key for EMFCompareIDEUIPlugin.
	 * @param emfMappings
	 *            The resource mappings to log.
	 */
	private void log(int statusCode, String key, ResourceMapping[] emfMappings) {
		final List<IResource> iResources = getInvolvedIResources(emfMappings);
		final String message = EMFCompareIDEUIMessages.getString(key, String.valueOf(iResources.size()));
		log(statusCode, message, iResources);
	}

	/**
	 * Logs the given {@code message} and the given {@code iResources} with the given severity
	 * {@code statusCode}.
	 * <p>
	 * The logged status is a {@link MultiStatus}, having the given {@code message} as a parent status and the
	 * names of the provided {@code iResources} as child statuses.
	 * </p>
	 * 
	 * @param statusCode
	 *            Status code must be one of {@link IStatus}.
	 * @param message
	 *            The message to be logged.
	 * @param iResources
	 *            The resources to be added as child status.
	 */
	private void log(int statusCode, String message, Collection<IResource> iResources) {
		final MultiStatus multiStatus = new MultiStatus(EMFCompareIDEUIPlugin.PLUGIN_ID, 0, message, null);
		for (IResource iResource : iResources) {
			final Status childStatus = new Status(statusCode, EMFCompareIDEUIPlugin.PLUGIN_ID,
					iResource.getFullPath().toOSString());
			multiStatus.add(childStatus);
		}
		log(multiStatus);
	}

	/**
	 * Returns the {@link IResource resources} involved in the given {@code emfMappings}.
	 * 
	 * @param emfMappings
	 *            The resource mappings to get the involved resources from.
	 * @return The resources involved in {@code emfMappings}.
	 */
	private List<IResource> getInvolvedIResources(ResourceMapping[] emfMappings) {
		final List<IResource> iResources = new ArrayList<IResource>();
		for (ResourceMapping mapping : emfMappings) {
			if (mapping instanceof EMFResourceMapping) {
				final SynchronizationModel syncModel = ((EMFResourceMapping)mapping).getLatestModel();
				for (IResource iResource : syncModel.getResources()) {
					iResources.add(iResource);
				}
			}
		}
		return iResources;
	}

	/**
	 * Logs the given {@code status} to the log of {@link EMFCompareIDEUIPlugin}.
	 * 
	 * @param status
	 *            The {@link IStatus} to log.
	 */
	private void log(IStatus status) {
		EMFCompareIDEUIPlugin.getDefault().getLog().log(status);
	}

	/**
	 * Merges one mapping.
	 * 
	 * @param mapping
	 *            The mapping to merge
	 * @param mergeContext
	 *            The merge context
	 * @param failingMappings
	 *            The set of failing mappings
	 * @param monitor
	 *            The progress monitor to use, 10 ticks will be consumed
	 */
	protected void mergeMapping(ResourceMapping mapping, final IMergeContext mergeContext,
			final Set<ResourceMapping> failingMappings, IProgressMonitor monitor) throws CoreException {
		final SubMonitor subMonitor = SubMonitor.convert(monitor, 10);
		// validateMappings() has made sure we only have EMFResourceMappings
		final SynchronizationModel syncModel = ((EMFResourceMapping)mapping).getLatestModel();
		// we may have non-existing storages in the left traversal, so let's get rid of them
		removeNonExistingStorages(syncModel.getLeftTraversal());
		// get the involved resources before we run the minimizer
		final Set<IResource> resources = Sets.newLinkedHashSet(syncModel.getResources());

		final IModelMinimizer minimizer = new IdenticalResourceMinimizer();
		minimizer.minimize(syncModel, subMonitor.newChild(1)); // 10%
		final IComparisonScope scope = ComparisonScopeBuilder.create(syncModel, subMonitor.newChild(3)); // 40%

		final Builder builder = EMFCompare.builder();
		EMFCompareBuilderConfigurator.createDefault().configure(builder);

		final Comparison comparison = builder.build().compare(scope,
				BasicMonitor.toMonitor(SubMonitor.convert(subMonitor.newChild(1), 10))); // 50%

		if (hasRealConflict(comparison)) {
			failingMappings.add(mapping);

			final IPreferenceStore store = EMFCompareIDEUIPlugin.getDefault().getPreferenceStore();
			boolean preMerge = store.getBoolean(EMFCompareUIPreferences.PRE_MERGE_MODELS_WHEN_CONFLICT);

			if (preMerge) {
				final Set<URI> conflictingURIs = performPreMerge(comparison, subMonitor.newChild(3)); // 80%
				save(scope.getLeft(), syncModel.getLeftTraversal(), syncModel.getRightTraversal(),
						syncModel.getOriginTraversal());
				markResourcesAsMerged(mergeContext, resources, conflictingURIs, subMonitor.newChild(2));
			}
		} else {
			final ResourceAdditionAndDeletionTracker resourceTracker = new ResourceAdditionAndDeletionTracker();
			try {
				scope.getLeft().eAdapters().add(resourceTracker);
				performBatchMerge(comparison, subMonitor.newChild(3)); // 80%
				save(scope.getLeft(), syncModel.getLeftTraversal(), syncModel.getRightTraversal(),
						syncModel.getOriginTraversal());
				delegateMergeOfUnmergedResourcesAndMarkDiffsAsMerged(syncModel, mergeContext, resourceTracker,
						subMonitor.newChild(2)); // 100%
			} finally {
				scope.getLeft().eAdapters().remove(resourceTracker);
			}
		}

		subMonitor.setWorkRemaining(0);
	}

	/**
	 * Removes storages that do not exist from the specified {@code traversal}.
	 * <p>
	 * In the current implementation, the check for existence is based on the assumption that the storage is
	 * an {@link IFile}. This is fine, since we currently need it on the local side only anyways.
	 * </p>
	 * 
	 * @param traversal
	 *            The traversal to remove non-existing storages from.
	 */
	protected void removeNonExistingStorages(StorageTraversal traversal) {
		for (IStorage storage : traversal.getStorages()) {
			if (storage instanceof IFile && !((IFile)storage).exists()) {
				traversal.removeStorage(storage);
			}
		}
	}

	/**
	 * Performs a pre-merge of the given {@code comparison}.
	 * <p>
	 * A pre-merge is a merge that performs all non-conflicting changes but omits conflicting changes or
	 * changes that depend on conflicting changes.
	 * </p>
	 * 
	 * @param comparison
	 *            The comparison to pre-merge.
	 * @param subMonitor
	 *            The progress monitor to use.
	 * @return the set of the uri for resources on which conflicts were not auto-mergeable.
	 */
	private Set<URI> performPreMerge(Comparison comparison, SubMonitor subMonitor) {
		final Monitor emfMonitor = BasicMonitor.toMonitor(subMonitor);
		final Set<URI> conflictingURIs = new LinkedHashSet<URI>();
		for (Diff next : comparison.getDifferences()) {
			doMergeForDiff(emfMonitor, conflictingURIs, next);
		}
		return conflictingURIs;
	}

	protected void doMergeForDiff(Monitor emfMonitor, Set<URI> conflictingURIs, Diff diff) {
		ComputeDiffsToMerge computer = new ComputeDiffsToMerge(true, MERGER_REGISTRY)
				.failOnRealConflictUnless(alwaysFalse());
		try {
			Set<Diff> diffsToMerge = computer.getAllDiffsToMerge(diff);
			for (Diff toMerge : diffsToMerge) {
				final IMerger merger = MERGER_REGISTRY.getHighestRankingMerger(toMerge);
				merger.copyRightToLeft(toMerge, emfMonitor);
			}
		} catch (MergeBlockedByConflictException e) {
			conflictingURIs.addAll(collectConflictingResources(e.getConflictingDiffs().iterator()));
		}
	}

	/**
	 * Iterates over the given diffs to collect the resources they impact. This will be called in case of
	 * conflicts in order to know exactly which resources should be marked as conflicting.
	 * 
	 * @param diffIterator
	 *            Iterator over the conflicting differences and their dependent diffs.
	 * @return The uris of all resources impacted by conflicting differences.
	 */
	protected Set<URI> collectConflictingResources(Iterator<Diff> diffIterator) {
		final Set<URI> conflictingURIs = new LinkedHashSet<URI>();
		while (diffIterator.hasNext()) {
			final Diff diff = diffIterator.next();
			final ImmutableSet.Builder<Diff> builder = ImmutableSet.builder();
			if (diff.getConflict() != null) {
				builder.addAll(diff.getConflict().getDifferences()).add(diff);
				for (Diff conflictingDiff : builder.build()) {
					final Match next = conflictingDiff.getMatch();
					final URI leftURI = resourceURIorNull(next.getLeft());
					final URI rightURI = resourceURIorNull(next.getRight());
					final URI originURI = resourceURIorNull(next.getOrigin());
					if (leftURI != null) {
						conflictingURIs.add(leftURI);
					}
					if (rightURI != null) {
						conflictingURIs.add(rightURI);
					}
					if (originURI != null) {
						conflictingURIs.add(originURI);
					}
				}
			}
		}
		return conflictingURIs;
	}

	/**
	 * Returns either the URI of the resource containing the given EObject, or <code>null</code> if none.
	 * 
	 * @param eObject
	 *            The EObject for which we need a resource URI.
	 * @return The URI of the resource containing the given EObject, <code>null</code> if none.
	 */
	private URI resourceURIorNull(EObject eObject) {
		if (eObject != null) {
			final Resource res = eObject.eResource();
			if (res != null) {
				return res.getURI();
			}
		}
		return null;
	}

	/**
	 * Marks the resources as merged if their URIs are not included in the given set of known
	 * {@code conflictingURIs}.
	 * 
	 * @param context
	 *            The current merge context.
	 * @param resources
	 *            The resources to be marked as merged.
	 * @param conflictingURIs
	 *            The set of known {@code conflictingURIs}.
	 * @param subMonitor
	 *            Monitor on which to report progress to the user.
	 */
	protected void markResourcesAsMerged(IMergeContext context, Set<IResource> resources,
			Set<URI> conflictingURIs, SubMonitor subMonitor) {
		for (IResource resource : resources) {
			if (resource instanceof IFile) {
				final IFile iFile = (IFile)resource;
				final URI uri = ResourceUtil.createURIFor(iFile);
				if (!conflictingURIs.contains(uri)) {
					markAsMerged(context, resource, subMonitor);
				}
			}
		}
	}

	/**
	 * Mark the resource at the given URI as merged.
	 * 
	 * @param context
	 *            The current merge context.
	 * @param resource
	 *            The resource to mark as merged.
	 * @param subMonitor
	 *            Monitor on which to report progress to the user.
	 */
	private void markAsMerged(IMergeContext context, IResource resource, SubMonitor subMonitor) {
		IDiff diff = context.getDiffTree().getDiff(resource);
		if (diff != null) {
			try {
				context.markAsMerged(diff, true, subMonitor);
			} catch (CoreException e) {
				EMFCompareIDEUIPlugin.getDefault().log(e);
			}
		}
	}

	/**
	 * Performs a batch merge of the given {@code comparison}.
	 * 
	 * @param comparison
	 *            The comparison to merge.
	 * @param subMonitor
	 *            The progress monitor to use.
	 */
	private void performBatchMerge(Comparison comparison, SubMonitor subMonitor) {
		final IBatchMerger merger = new BatchMerger(MERGER_REGISTRY, fromSide(DifferenceSource.RIGHT));
		merger.copyAllRightToLeft(comparison.getDifferences(), BasicMonitor.toMonitor(subMonitor));
	}

	/**
	 * Delegates the merge of so far non-merged resource additions and deletions and marks all other already
	 * merged resources as merged.
	 * 
	 * @param syncModel
	 *            The synchronization model to obtain the storages.
	 * @param mergeContext
	 *            The merge context.
	 * @param resourceTracker
	 *            The tracker that tracked already merged file additions and deletions.
	 * @param subMonitor
	 *            The progress monitor to use.
	 */
	protected void delegateMergeOfUnmergedResourcesAndMarkDiffsAsMerged(SynchronizationModel syncModel,
			IMergeContext mergeContext, ResourceAdditionAndDeletionTracker resourceTracker,
			SubMonitor subMonitor) throws CoreException {

		// mark already deleted files as merged
		for (IFile deletedFile : resourceTracker.getDeletedIFiles()) {
			final IDiff diff = mergeContext.getDiffTree().getDiff(deletedFile);
			markAsMerged(diff, mergeContext, subMonitor);
		}

		// for all left storages, delegate the merge of a deletion that has not been performed yet and mark
		// all already performed diffs as merged
		for (IStorage storage : syncModel.getLeftTraversal().getStorages()) {
			final IPath fullPath = ResourceUtil.getFixedPath(storage);
			if (fullPath == null) {
				EMFCompareIDEUIPlugin.getDefault().getLog().log(new Status(IStatus.WARNING,
						EMFCompareIDEUIPlugin.PLUGIN_ID,
						EMFCompareIDEUIMessages.getString("EMFResourceMappingMerger.mergeIncomplete"))); //$NON-NLS-1$
			} else {
				final IDiff diff = mergeContext.getDiffTree().getDiff(fullPath);
				if (diff != null) {
					if (IDiff.REMOVE == diff.getKind()
							&& !resourceTracker.containsRemovedResource(fullPath)) {
						merge(diff, mergeContext, subMonitor.newChild(1));
					} else {
						markAsMerged(diff, mergeContext, subMonitor.newChild(1));
					}
				}
			}
		}

		// delegate all additions from the right storages that have not been performed yet
		// or, if they have been merged, mark the diff as merged
		for (IStorage rightStorage : syncModel.getRightTraversal().getStorages()) {
			final IPath fullPath = ResourceUtil.getFixedPath(rightStorage);
			if (fullPath != null) {
				final IDiff diff = mergeContext.getDiffTree().getDiff(fullPath);
				if (diff != null && IDiff.ADD == diff.getKind()) {
					if (!resourceTracker.containsAddedResource(fullPath)) {
						IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(fullPath);
						IProject project = file.getProject();
						if (project.isAccessible()) {
							merge(diff, mergeContext, subMonitor.newChild(1));
						} else {
							// The project that will contain the resource is not accessible.
							// We have to copy the file "manually" from the right side to the left side.
							try (InputStream inputStream = rightStorage.getContents();
									FileOutputStream outputStream = new FileOutputStream(
											ResourceUtil.getAbsolutePath(rightStorage).toFile())) {
								ByteStreams.copy(inputStream, outputStream);
							} catch (IOException e) {
								EMFCompareIDEUIPlugin.getDefault().log(e);
								// TODO Should we throw the exception here to interrupt the merge ?
							}
						}
					} else {
						markAsMerged(diff, mergeContext, subMonitor.newChild(1));
					}
				}
			}
		}
	}

	/**
	 * Merges the given {@code diff}.
	 * 
	 * @param diff
	 *            The difference to be merged.
	 * @param mergeContext
	 *            The merge context.
	 * @param subMonitor
	 *            The process monitor to use.
	 */
	protected void merge(IDiff diff, IMergeContext mergeContext, SubMonitor subMonitor) {
		try {
			mergeContext.merge(diff, false, subMonitor);
		} catch (CoreException e) {
			EMFCompareIDEUIPlugin.getDefault().log(e);
		}
	}

	/**
	 * Marks the given {@code diff} as merged.
	 * 
	 * @param diff
	 *            The difference to be marked as merge.
	 * @param mergeContext
	 *            The merge context.
	 * @param subMonitor
	 *            The progress monitor to use.
	 */
	protected void markAsMerged(final IDiff diff, IMergeContext mergeContext, SubMonitor subMonitor) {
		try {
			mergeContext.markAsMerged(diff, true, subMonitor);
		} catch (CoreException e) {
			EMFCompareIDEUIPlugin.getDefault().log(e);
		}
	}

	/**
	 * Validates the given array of mappings. Basically, this merger can only operate if all of its target
	 * mappings are instances of EMFResourceMappings that were properly initialized.
	 * 
	 * @param mappings
	 *            The mappings we are to validate.
	 * @return {@link Status#OK_STATUS} if the given mappings are valid, a status describing the failure
	 *         otherwise.
	 */
	private IStatus validateMappings(ResourceMapping[] mappings) {
		for (ResourceMapping mapping : mappings) {
			if (mapping instanceof EMFResourceMapping
					&& mapping.getModelObject() instanceof SynchronizationModel) {
				final SynchronizationModel model = (SynchronizationModel)mapping.getModelObject();
				if (model.getDiagnostic().getSeverity() >= Diagnostic.WARNING) {
					return BasicDiagnostic.toIStatus(model.getDiagnostic());
				}
			} else {
				return new Status(IStatus.ERROR, EMFCompareIDEUIPlugin.PLUGIN_ID, EMFCompareIDEUIMessages
						.getString("EMFResourceMappingMerger.mergeFailedInvalidMapping")); //$NON-NLS-1$
			}
		}
		return Status.OK_STATUS;
	}

	/**
	 * Saves the given notifier to disk after a successful merge.
	 * 
	 * @param notifier
	 *            The notifier.
	 * @param leftTraversal
	 *            The traversal corresponding to the left side.
	 * @param rightTraversal
	 *            The traversal corresponding to the right side.
	 * @param originTraversal
	 *            The traversal corresponding to the common ancestor of both other side. Can be
	 *            <code>null</code>.
	 */
	protected void save(Notifier notifier, StorageTraversal leftTraversal, StorageTraversal rightTraversal,
			StorageTraversal originTraversal) {
		if (notifier instanceof ResourceSet) {
			ResourceUtil.saveAllResources((ResourceSet)notifier,
					ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
							Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER),
					leftTraversal, rightTraversal, originTraversal);
		} else if (notifier instanceof Resource) {
			ResourceUtil.saveResource((Resource)notifier,
					ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
							Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER));
		}
	}

	/**
	 * Checks whether this comparison presents a real conflict.
	 * 
	 * @param comparison
	 *            The comparison to check for conflicts.
	 * @return <code>true</code> if there's at least one {@link ConflictKind#REAL real conflict} within this
	 *         comparison.
	 */
	private boolean hasRealConflict(Comparison comparison) {
		for (Conflict conflict : comparison.getConflicts()) {
			if (conflict.getKind() == ConflictKind.REAL) {
				return true;
			}
		}
		return false;
	}

	/** {@inheritDoc} */
	public ISchedulingRule getMergeRule(IMergeContext context) {
		final ResourceMapping[] emfMappings = getEMFMappings(context);
		final Set<IProject> impactedProjects = new LinkedHashSet<IProject>();
		for (ResourceMapping mapping : emfMappings) {
			impactedProjects.addAll(Arrays.asList(mapping.getProjects()));
		}
		return MultiRule.combine(impactedProjects.toArray(new ISchedulingRule[impactedProjects.size()]));
	}

	/**
	 * Retrieves all mappings from the given merge context that were created from the EMFModelProvider.
	 * 
	 * @param context
	 *            The context from which to retrieve resource mappings.
	 * @return All resource mappings from this context that were created from the EMFModelProvider.
	 */
	private ResourceMapping[] getEMFMappings(IMergeContext context) {
		return context.getScope().getMappings(EMFModelProvider.PROVIDER_ID);
	}

	/** {@inheritDoc} */
	public IStatus validateMerge(IMergeContext mergeContext, IProgressMonitor monitor) {
		return Status.OK_STATUS;
	}

	protected static class ResourceAdditionAndDeletionTracker extends AdapterImpl {

		private final Set<String> urisOfAddedResources = new HashSet<String>();

		private final Set<String> urisOfDeletedResources = new HashSet<String>();

		private final Set<IFile> deletedIFiles = new HashSet<IFile>();

		@Override
		public void notifyChanged(Notification msg) {
			if (!isAdditionOrDeletionOfResourceNotification(msg)) {
				return;
			}

			final Resource newResource = (Resource)msg.getNewValue();
			final URI uri = newResource.getURI();
			if (uri.isPlatformResource()) {
				final String path = uri.toPlatformString(true);
				final IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path));
				if (msg.getEventType() == Notification.ADD) {
					trackResourceAddition(file);
				} else if (msg.getEventType() == Notification.REMOVE) {
					trackResourceDeletion(file);
				}
			}
		}

		private boolean isAdditionOrDeletionOfResourceNotification(Notification msg) {
			return (msg.getEventType() == Notification.ADD || msg.getEventType() == Notification.REMOVE)
					&& msg.getNewValue() instanceof Resource;
		}

		private void trackResourceAddition(IFile file) {
			urisOfAddedResources.add(getStringRepresentation(file.getFullPath()));
		}

		private void trackResourceDeletion(IFile file) {
			deletedIFiles.add(file);
			urisOfDeletedResources.add(getStringRepresentation(file.getFullPath()));
		}

		private String getStringRepresentation(IPath path) {
			return path.toPortableString();
		}

		public boolean containsAddedResource(IPath path) {
			return urisOfAddedResources.contains(getStringRepresentation(path));
		}

		public boolean containsRemovedResource(IPath path) {
			return urisOfDeletedResources.contains(getStringRepresentation(path));
		}

		public Set<IFile> getDeletedIFiles() {
			return Collections.unmodifiableSet(deletedIFiles);
		}
	}
}
