/*******************************************************************************
 * Copyright (c) 2015, 2016 Obeo.
 * 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:
 *     Laurent Goubet <laurent.goubet@obeo.fr> - initial API and implementation
 *     Axel Richard <axel.richard@obeo.fr> - Update #registerHandledFiles()
 *******************************************************************************/
package org.eclipse.emf.compare.egit.internal.merge;

//CHECKSTYLE:OFF
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.RemoteResourceMappingContext;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.internal.job.RuleUtil;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.emf.compare.egit.internal.storage.AbstractGitResourceVariant;
import org.eclipse.emf.compare.egit.internal.storage.TreeParserResourceVariant;
import org.eclipse.emf.compare.egit.internal.wrapper.JGitProgressMonitorWrapper;
import org.eclipse.jgit.attributes.Attributes;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.dircache.DirCacheBuildIterator;
import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.merge.MergeResult;
import org.eclipse.jgit.merge.RecursiveMerger;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.TeamException;
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.ISynchronizationScopeManager;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.core.subscribers.SubscriberMergeContext;
import org.eclipse.team.core.subscribers.SubscriberResourceMappingContext;
import org.eclipse.team.core.subscribers.SubscriberScopeManager;
import org.eclipse.team.core.variants.IResourceVariant;

/**
 * This extends the recursive merger in order to take into account specific mergers provided by the Team
 * {@link org.eclipse.core.resources.mapping.ModelProvider model providers}.
 * <p>
 * The Recursive Merger handles files one-by-one, calling file-specific merge drivers for each. On the
 * opposite, this strategy can handle bigger sets of files at once, delegating the merge to the files' model.
 * As such, file-specific merge drivers may not be called from this strategy if that file is part of a larger
 * model.
 * </p>
 * <p>
 * Any file that is <b>not</b> part of a model, which model cannot be determined, or which model does not
 * specify a custom merger, will be handled as it would by the RecursiveMerger.
 * </p>
 * 
 * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
 * @author <a href="mailto:laurent.delaigue@obeo.fr">Laurent Delaigue</a>
 */
@SuppressWarnings("restriction")
public class RecursiveModelMerger extends RecursiveMerger {

	private static final Logger LOGGER = Logger.getLogger(RecursiveModelMerger.class);

	/**
	 * This will be populated during the course of the RecursiveMappingMergers' executions. These files have
	 * been cleanly merged and we should thus make sure the DirCacheBuilder takes their latest working
	 * directory version before committing.
	 */
	private final Set<String> makeInSync = new LinkedHashSet<>();

	/**
	 * keeps track of the files we've already merged. Since we iterate one file at a time but may merge
	 * multiple files at once when they are part of the same model, this will help us avoid merging the same
	 * file or model twice.
	 */
	private final Set<String> handledPaths = new HashSet<>();

	private AbstractTreeIterator aBaseTree;

	private RevTree aHeadTree;

	private RevTree aMergeTree;

	/**
	 * Default recursive model merger.
	 *
	 * @param db
	 * @param inCore
	 */
	public RecursiveModelMerger(Repository db, boolean inCore) {
		super(db, inCore);
	}

	@Override
	protected boolean mergeTrees(AbstractTreeIterator baseTree, RevTree headTree, RevTree mergeTree,
			boolean ignoreConflicts) throws IOException {
		// We need to keep track on all version to be merged to be able to build a new TreeWalk in
		// #mergeTreeWalk
		this.aBaseTree = baseTree;
		this.aHeadTree = headTree;
		this.aMergeTree = mergeTree;
		return super.mergeTrees(baseTree, headTree, mergeTree, ignoreConflicts);
	}

