/*******************************************************************************
 * Copyright (c) 2006, 2009 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.ccvs.ui.mappings;

import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.team.core.diff.*;
import org.eclipse.team.core.mapping.IResourceDiffTree;
import org.eclipse.team.core.mapping.ISynchronizationContext;
import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
import org.eclipse.team.internal.ccvs.core.mapping.*;
import org.eclipse.team.internal.ccvs.ui.CVSUIMessages;
import org.eclipse.team.internal.ccvs.ui.subscriber.CVSChangeSetCollector;
import org.eclipse.team.internal.core.subscribers.*;
import org.eclipse.team.internal.core.subscribers.BatchingChangeSetManager.CollectorChangeEvent;
import org.eclipse.team.internal.ui.IPreferenceIds;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.mapping.ResourceModelContentProvider;
import org.eclipse.team.internal.ui.mapping.ResourceModelLabelProvider;
import org.eclipse.team.internal.ui.synchronize.ChangeSetCapability;
import org.eclipse.team.internal.ui.synchronize.IChangeSetProvider;
import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipant;
import org.eclipse.ui.navigator.*;

public class ChangeSetContentProvider extends ResourceModelContentProvider implements ITreePathContentProvider {

	private final class CollectorListener implements IChangeSetChangeListener, BatchingChangeSetManager.IChangeSetCollectorChangeListener {
		@Override
		public void setAdded(final ChangeSet set) {
			// We only react here for active change sets.
			// Checked-in change set changes are batched
			if (set instanceof ActiveChangeSet) {
				if (isVisibleInMode(set)) {
					Utils.syncExec((Runnable) () -> {
						Object input = getViewer().getInput();
						((AbstractTreeViewer) getViewer()).add(input, set);
					}, (StructuredViewer)getViewer());
				}
				handleSetAddition(set);
			}
		}

		private void handleSetAddition(final ChangeSet set) {
			getUnassignedSet().remove(set.getResources());
		}

		@Override
		public void defaultSetChanged(final ChangeSet previousDefault, final ChangeSet set) {
			if (isVisibleInMode(set) || isVisibleInMode(previousDefault)) {
				Utils.asyncExec((Runnable) () -> {
					if (set == null) {
						// unset default changeset
						((AbstractTreeViewer) getViewer()).update(previousDefault, null);
					} else if (previousDefault != null) {
						((AbstractTreeViewer) getViewer()).update(new Object[] { previousDefault, set }, null);
					} else {
						// when called for the first time previous default change set is null
						((AbstractTreeViewer) getViewer()).update(set, null);
					}
				}, (StructuredViewer)getViewer());
			}
		}

		@Override
		public void setRemoved(final ChangeSet set) {
			// We only react here for active change sets.
			// Checked-in change set changes are batched
			if (set instanceof ActiveChangeSet) {
				if (isVisibleInMode(set)) {
					Utils.syncExec((Runnable) () -> ((AbstractTreeViewer) getViewer())
							.remove(TreePath.EMPTY.createChildPath(set)), (StructuredViewer) getViewer());
				}
				handleSetRemoval(set);
			}
		}

		private void handleSetRemoval(final ChangeSet set) {
			IResource[] resources = set.getResources();
			List toAdd = new ArrayList();
			for (int i = 0; i < resources.length; i++) {
				IResource resource = resources[i];
				IDiff diff = getContext().getDiffTree().getDiff(resource);
				if (diff != null && !isContainedInSet(diff))
					toAdd.add(diff);
			}
			getUnassignedSet().add((IDiff[]) toAdd.toArray(new IDiff[toAdd.size()]));
		}

		@Override
		public void nameChanged(final ChangeSet set) {
			if (isVisibleInMode(set)) {
				Utils.asyncExec((Runnable) () -> ((AbstractTreeViewer) getViewer()).update(set, null),
						(StructuredViewer) getViewer());
			}
		}

		@Override
		public void resourcesChanged(final ChangeSet set, final IPath[] paths) {
			// We only react here for active change sets.
			// Checked-in change set changes are batched
			if (set instanceof ActiveChangeSet) {
				if (isVisibleInMode(set)) {
					Utils.syncExec((Runnable) () -> {
						if (hasChildrenInContext(set))
							if (getVisibleSetsInViewer().contains(set))
								((AbstractTreeViewer) getViewer()).refresh(set, true);
							else
								((AbstractTreeViewer) getViewer()).add(getViewer().getInput(), set);
						else
							((AbstractTreeViewer) getViewer()).remove(set);
					}, (StructuredViewer)getViewer());
				}
				handleSetChange(set, paths);
			}
		}

		private void handleSetChange(final ChangeSet set, final IPath[] paths) {
			try {
				getTheRest().beginInput();
				for (int i = 0; i < paths.length; i++) {
					IPath path = paths[i];
					boolean isContained = ((DiffChangeSet)set).contains(path);
					if (isContained) {
						IDiff diff = ((DiffChangeSet)set).getDiffTree().getDiff(path);
						if (diff != null) {
							getTheRest().remove(ResourceDiffTree.getResourceFor(diff));
						}
					} else {
						IDiff diff = getContext().getDiffTree().getDiff(path);
						if (diff != null && !isContainedInSet(diff)) {
							getTheRest().add(diff);
						}
					}   
				}
			} finally {
				getTheRest().endInput(null);
			}
		}

		@Override
		public void changeSetChanges(final CollectorChangeEvent event, IProgressMonitor monitor) {
			ChangeSet[] addedSets = event.getAddedSets();
			final ChangeSet[] visibleAddedSets = getVisibleSets(addedSets);
			ChangeSet[] removedSets = event.getRemovedSets();
			final ChangeSet[] visibleRemovedSets = getVisibleSets(removedSets);
			ChangeSet[] changedSets = event.getChangedSets();
			final ChangeSet[] visibleChangedSets = getVisibleSets(changedSets);
			if (visibleAddedSets.length > 0 || visibleRemovedSets.length > 0 || visibleChangedSets.length > 0) {
				Utils.syncExec((Runnable) () -> {
					try {
						getViewer().getControl().setRedraw(false);
						if (visibleAddedSets.length > 0) {
							Object input = getViewer().getInput();
							((AbstractTreeViewer) getViewer()).add(input, visibleAddedSets);
						}
						if (visibleRemovedSets.length > 0)
							((AbstractTreeViewer) getViewer()).remove(visibleRemovedSets);
						for (int i = 0; i < visibleChangedSets.length; i++) {
							ChangeSet set = visibleChangedSets[i];
							((AbstractTreeViewer) getViewer()).refresh(set, true);
						}
					} finally {
						getViewer().getControl().setRedraw(true);
					}
				}, (StructuredViewer)getViewer());
			}
			try {
				getTheRest().beginInput();
				for (int i = 0; i < addedSets.length; i++) {
					ChangeSet set = addedSets[i];
					handleSetAddition(set);
				}
				if (removedSets.length > 0) {
					// If sets were removed, we reset the unassigned set.
					// We need to do this because it is possible that diffs were 
					// removed from the set before the set itself was removed.
					// See bug 173138
					addAllUnassignedToUnassignedSet();
				}
				for (int i = 0; i < changedSets.length; i++) {
					ChangeSet set = changedSets[i];
					IPath[] paths = event.getChangesFor(set);
					if (event.getSource().contains(set)) {
						handleSetChange(set, paths);
					} else {
						try {
							getTheRest().beginInput();
							for (int j = 0; j < paths.length; j++) {
								IPath path = paths[j];
								IDiff diff = getContext().getDiffTree().getDiff(path);
								if (diff != null && !isContainedInSet(diff))
									getTheRest().add(diff);
							}
						} finally {
							getTheRest().endInput(null);
						}
					}
				}
			} finally {
				getTheRest().endInput(monitor);
			}
		}

		private ChangeSet[] getVisibleSets(ChangeSet[] sets) {
			List result = new ArrayList(sets.length);
			for (int i = 0; i < sets.length; i++) {
				ChangeSet set = sets[i];
				if (isVisibleInMode(set)) {
					result.add(set);
				}
			}
			return (ChangeSet[]) result.toArray(new ChangeSet[result.size()]);
		}
	}

	private DiffChangeSet unassignedDiffs;
	private boolean firstDiffChange = true;
	
	/*
	 * Listener that reacts to changes made to the active change set collector
	 */
	private IChangeSetChangeListener collectorListener = new CollectorListener();
	
	private IDiffChangeListener diffTreeListener = new IDiffChangeListener() {
	
		@Override
		public void propertyChanged(IDiffTree tree, int property, IPath[] paths) {
			// Ignore
		}
	
		boolean isSetVisible(DiffChangeSet set) {
			return getVisibleSetsInViewer().contains(set);
		}
		
		@Override
		public void diffsChanged(IDiffChangeEvent event, IProgressMonitor monitor) {
			Object input = getViewer().getInput();
			if (input instanceof ChangeSetModelProvider && unassignedDiffs != null && event.getTree() == unassignedDiffs.getDiffTree()) {
				Utils.asyncExec((Runnable) () -> {
					if (unassignedDiffs.isEmpty() || !hasChildren(TreePath.EMPTY.createChildPath(getUnassignedSet()))) {
						((AbstractTreeViewer) getViewer()).remove(unassignedDiffs);
					} else if (!isSetVisible(unassignedDiffs)) {
						Object input1 = getViewer().getInput();
						((AbstractTreeViewer) getViewer()).add(input1, unassignedDiffs);
					} else {
						((AbstractTreeViewer) getViewer()).refresh(unassignedDiffs);
					}
				}, (StructuredViewer)getViewer());
			}
		}
	
	};
	private CheckedInChangeSetCollector checkedInCollector;
	private boolean collectorInitialized;
	
	@Override
	protected String getModelProviderId() {
		return ChangeSetModelProvider.ID;
	}
	
	/* package */ boolean isVisibleInMode(ChangeSet set) {
		final Object input = getViewer().getInput();
		if (input instanceof ChangeSetModelProvider) {
			if (set instanceof ActiveChangeSet) {
				return getConfiguration().getMode() != ISynchronizePageConfiguration.INCOMING_MODE;
			}
			if (set instanceof DiffChangeSet) {
				return getConfiguration().getMode() != ISynchronizePageConfiguration.OUTGOING_MODE;
			}
		}
		return false;
	}

	protected boolean isEnabled() {
		final Object input = getViewer().getInput();
		return (input instanceof ChangeSetModelProvider);
	}
	
	@Override
	public Object[] getElements(Object parent) {
		if (parent instanceof ISynchronizationContext) {
			// Do not show change sets when all models are visible because
			// model providers that override the resource content may cause
			// problems for the change set content provider
			return new Object[0];
		}
		if (parent == getModelProvider()) {
			return getRootElements();
		}
		return super.getElements(parent);
	}

	private Object[] getRootElements() {
		if (!collectorInitialized) {
			initializeCheckedInChangeSetCollector(getChangeSetCapability());
			collectorInitialized = true;
		}
		List result = new ArrayList();
		ChangeSet[] sets = getAllSets();
		for (int i = 0; i < sets.length; i++) {
			ChangeSet set = sets[i];
			if (hasChildren(TreePath.EMPTY.createChildPath(set)))
				result.add(set);
		}
		if (!getUnassignedSet().isEmpty() && hasChildren(TreePath.EMPTY.createChildPath(getUnassignedSet()))) {
			result.add(getUnassignedSet());
		}
		return result.toArray();
	}

	synchronized DiffChangeSet getUnassignedSet() {
		if (unassignedDiffs == null) {
			unassignedDiffs = new UnassignedDiffChangeSet(
					CVSUIMessages.ChangeSetContentProvider_0);
			unassignedDiffs.getDiffTree().addDiffChangeListener(
					diffTreeListener);
			addAllUnassignedToUnassignedSet();
		}
		return unassignedDiffs;
	}

	private void addAllUnassignedToUnassignedSet() {
		IResourceDiffTree allChanges = getContext().getDiffTree();
		final List diffs = new ArrayList();
		allChanges.accept(ResourcesPlugin.getWorkspace().getRoot().getFullPath(), diff -> {
			if (!isContainedInSet(diff))
				diffs.add(diff);
			return true;
		}, IResource.DEPTH_INFINITE);
		unassignedDiffs.add((IDiff[]) diffs.toArray(new IDiff[diffs.size()]));
	}
	
	private ResourceDiffTree getTheRest() {
		return (ResourceDiffTree)getUnassignedSet().getDiffTree();
	}

	/**
	 * Return whether the given diff is contained in a set other than
	 * the unassigned set.
	 * @param diff the diff
	 * @return whether the given diff is contained in a set other than
	 * the unassigned set
	 */
	protected boolean isContainedInSet(IDiff diff) {
		ChangeSet[] sets = getAllSets();
		for (int i = 0; i < sets.length; i++) {
			ChangeSet set = sets[i];
			if (set.contains(ResourceDiffTree.getResourceFor(diff))) {
				return true;
			}
		}
		return false;
	}

	@Override
	protected ResourceTraversal[] getTraversals(
			ISynchronizationContext context, Object object) {
		if (object instanceof ChangeSet) {
			ChangeSet set = (ChangeSet) object;
			IResource[] resources = set.getResources();
			return new ResourceTraversal[] { new ResourceTraversal(resources, IResource.DEPTH_ZERO, IResource.NONE) };
		}
		return super.getTraversals(context, object);
	}

	@Override
	public Object[] getChildren(TreePath parentPath) {
		if (!isEnabled())
			return new Object[0];
		if (parentPath.getSegmentCount() == 0)
			return getRootElements();
		Object first = parentPath.getFirstSegment();
		if (!isVisibleInMode(first)) {
			return new Object[0];
		}
		IResourceDiffTree diffTree;
		Object parent = parentPath.getLastSegment();
		if (first instanceof DiffChangeSet) {
			DiffChangeSet set = (DiffChangeSet) first;
			diffTree = set.getDiffTree();
			if (parent instanceof DiffChangeSet) {
				parent = getModelRoot();
			}
		} else {
			return new Object[0];
		}
		Object[] children = getChildren(parent);
		Set result = new HashSet();
		for (int i = 0; i < children.length; i++) {
			Object child = children[i];
			if (isVisible(child, diffTree)) {
				result.add(child);
			}
		}
		return result.toArray();
	}

	private boolean isVisibleInMode(Object first) {
		if (first instanceof ChangeSet) {
			ChangeSet cs = (ChangeSet) first;
			int mode = getConfiguration().getMode();
			switch (mode) {
			case ISynchronizePageConfiguration.BOTH_MODE:
				return true;
			case ISynchronizePageConfiguration.CONFLICTING_MODE:
				return containsConflicts(cs);
			case ISynchronizePageConfiguration.INCOMING_MODE:
				return cs instanceof CVSCheckedInChangeSet || (isUnassignedSet(cs) && hasIncomingChanges(cs));
			case ISynchronizePageConfiguration.OUTGOING_MODE:
				return cs instanceof ActiveChangeSet || hasConflicts(cs) || (isUnassignedSet(cs) && hasOutgoingChanges(cs));
			default:
				break;
			}
		}
		return true;
	}

	private boolean hasIncomingChanges(ChangeSet cs) {
		if (cs instanceof DiffChangeSet) {
			DiffChangeSet dcs = (DiffChangeSet) cs;
			return dcs.getDiffTree().countFor(IThreeWayDiff.INCOMING, IThreeWayDiff.DIRECTION_MASK) > 0;
		}
		return false;
	}

	private boolean hasOutgoingChanges(ChangeSet cs) {
		if (cs instanceof DiffChangeSet) {
			DiffChangeSet dcs = (DiffChangeSet) cs;
			return dcs.getDiffTree().countFor(IThreeWayDiff.OUTGOING, IThreeWayDiff.DIRECTION_MASK) > 0;
		}
		return false;
	}

	private boolean isUnassignedSet(ChangeSet cs) {
		return cs == unassignedDiffs;
	}

	private boolean hasConflicts(ChangeSet cs) {
		if (cs instanceof DiffChangeSet) {
			DiffChangeSet dcs = (DiffChangeSet) cs;
			return dcs.getDiffTree().countFor(IThreeWayDiff.CONFLICTING, IThreeWayDiff.DIRECTION_MASK) > 0;
		}
		return false;
	}

	private boolean containsConflicts(ChangeSet cs) {
		if (cs instanceof DiffChangeSet) {
			DiffChangeSet dcs = (DiffChangeSet) cs;
			return dcs.getDiffTree().hasMatchingDiffs(ResourcesPlugin.getWorkspace().getRoot().getFullPath(), ResourceModelLabelProvider.CONFLICT_FILTER);
		}
		return false;
	}

	private boolean isVisible(Object object, IResourceDiffTree tree) {
		if (object instanceof IResource) {
			IResource resource = (IResource) object;
			IDiff diff = tree.getDiff(resource);
			if (diff != null && isVisible(diff))
				return true;
			int depth = getTraversalCalculator().getLayoutDepth(resource, null);
			IDiff[] diffs = tree.getDiffs(resource, depth);
			for (int i = 0; i < diffs.length; i++) {
				IDiff child = diffs[i];
				if (isVisible(child)) {
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean hasChildren(TreePath path) {
		if (path.getSegmentCount() == 1) {
			Object first = path.getFirstSegment();
			if (first instanceof ChangeSet) {
				return isVisibleInMode(first) && hasChildrenInContext((ChangeSet)first);
			}
		}
		return getChildren(path).length > 0;
	}

	private boolean hasChildrenInContext(ChangeSet set) {
		IResource[] resources = set.getResources();
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			if (getContext().getDiffTree().getDiff(resource) != null)
				return true;
		}
		return false;
	}

	@Override
	public TreePath[] getParents(Object element) {
		if (element instanceof ChangeSet) {
			return new TreePath[] { TreePath.EMPTY };
		}
		if (element instanceof IResource) {
			IResource resource = (IResource) element;
			DiffChangeSet[] sets = getSetsContaining(resource);
			if (sets.length > 0) {
				List result = new ArrayList();
				for (int i = 0; i < sets.length; i++) {
					DiffChangeSet set = sets[i];
					TreePath path = getPathForElement(set, resource.getParent());
					if (path != null)
						result.add(path);
				}
				return (TreePath[]) result.toArray(new TreePath[result.size()]);
			} else {
				TreePath path = getPathForElement(getUnassignedSet(), resource.getParent());
				if (path != null)
					return new TreePath[] { path };
			}
		}
		
		return new TreePath[0];
	}

	private DiffChangeSet[] getSetsContaining(IResource resource) {
		List result = new ArrayList();
		DiffChangeSet[] allSets = getAllSets();
		for (int i = 0; i < allSets.length; i++) {
			DiffChangeSet set = allSets[i];
			if (isVisible(resource, set.getDiffTree())) {
				result.add(set);
			}
		}
		return (DiffChangeSet[]) result.toArray(new DiffChangeSet[result.size()]);
	}

	/**
	 * Return all the change sets (incoming and outgoing). This 
	 * list must not include the unassigned set. 
	 * @return all the change sets (incoming and outgoing)
	 */
	private DiffChangeSet[] getAllSets() {
		List result = new ArrayList();
		ChangeSetCapability csc = getChangeSetCapability();
		if (csc.supportsActiveChangeSets()) {
			ActiveChangeSetManager collector = csc.getActiveChangeSetManager();
			ChangeSet[] sets = collector.getSets();	
			for (int i = 0; i < sets.length; i++) {
				ChangeSet set = sets[i];
				result.add(set);
			}
		}
		if (checkedInCollector != null) {
			ChangeSet[] sets = checkedInCollector.getSets();	
			for (int i = 0; i < sets.length; i++) {
				ChangeSet set = sets[i];
				result.add(set);
			}
		}
		return (DiffChangeSet[]) result.toArray(new DiffChangeSet[result.size()]);
	}

	private TreePath getPathForElement(DiffChangeSet set, IResource resource) {
		List pathList = getPath(set.getDiffTree(), resource);
		if (pathList != null) {
			pathList.add(0, set);
			TreePath path = new TreePath(pathList.toArray());
			return path;
		}
		return null;
	}
	
	private List getPath(IResourceDiffTree tree, IResource resource) {
		if (resource == null)
			return null;
		boolean hasDiff = tree.getDiff(resource) == null;
		if (hasDiff && tree.members(resource).length == 0)
			return null;
		if (resource.getType() == IResource.ROOT) {
			return null;
		}
		List result = new ArrayList();
		result.add(resource.getProject());
		if (resource.getType() != IResource.PROJECT) {
			String layout = getTraversalCalculator().getLayout();
			if (layout.equals(IPreferenceIds.FLAT_LAYOUT)) {
				result.add(resource);
			} else if (layout.equals(IPreferenceIds.COMPRESSED_LAYOUT) && resource.getType() == IResource.FOLDER) {
				result.add(resource);
			} else if (layout.equals(IPreferenceIds.COMPRESSED_LAYOUT) && resource.getType() == IResource.FILE) {
				IContainer parent = resource.getParent();
				if (parent.getType() != IResource.PROJECT)
					result.add(parent);
				result.add(resource);
			} else {
				List resourcePath = new ArrayList();
				IResource next = resource;
				while (next.getType() != IResource.PROJECT) {
					resourcePath.add(next);
					next = next.getParent();
				}
				for (int i = resourcePath.size() - 1; i >=0; i--) {
					result.add(resourcePath.get(i));
				}
			}
		}
		return result;
	}

	@Override
	public void init(ICommonContentExtensionSite site) {
		super.init(site);
		ChangeSetCapability csc = getChangeSetCapability();
		if (csc.supportsActiveChangeSets()) {
			ActiveChangeSetManager collector = csc.getActiveChangeSetManager();
			collector.addListener(collectorListener);
		}
		ChangeSetSorter sorter = getSorter();
		if (sorter != null) {
			sorter.setConfiguration(getConfiguration());
		}
	}

	private ChangeSetSorter getSorter() {
		INavigatorContentService contentService = getExtensionSite().getService();
		INavigatorSorterService sortingService = contentService.getSorterService();
		INavigatorContentExtension extension = getExtensionSite().getExtension();
		if (extension != null) {
			ViewerSorter sorter = sortingService.findSorter(extension.getDescriptor(), getModelProvider(), new DiffChangeSet(), new DiffChangeSet());
			if (sorter instanceof ChangeSetSorter) {
				return (ChangeSetSorter) sorter;
			}
		}
		return null;
	}
	
	private void initializeCheckedInChangeSetCollector(ChangeSetCapability csc) {
		if (csc.supportsCheckedInChangeSets()) {
			checkedInCollector = ((ModelParticipantChangeSetCapability)csc).createCheckedInChangeSetCollector(getConfiguration());
			getConfiguration().setProperty(CVSChangeSetCollector.CVS_CHECKED_IN_COLLECTOR, checkedInCollector);
			checkedInCollector.addListener(collectorListener);
			checkedInCollector.add(((ResourceDiffTree)getContext().getDiffTree()).getDiffs());
		}
	}
	
	@Override
	public void dispose() {
		ChangeSetCapability csc = getChangeSetCapability();
		if (csc.supportsActiveChangeSets()) {
			csc.getActiveChangeSetManager().removeListener(collectorListener);
		}
		if (checkedInCollector != null) {
			checkedInCollector.removeListener(collectorListener);
			checkedInCollector.dispose();
		}
		if (unassignedDiffs != null) {
			unassignedDiffs.getDiffTree().removeDiffChangeListener(diffTreeListener);
		}
		super.dispose();
	}
	
	@Override
	public boolean isVisible(IDiff diff) {
		return super.isVisible(diff);
	}

	public IResourceDiffTree getDiffTree(TreePath path) {
		if (path.getSegmentCount() > 0) {
			Object first = path.getFirstSegment();
			if (first instanceof DiffChangeSet) {
				DiffChangeSet set = (DiffChangeSet) first;
				return set.getDiffTree();
			}
		}
		return getTheRest();
	}
	
	@Override
	public void diffsChanged(IDiffChangeEvent event, IProgressMonitor monitor) {
		// Override inherited method to reconcile sub-trees
		IPath[] removed = event.getRemovals();
		IDiff[] added = event.getAdditions();
		IDiff[] changed = event.getChanges();
		// Only adjust the set of the rest. The others will be handled by the collectors
		try {
			getTheRest().beginInput();
			for (int i = 0; i < removed.length; i++) {
				IPath path = removed[i];
				getTheRest().remove(path);
			}
			for (int i = 0; i < added.length; i++) {
				IDiff diff = added[i];
				// Only add the diff if it is not already in another set
				if (!isContainedInSet(diff)) {
					getTheRest().add(diff);
				}
			}
			for (int i = 0; i < changed.length; i++) {
				IDiff diff = changed[i];
				// Only add the diff if it is already contained in the free set
				if (getTheRest().getDiff(diff.getPath()) != null) {
					getTheRest().add(diff);
				}
			}
		} finally {
			getTheRest().endInput(monitor);
		}
		if (checkedInCollector != null)
			checkedInCollector.handleChange(event);
		if (firstDiffChange) {
			// One the first diff event, refresh the viewer to ensure outgoing change sets appear
			firstDiffChange = false;
			Utils.asyncExec((Runnable) () -> ((AbstractTreeViewer) getViewer()).refresh(),
					(StructuredViewer) getViewer());
		}
	}
	
	@Override
	protected void updateLabels(ISynchronizationContext context, IPath[] paths) {
		super.updateLabels(context, paths);
		ChangeSet[] sets = getSetsShowingPropogatedStateFrom(paths);
		if (sets.length > 0)
			((AbstractTreeViewer)getViewer()).update(sets, null);
	}
	
	
	private ChangeSet[] getSetsShowingPropogatedStateFrom(IPath[] paths) {
		Set result = new HashSet();
		for (int i = 0; i < paths.length; i++) {
			IPath path = paths[i];
			ChangeSet[] sets = getSetsShowingPropogatedStateFrom(path);
			for (int j = 0; j < sets.length; j++) {
				ChangeSet set = sets[j];
				result.add(set);
			}
		}
		return (ChangeSet[]) result.toArray(new ChangeSet[result.size()]);
	}
	
	protected DiffChangeSet[] getSetsShowingPropogatedStateFrom(IPath path) {
		List result = new ArrayList();
		DiffChangeSet[] allSets = getAllSets();
		for (int i = 0; i < allSets.length; i++) {
			DiffChangeSet set = allSets[i];
			if (set.getDiffTree().getDiff(path) != null || set.getDiffTree().getChildren(path).length > 0) {
				result.add(set);
			}
		}
		return (DiffChangeSet[]) result.toArray(new DiffChangeSet[result.size()]);
	}

	public ChangeSetCapability getChangeSetCapability() {
		ISynchronizeParticipant participant = getConfiguration().getParticipant();
		if (participant instanceof IChangeSetProvider) {
			IChangeSetProvider provider = (IChangeSetProvider) participant;
			return provider.getChangeSetCapability();
		}
		return null;
	}
	
	private Set getVisibleSetsInViewer() {
		TreeViewer viewer = (TreeViewer)getViewer();
		Tree tree = viewer.getTree();
		TreeItem[] children = tree.getItems();
		Set result = new HashSet();
		for (int i = 0; i < children.length; i++) {
			TreeItem control = children[i];
			Object data = control.getData();
			if (data instanceof ChangeSet) {
				ChangeSet set = (ChangeSet) data;
				result.add(set);
			}
		}
		return result;
	}

}