	@Override
	protected boolean mergeTreeWalk(TreeWalk treeWalk, boolean ignoreConflicts) throws IOException {
		if (LOGGER.isInfoEnabled()) {
			LOGGER.info("STARTING Recursive model merge."); //$NON-NLS-1$
		}
		final TreeWalkResourceVariantTreeProvider variantTreeProvider = new TreeWalkResourceVariantTreeProvider.Builder()//
				.setRepository(getRepository())//
				.setaBaseTree(aBaseTree)//
				.setHeadTree(aHeadTree)//
				.setMergeTree(aMergeTree)//
				.setDircache(dircache) //
				.setReader(reader) //
				.build();

		final GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(
				variantTreeProvider);
		final RemoteResourceMappingContext remoteMappingContext = new SubscriberResourceMappingContext(
				subscriber, true);

		try {
			refreshRoots(subscriber.roots());
		} catch (CoreException e) {
			// We cannot be sure that Team and/or the merger implementations
			// will properly handle unrefreshed files. Fall back to merging
			// without workspace awareness.
			Activator.logError(MergeText.RecursiveModelMerger_RefreshError, e);
			return super.mergeTreeWalk(treeWalk, ignoreConflicts);
		}

		monitor.beginTask(MergeText.RecursiveModelMerger_BuildLogicalModels, ProgressMonitor.UNKNOWN);
		// Eager lookup for the logical models to avoid issues in case we
		// iterate over a file that does not exist locally before the rest of
		// its logical model.
		final LogicalModels logicalModels = new LogicalModels();
		logicalModels.build(variantTreeProvider.getKnownResources(), remoteMappingContext);
		monitor.endTask();

		if (monitor.isCancelled()) {
			throw new OperationCanceledException();
		}

		// The treewalk might decide to handle files with no differences by itself instead of leaving that
		// decision to us (id treewalk.getFilter() is "AnyDiff", then it'll skip over the "in-sync" files
		// while adding them to the dircache at the same time). In such a case, we need to prevent ModelMerge
		// from adding the "unchanged" files (which require no merging) in the DirCacheBuilder, otherwise
		// we'll end up with "duplicate stage not allowed" exceptions at the end of merge operations
		// (dirCache.finish()).
		// see also bug #535200
		boolean handleUnchangedFiles = true;
		if (treeWalk.getFilter() == TreeFilter.ANY_DIFF) {
			handleUnchangedFiles = false;
		}

		// We are done with the setup. We can now iterate over the tree walk and
		// either delegate to the logical model's merger if any or fall back to
		// standard git merging. Basically, any file that is not a part of a
		// logical model that defines its own specific merger will be handled as
		// it would by the RecursiveMerger.
		while (treeWalk.next()) {
			final int modeBase = treeWalk.getRawMode(T_BASE);
			final int modeOurs = treeWalk.getRawMode(T_OURS);
			final int modeTheirs = treeWalk.getRawMode(T_THEIRS);
			if (modeBase == 0 && modeOurs == 0 && modeTheirs == 0) {
				// untracked
				continue;
			}
			final String path = treeWalk.getPathString();
			if (handledPaths.contains(path)) {
				// This one has been handled as a result of a previous model
				// merge. Simply make sure we use its latest content if it is
				// not in conflict.
				if (treeWalk.isSubtree() && enterSubtree) {
					treeWalk.enterSubtree();
				}
				if (!unmergedPaths.contains(path)) {
					registerMergedPath(path);
					if (LOGGER.isDebugEnabled()) {
						LOGGER.debug("Ignoring previously handled file: " + path); //$NON-NLS-1$
					}
				}
				continue;
			}

			final int nonZeroMode = modeBase != 0 ? modeBase : modeOurs != 0 ? modeOurs : modeTheirs;
			final IResource resource = variantTreeProvider.getResourceHandleForLocation(getRepository(), path,
					FileMode.fromBits(nonZeroMode) == FileMode.TREE);
			Set<IResource> logicalModel = logicalModels.getModel(resource);

			IResourceMappingMerger modelMerger = null;
			if (logicalModel != null) {
				try {
					// We need to refresh because new resources may have been added
					refreshRoots(subscriber.roots());
					modelMerger = getResourceMappingMerger(logicalModel);
				} catch (CoreException e) {
					Activator.logError(MergeText.RecursiveModelMerger_AdaptError, e);
					// ignore this model and fall back to default
					if (!fallBackToDefaultMerge(treeWalk, ignoreConflicts)) {
						cleanUp();
						if (LOGGER.isInfoEnabled()) {
							LOGGER.info(
									"FAILED - Recursive model merge, could not find appropriate merger and default merge failed."); //$NON-NLS-1$
						}
						return false;
					}
				}
			}
			if (modelMerger != null) {
				enterSubtree = true;

				boolean success = new ModelMerge(this, subscriber, remoteMappingContext, path, logicalModel,
						modelMerger, handleUnchangedFiles).run(new JGitProgressMonitorWrapper(monitor));
				if (!success) {
					if (LOGGER.isInfoEnabled()) {
						LOGGER.info("FAILED - Recursive model merge."); //$NON-NLS-1$
					}
					return false;
				} else if (!unmergedPaths.contains(path)) {
					if (LOGGER.isDebugEnabled()) {
						LOGGER.debug("Merged model file: " + path); //$NON-NLS-1$
					}
					registerMergedPath(path);
				}
				if (treeWalk.isSubtree()) {
					enterSubtree = true;
				}
			} else if (!fallBackToDefaultMerge(treeWalk, ignoreConflicts)) {
				cleanUp();
				if (LOGGER.isInfoEnabled()) {
					LOGGER.info("FAILED - Recursive model merge, default merge failed."); //$NON-NLS-1$
				}
				return false;
			}
			if (treeWalk.isSubtree() && enterSubtree) {
				treeWalk.enterSubtree();
			}
		}
		if (!makeInSync.isEmpty()) {
			indexModelMergedFiles();
		}
		if (LOGGER.isInfoEnabled()) {
			LOGGER.info("SUCCESS - Recursive model merge."); //$NON-NLS-1$
		}
		return true;
	}

	protected IResourceMappingMerger getResourceMappingMerger(Set<IResource> logicalModel)
			throws CoreException {
		return LogicalModels.findAdapter(logicalModel, IResourceMappingMerger.class);
	}

	private boolean fallBackToDefaultMerge(TreeWalk treeWalk, boolean ignoreConflicts)
			throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, IOException {
		boolean hasWorkingTreeIterator = tw.getTreeCount() > T_FILE;
		boolean hasAttributeNodeProvider = treeWalk.getAttributesNodeProvider() != null;
		return processEntry(treeWalk.getTree(T_BASE, CanonicalTreeParser.class),
				treeWalk.getTree(T_OURS, CanonicalTreeParser.class),
				treeWalk.getTree(T_THEIRS, CanonicalTreeParser.class),
				treeWalk.getTree(T_INDEX, DirCacheBuildIterator.class),
				hasWorkingTreeIterator ? treeWalk.getTree(T_FILE, WorkingTreeIterator.class) : null,
				ignoreConflicts, hasAttributeNodeProvider ? treeWalk.getAttributes() : new Attributes());
	}

	/**
	 * Add files modified by model mergers to the index.
	 *
	 * @throws CorruptObjectException
	 * @throws MissingObjectException
	 * @throws IncorrectObjectTypeException
	 * @throws IOException
	 */
	private void indexModelMergedFiles()
			throws CorruptObjectException, MissingObjectException, IncorrectObjectTypeException, IOException {
		try (TreeWalk syncingTreeWalk = new TreeWalk(getRepository())) {
			int dirCacheIndex = syncingTreeWalk.addTree(new DirCacheIterator(dircache));

			// Setting the DirCacheIterator is required to be able to handle properly Git attributes
			FileTreeIterator aWorkingTreeIterator = new FileTreeIterator(getRepository());
			syncingTreeWalk.addTree(aWorkingTreeIterator);
			aWorkingTreeIterator.setDirCacheIterator(syncingTreeWalk, dirCacheIndex);

			syncingTreeWalk.setRecursive(true);
			syncingTreeWalk.setFilter(PathFilterGroup.createFromStrings(makeInSync));
			String lastAdded = null;
			while (syncingTreeWalk.next()) {
				String path = syncingTreeWalk.getPathString();
				if (path.equals(lastAdded)) {
					continue;
				}

				WorkingTreeIterator workingTree = syncingTreeWalk.getTree(1, WorkingTreeIterator.class);
				DirCacheIterator dirCache = syncingTreeWalk.getTree(0, DirCacheIterator.class);
				if (dirCache == null && workingTree != null && workingTree.isEntryIgnored()) {
					// nothing to do on this one
				} else if (workingTree != null) {
					if (dirCache == null || dirCache.getDirCacheEntry() == null
							|| !dirCache.getDirCacheEntry().isAssumeValid()) {
						final DirCacheEntry dce = new DirCacheEntry(path);
						final FileMode mode = workingTree.getIndexFileMode(dirCache);
						dce.setFileMode(mode);

						if (FileMode.GITLINK != mode) {
							dce.setLength(workingTree.getEntryLength());
							dce.setLastModified(workingTree.getEntryLastModified());
							try (InputStream is = workingTree.openEntryStream()) {
								dce.setObjectId(getObjectInserter().insert(Constants.OBJ_BLOB,
										workingTree.getEntryContentLength(), is));
							}
						} else {
							dce.setObjectId(workingTree.getEntryObjectId());
						}
						builder.add(dce);
						lastAdded = path;
					} else {
						builder.add(dirCache.getDirCacheEntry());
					}
				} else if (dirCache != null && FileMode.GITLINK == dirCache.getEntryFileMode()) {
					builder.add(dirCache.getDirCacheEntry());
				}
			}
		}
	}

	private static String getRepoRelativePath(IResource file) {
		final RepositoryMapping mapping = RepositoryMapping.getMapping(file);
		if (mapping != null) {
			return mapping.getRepoRelativePath(file);
		}
		return null;
	}

	/**
	 * On many aspects, team relies on the refreshed state of the workspace files, notably to determine if a
	 * file is in sync or not. Since we could have been called for a rebase, rebase that checked out a new
	 * commit without refreshing the workspace afterwards, team could see "in-sync" files even though they no
	 * longer exist in the workspace. This should be called before any merging takes place to make sure all
	 * files concerned by this merge operation are refreshed beforehand.
	 *
	 * @param resources
	 *            The set of resource roots to refresh.
	 * @throws CoreException
	 *             Thrown whenever we fail at refreshing one of the resources or its children.
	 */
	private void refreshRoots(IResource[] resources) throws CoreException {
		for (IResource root : resources) {
			if (root.isAccessible()) {
				root.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
			}
		}
	}

	private void markConflict(String filePath, DirCacheBuilder cacheBuilder,
			TreeParserResourceVariant baseVariant, TreeParserResourceVariant ourVariant,
			TreeParserResourceVariant theirVariant) {
		add(filePath, cacheBuilder, baseVariant, DirCacheEntry.STAGE_1);
		add(filePath, cacheBuilder, ourVariant, DirCacheEntry.STAGE_2);
		add(filePath, cacheBuilder, theirVariant, DirCacheEntry.STAGE_3);
	}

	private void add(String path, DirCacheBuilder cacheBuilder, TreeParserResourceVariant variant,
			int stage) {
		if (variant != null && !FileMode.TREE.equals(variant.getRawMode())) {
			DirCacheEntry e = new DirCacheEntry(path, stage);
			e.setFileMode(FileMode.fromBits(variant.getRawMode()));
			e.setObjectId(variant.getObjectId());
			e.setLastModified(0);
			e.setLength(0);
			cacheBuilder.add(e);
		}
	}

	private static class ModelMerge {
		private final RecursiveModelMerger merger;

		private final GitResourceVariantTreeSubscriber subscriber;

		private final RemoteResourceMappingContext remoteMappingContext;

		private final String path;

		private final Set<IResource> logicalModel;

		private final IResourceMappingMerger modelMerger;

		private final boolean handleUnchangedFiles;

		public ModelMerge(RecursiveModelMerger merger, GitResourceVariantTreeSubscriber subscriber,
				RemoteResourceMappingContext remoteMappingContext, String path, Set<IResource> logicalModel,
				IResourceMappingMerger modelMerger, boolean handleUnchangedFiles) {
			this.merger = merger;
			this.subscriber = subscriber;
			this.remoteMappingContext = remoteMappingContext;
			this.path = path;
			this.logicalModel = logicalModel;
			this.modelMerger = modelMerger;
			this.handleUnchangedFiles = handleUnchangedFiles;
		}

		private boolean run(IProgressMonitor monitor) throws CorruptObjectException, IOException {
			SubMonitor progress = SubMonitor.convert(monitor, 1);
			IMergeContext mergeContext = null;
			try {
				mergeContext = prepareMergeContext();
				final IStatus status = modelMerger.merge(mergeContext, progress.newChild(1));
				registerHandledFiles(mergeContext, status);
			} catch (CoreException e) {
				Activator.logError(e.getMessage(), e);
				merger.cleanUp();
				return false;
			} catch (OperationCanceledException e) {
				final String message = NLS.bind(MergeText.RecursiveModelMerger_ScopeInitializationInterrupted,
						path);
				Activator.logError(message, e);
				merger.cleanUp();
				return false;
			} finally {
				if (mergeContext != null) {
					mergeContext.dispose();
				}
			}
			return true;
		}

		private void registerHandledFiles(final IMergeContext mergeContext, final IStatus status)
				throws TeamException, CoreException {
			for (IResource handledFile : logicalModel) {
				String filePath = getRepoRelativePath(handledFile);
				if (filePath == null) {
					IResourceVariant sourceVariant = subscriber.getSourceTree()
							.getResourceVariant(handledFile);
					IResourceVariant remoteVariant = subscriber.getRemoteTree()
							.getResourceVariant(handledFile);
					IResourceVariant baseVariant = subscriber.getBaseTree().getResourceVariant(handledFile);
					if (sourceVariant instanceof AbstractGitResourceVariant) {
						// In the case of a conflict, the file may not exist
						// So don't check for file existence
						filePath = ((AbstractGitResourceVariant)sourceVariant).getPath();
					}
					if (filePath == null && remoteVariant instanceof AbstractGitResourceVariant) {
						// In the case of a conflict, the file may not exist
						// So don't check for file existence
						filePath = ((AbstractGitResourceVariant)remoteVariant).getPath();
					}
					if (filePath == null && baseVariant instanceof AbstractGitResourceVariant) {
						// In the case of a conflict, the file may not exist
						// So don't check for file existence
						filePath = ((AbstractGitResourceVariant)baseVariant).getPath();
					}

				}
				if (LOGGER.isDebugEnabled()) {
					LOGGER.debug("Registering handled file " + filePath); //$NON-NLS-1$
				}

				if (merger.handledPaths.contains(filePath)) {
					continue;
				}

				if (filePath != null) {
					merger.modifiedFiles.add(filePath);
					merger.handledPaths.add(filePath);
				} else if (LOGGER.isDebugEnabled()) {
					LOGGER.debug("Impossible to compute a repo-relative filePath for file " //$NON-NLS-1$
							+ handledFile);
				}

				// The merge failed. If some parts of the model were
				// auto-mergeable, the model merger told us so through
				// GitMergeContext#markAsMerged() (stored within #makeInSync).
				// All other components of the logical model should be marked as
				// conflicts.
				if (mergeContext.getDiffTree().getDiff(handledFile) == null) {
					// If no diff, the model merger does... nothing
					// Make sure this file will be added to the index.
					if (handleUnchangedFiles) {
						merger.registerMergedPath(filePath);
						if (LOGGER.isDebugEnabled()) {
							LOGGER.debug("Merged non-modified file: " + filePath); //$NON-NLS-1$
						}
					}
				} else if (filePath != null && status.getSeverity() != IStatus.OK) {
					if (merger.makeInSync.contains(filePath)) {
						// The conflict has priority over the merge. This only can happen when
						// the comparison could not finish successful.
						merger.makeInSync.remove(filePath);
					}
					merger.unmergedPaths.add(filePath);
					merger.mergeResults.put(filePath, new MergeResult<>(Collections.<RawText> emptyList()));
					final TreeParserResourceVariant baseVariant = (TreeParserResourceVariant)subscriber
							.getBaseTree().getResourceVariant(handledFile);
					final TreeParserResourceVariant ourVariant = (TreeParserResourceVariant)subscriber
							.getSourceTree().getResourceVariant(handledFile);
					final TreeParserResourceVariant theirVariant = (TreeParserResourceVariant)subscriber
							.getRemoteTree().getResourceVariant(handledFile);
					merger.markConflict(filePath, merger.builder, baseVariant, ourVariant, theirVariant);

					if (LOGGER.isDebugEnabled()) {
						LOGGER.debug("Marking conflict on " + filePath); //$NON-NLS-1$
					}
				}
			}
		}

		/**
		 * Create and initialize the merge context for the given model.
		 *
		 * @return An initialized merge context for the given model.
		 * @throws CoreException
		 *             Thrown if we cannot initialize the scope for this merge context.
		 * @throws OperationCanceledException
		 *             Thrown if the user cancelled the initialization.
		 */
		private IMergeContext prepareMergeContext() throws CoreException, OperationCanceledException {
			final Set<ResourceMapping> allMappings = LogicalModels.getResourceMappings(logicalModel,
					remoteMappingContext);
			final ResourceMapping[] mappings = allMappings.toArray(new ResourceMapping[allMappings.size()]);

			final ISynchronizationScopeManager manager = new SubscriberScopeManager(subscriber.getName(),
					mappings, subscriber, remoteMappingContext, true) {
				@Override
				public ISchedulingRule getSchedulingRule() {
					return RuleUtil.getRule(merger.getRepository());
				}
			};
			manager.initialize(new NullProgressMonitor());

			final IMergeContext context = new GitMergeContext(merger, subscriber, manager);
			// Wait for the asynchronous scope expanding to end (started from
			// the initialization of our merge context)
			waitForScope(context);

			return context;
		}

		private void waitForScope(IMergeContext context) {
			// The UILockListener might prevent us from properly joining.
			boolean joined = false;
			while (!joined) {
				try {
					Job.getJobManager().join(context, new NullProgressMonitor());
					joined = true;
				} catch (InterruptedException e) {
					// Some other UI threads were trying to run. Let the
					// syncExecs do their jobs and re-try to join on ours.
				}
			}
		}
	}

	private static class GitMergeContext extends SubscriberMergeContext {

		private final RecursiveModelMerger merger;

		/**
		 * Create and initialize a merge context for the given subscriber.
		 *
		 * @param merger
		 *            the merger
		 * @param subscriber
		 *            the subscriber.
		 * @param scopeManager
		 *            the scope manager.
		 */
		public GitMergeContext(RecursiveModelMerger merger, Subscriber subscriber,
				ISynchronizationScopeManager scopeManager) {
			super(subscriber, scopeManager);
			this.merger = merger;
			initialize();
		}

		public void markAsMerged(IDiff node, boolean inSyncHint, IProgressMonitor monitor)
				throws CoreException {
			final IResource resource = getDiffTree().getResource(node);
			merger.addSyncPath(resource);
		}

		public void reject(IDiff diff, IProgressMonitor monitor) throws CoreException {
			// Empty implementation
		}

		@Override
		protected void makeInSync(IDiff diff, IProgressMonitor monitor) throws CoreException {
			final IResource resource = getDiffTree().getResource(diff);
			merger.addSyncPath(resource);
		}
	}

	private void addSyncPath(IResource resource) {
		String repoRelativePath = getRepoRelativePath(resource);
		registerMergedPath(repoRelativePath);
	}

	private boolean registerMergedPath(String path) {
		if (path != null && !unmergedPaths.contains(path)) {
			return makeInSync.add(path);
		}
		return false;
	}
}
// CHECKSTYLE:ON
