/*******************************************************************************
 * Copyright (c) 2000, 2018 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.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.TreeEvent;
import org.eclipse.swt.events.TreeListener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.team.core.ITeamStatus;
import org.eclipse.team.core.synchronize.ISyncInfoSetChangeEvent;
import org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener;
import org.eclipse.team.core.synchronize.ISyncInfoTreeChangeEvent;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.synchronize.SyncInfoSet;
import org.eclipse.team.internal.core.TeamPlugin;
import org.eclipse.team.internal.ui.Policy;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.ui.synchronize.ISynchronizeModelElement;
import org.eclipse.team.ui.synchronize.ISynchronizePage;
import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
import org.eclipse.team.ui.synchronize.SynchronizePageActionGroup;

/**
 * This class is responsible for creating and maintaining a presentation model of
 * {@link SynchronizeModelElement} elements that can be shown in a viewer. The model
 * is based on the synchronization information contained in the provided {@link SyncInfoSet}.
 */
public abstract class AbstractSynchronizeModelProvider implements ISynchronizeModelProvider, ISyncInfoSetChangeListener, TreeListener {

	/**
	 * Property constant for the expansion state for the elements displayed by the page. The
	 * expansion state is a List of resource paths.
	 */
	public static final String P_VIEWER_EXPANSION_STATE = TeamUIPlugin.ID  + ".P_VIEWER_EXPANSION_STATE"; //$NON-NLS-1$

	/**
	 * Property constant for the selection state for the elements displayed by the page. The
	 * selection state is a List of resource paths.
	 */
	public static final String P_VIEWER_SELECTION_STATE = TeamUIPlugin.ID  + ".P_VIEWER_SELECTION_STATE"; //$NON-NLS-1$

	/**
	 * Property constant for the checked state for the elements displayed by the page. The
	 * checked state is a List of resource paths.
	 */
	public static final String P_VIEWER_CHECKED_STATE = TeamUIPlugin.ID  + ".P_VIEWER_CHECKED_STATE"; //$NON-NLS-1$

	private ISynchronizeModelElement root;

	private ISynchronizePageConfiguration configuration;

	private SyncInfoSet set;

	private SynchronizeModelUpdateHandler updateHandler;

	private boolean disposed = false;

	private SynchronizePageActionGroup actionGroup;

	private ListenerList<IPropertyChangeListener> listeners;

	private static final boolean DEBUG = false;

	/**
	 * Constructor for creating a sub-provider
	 * @param parentProvider the parent provider
	 * @param parentNode the root node of the model built by this provider
	 * @param configuration the sync page configuration
	 * @param set the sync info set from which the model is built
	 */
	protected AbstractSynchronizeModelProvider(AbstractSynchronizeModelProvider parentProvider, ISynchronizeModelElement parentNode, ISynchronizePageConfiguration configuration, SyncInfoSet set) {
		Assert.isNotNull(set);
		Assert.isNotNull(parentNode);
		this.root = parentNode;
		this.set = set;
		this.configuration = configuration;
		if (parentProvider == null) {
			// The update handler will register for sync change events
			// with the sync set when the handler is activated
			updateHandler = new SynchronizeModelUpdateHandler(this);
			getTree().addTreeListener(this);
		} else {
			// We will use the parent's update handler and register for changes with the given set
			updateHandler = parentProvider.updateHandler;
			set.addSyncSetChangedListener(this);
		}
	}

	private Tree getTree() {
		return ((Tree)((AbstractTreeViewer)getViewer()).getControl());
	}

	/**
	 * Constructor for creating a root model provider.
	 * @param configuration the sync page configuration
	 * @param set the sync info set from which the model is built
	 */
	protected AbstractSynchronizeModelProvider(ISynchronizePageConfiguration configuration, SyncInfoSet set) {
		this(null, new UnchangedResourceModelElement(null, ResourcesPlugin.getWorkspace().getRoot()) {
			/*
			 * Override to ensure that the diff viewer will appear in CompareEditorInputs
			 */
			@Override
			public boolean hasChildren() {
				return true;
			}
		}, configuration, set);
		// Register the action group for this provider, since it is the root provider
		SynchronizePageActionGroup actionGroup = getActionGroup();
		if (actionGroup != null) {
			configuration.addActionContribution(actionGroup);
		}
	}

	/**
	 * Return the action group for this provider or <code>null</code>
	 * if there are no actions associated with this provider. The action
	 * group will be registered with the configuration if this is
	 * the root provider. If this provider is a sub-provider, it
	 * is up to the parent provider to register the action group.
	 * <p>
	 * The action group for a provider is created by calling the
	 * <code>createdActionGroup</code> method. If this method returns
	 * a non-null group, it is cached so it can be disposed
	 * when the provider is disposed.
	 * @return the action group for this provider or <code>null</code>
	 * if there are no actions associated with this provider
	 */
	public final synchronized SynchronizePageActionGroup getActionGroup() {
		if (actionGroup == null) {
			actionGroup = createActionGroup();
		}
		return actionGroup;
	}

	/**
	 * Create the action group for this provider. By default,
	 * a <code>null</code> is returned. Subclasses may override.
	 * @return the action group for this provider or <code>null</code>
	 */
	protected SynchronizePageActionGroup createActionGroup() {
		return null;
	}

	/**
	 * Return the set that contains the elements this provider is using as
	 * a basis for creating a presentation model. This cannot be null.
	 *
	 * @return the set that contains the elements this provider is
	 * using as a basis for creating a presentation model.
	 */
	@Override
	public SyncInfoSet getSyncInfoSet() {
		return set;
	}

	/**
	 * Returns the input created by this provider or <code>null</code> if
	 * {@link #prepareInput(IProgressMonitor)} hasn't been called on this object yet.
	 *
	 * @return the input created by this provider.
	 */
	@Override
	public ISynchronizeModelElement getModelRoot() {
		return root;
	}

	/**
	 * Return the page configuration for this provider.
	 *
	 * @return the page configuration for this provider.
	 */
	public ISynchronizePageConfiguration getConfiguration() {
		return configuration;
	}

	/**
	 * Return the <code>AbstractTreeViewer</code> associated with this
	 * provider or <code>null</code> if the viewer is not of the proper type.
	 * @return the structured viewer that is displaying the model managed by this provider
	 */
	@Override
	public StructuredViewer getViewer() {
		ISynchronizePage page = configuration.getPage();
		if (page == null) return null;
		Viewer viewer = page.getViewer();
		if (viewer instanceof AbstractTreeViewer) {
			return (AbstractTreeViewer)viewer;
		}
		return null;
	}

	/**
	 * Builds the viewer model based on the contents of the sync set.
	 */
	@Override
	public ISynchronizeModelElement prepareInput(IProgressMonitor monitor) {
		// Connect to the sync set which will register us as a listener and give us a reset event
		// in a background thread
		if (isRootProvider()) {
			updateHandler.connect(monitor);
		} else {
			getSyncInfoSet().connect(this, monitor);
		}
		return getModelRoot();
	}

	/**
	 * Calculate the problem marker that should be shown on the given
	 * element. The returned property can be either
	 * ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY or
	 * ISynchronizeModelElement.PROPAGATED_WARNING_MARKER_PROPERTY.
	 * @param element a synchronize model element
	 * @return the marker property that should be displayed on the element
	 * or <code>null</code> if no marker should be displayed
	 */
	public String calculateProblemMarker(ISynchronizeModelElement element) {
		IResource resource = element.getResource();
		String property = null;
		if (resource != null && resource.exists()) {
			try {
				IMarker[] markers = resource.findMarkers(IMarker.PROBLEM, true, getLogicalModelDepth(resource));
				for (int i = 0; i < markers.length; i++) {
					IMarker marker = markers[i];
					try {
						Integer severity = (Integer) marker.getAttribute(IMarker.SEVERITY);
						if (severity != null) {
							if (severity.intValue() == IMarker.SEVERITY_ERROR) {
								property = ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY;
								break;
							} else if (severity.intValue() == IMarker.SEVERITY_WARNING) {
								property = ISynchronizeModelElement.PROPAGATED_WARNING_MARKER_PROPERTY;
								// Keep going because there may be errors on other resources
							}
						}
					} catch (CoreException e) {
						if (!resource.exists()) {
							// The resource was deleted concurrently. Forget any previously found property
							property = null;
							break;
						}
						// If the marker exists, log the exception and continue.
						// Otherwise, just ignore the exception and keep going
						if (marker.exists()) {
							TeamPlugin.log(e);
						}
					}
				}
			} catch (CoreException e) {
				// If the resource exists (is accessible), log the exception and continue.
				// Otherwise, just ignore the exception
				if (resource.isAccessible()
						&& e.getStatus().getCode() != IResourceStatus.RESOURCE_NOT_FOUND
						&& e.getStatus().getCode() != IResourceStatus.PROJECT_NOT_OPEN) {
					TeamPlugin.log(e);
				}
			}
		} else if (resource == null) {
			// For non-resource elements, show the same propogaqted marker as the children
			IDiffElement[] children = element.getChildren();
			for (int i = 0; i < children.length; i++) {
				IDiffElement child = children[i];
				if (child instanceof ISynchronizeModelElement) {
					ISynchronizeModelElement childElement = (ISynchronizeModelElement)child;
					if (childElement.getProperty(ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY)) {
						property = ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY;
						break;
					} else if (childElement.getProperty(ISynchronizeModelElement.PROPAGATED_WARNING_MARKER_PROPERTY)) {
						property = ISynchronizeModelElement.PROPAGATED_WARNING_MARKER_PROPERTY;
						// Keep going because there may be errors on other resources
					}

				}
			}
		}
		return property;
	}

	/**
	 * Return the logical model depth used for marker propagation
	 * @param resource the resource
	 * @return the depth the resources should be traversed
	 */
	protected int getLogicalModelDepth(IResource resource) {
		return IResource.DEPTH_INFINITE;
	}

	/**
	 * Update the label of the given diff node. The label for nodes queued
	 * using this method will not be updated until <code>firePendingLabelUpdates</code>
	 * is called.
	 * @param diffNode the diff node to be updated
	 */
	protected void queueForLabelUpdate(ISynchronizeModelElement diffNode) {
		updateHandler.queueForLabelUpdate(diffNode);
	}

	/**
	 * Throw away any old state associated with this provider and
	 * rebuild the model from scratch.
	 */
	protected void reset() {
		// save expansion state
		if(isRootProvider() && hasViewerState()) {
			saveViewerState();
		}

		// Clear existing model, but keep the root node
		clearModelObjects(getModelRoot());

		// Rebuild the model
		buildModelObjects(getModelRoot());

		// Notify listeners that model has changed
		ISynchronizeModelElement root = getModelRoot();
		if(root instanceof SynchronizeModelElement) {
			((SynchronizeModelElement)root).fireChanges();
		}

		if (Utils.canUpdateViewer(getViewer())) {
			// If we can update the viewer, that means that the view was updated
			// when the model was rebuilt.
			refreshModelRoot();
		} else {
			// Only refresh the view if there is now background update in
			// progress. If there is, the background update will refresh
			if (!updateHandler.isPerformingBackgroundUpdate()) {
				Utils.asyncExec((Runnable) () -> refreshModelRoot(), getViewer());
			}
		}
	}

	private void refreshModelRoot() {
		StructuredViewer viewer = getViewer();
		if (viewer != null && !viewer.getControl().isDisposed()) {
			try {
				viewer.getControl().setRedraw(false);
				if (isRootProvider() || getModelRoot().getParent() == null) {
					// Refresh the entire view
					viewer.refresh();
				} else {
					// Only refresh the model root bu also ensure that
					// the parents of the model root and the model root
					// itself are added to the view
					addToViewer(getModelRoot());
				}
				//	restore expansion state
				if (isRootProvider())
					restoreViewerState();
			} finally {
				viewer.getControl().setRedraw(true);
			}
		}
	}

	/**
	 * For each node create children based on the contents of
	 * @param node
	 * @return the diff elements
	 */
	protected abstract IDiffElement[] buildModelObjects(ISynchronizeModelElement node);

	/**
	 * Returns whether the viewer has state to be saved.
	 * @return whether the viewer has state to be saved
	 */
	protected abstract boolean hasViewerState();

	/*
	 * Return all the resources that are expanded in the page.
	 * This method should only be called in the UI thread
	 * after validating that the viewer is still valid.
	 */
	protected IResource[] getExpandedResources() {
		Set<IResource> expanded = new HashSet<>();
		IResource[] savedExpansionState = getCachedResources(P_VIEWER_EXPANSION_STATE);
		for (int i = 0; i < savedExpansionState.length; i++) {
			IResource resource = savedExpansionState[i];
			expanded.add(resource);
		}
		StructuredViewer viewer = getViewer();
		Object[] objects = ((AbstractTreeViewer) viewer).getVisibleExpandedElements();
		IResource[] currentExpansionState = getResources(objects);
		for (int i = 0; i < currentExpansionState.length; i++) {
			IResource resource = currentExpansionState[i];
			expanded.add(resource);
		}
		return expanded.toArray(new IResource[expanded.size()]);
	}

	/*
	 * Return all the resources that are selected in the page.
	 * This method should only be called in the UI thread
	 * after validating that the viewer is still valid.
	 */
	protected IResource[] getSelectedResources() {
		StructuredViewer viewer = getViewer();
		return getResources(viewer.getStructuredSelection().toArray());
	}

	/*
	 * Return all the resources that are checked in the page.
	 * This method should only be called in the UI thread
	 * after validating that the viewer is still valid.
	 */
	protected IResource[] getCheckedResources() {
		StructuredViewer viewer = getViewer();
		if (viewer instanceof CheckboxTreeViewer){
			return getResources(((CheckboxTreeViewer)viewer).getCheckedElements());
		}

		return new IResource[0];
	}

	/*
	 * Expand the resources if they appear in the page.
	 * This method should only be called in the UI thread
	 * after validating that the viewer is still valid.
	 */
	protected void expandResources(IResource[] resources) {
		Set<ISynchronizeModelElement> expandedElements = new HashSet<>();
		StructuredViewer viewer = getViewer();
		for (int j = 0; j < resources.length; j++) {
			IResource resource = resources[j];
			ISynchronizeModelElement[] elements = getModelObjects(resource);
			// Only expand when there is one element per resource
			if (elements.length == 1) {
				for (int i = 0; i < elements.length; i++) {
					ISynchronizeModelElement element = elements[i];
					// Add all parents of the element to the expansion set
					while (element != null) {
						expandedElements.add(element);
						element = (ISynchronizeModelElement)element.getParent();
					}
				}
			}
		}
		if (!expandedElements.isEmpty())
			((AbstractTreeViewer) viewer).setExpandedElements(expandedElements.toArray());
	}

	protected IResource[] getResources(Object[] objects) {
		Set<IResource> result = new HashSet<>();
		if (objects.length > 0) {
			for (int i = 0; i < objects.length; i++) {
				if (objects[i] instanceof ISynchronizeModelElement) {
					IResource resource = ((ISynchronizeModelElement)objects[i]).getResource();
					if(resource != null)
						result.add(resource);
				}
			}
		}
		return result.toArray(new IResource[result.size()]);
	}

	private void clearResourceCache(String configProperty) {
		getConfiguration().setProperty(configProperty, null);
	}

	private void cacheResources(IResource[] resources, String configProperty) {
		if (resources.length > 0) {
			ISynchronizePageConfiguration config = getConfiguration();
			ArrayList<String> paths = new ArrayList<>();
			for (int i = 0; i < resources.length; i++) {
				IResource resource = resources[i];
				String path = resource.getFullPath().toString();
				if (resource.getType() != IResource.FILE && path.charAt(path.length() - 1) != IPath.SEPARATOR) {
					// Include a trailing slash on folders and projects.
					// It is used when recreating cached resources that don't exist locally
					path += IPath.SEPARATOR;
				}
				paths.add(path);
			}
			config.setProperty(configProperty, paths);
		} else {
			clearResourceCache(configProperty);
		}
	}

	private IResource[] getCachedResources(String configProperty) {
		List paths = (List)getConfiguration().getProperty(configProperty);
		if (paths == null)
			return new IResource[0];
		IContainer container = ResourcesPlugin.getWorkspace().getRoot();
		ArrayList<IResource> resources = new ArrayList<>();
		for (Iterator it = paths.iterator(); it.hasNext();) {
			String path = (String) it.next();
			IResource resource = getResourceForPath(container, path);
			if (resource != null) {
				resources.add(resource);
			}
		}
		return resources.toArray(new IResource[resources.size()]);
	}

	/**
	 * Save the viewer state (expansion and selection)
	 */
	protected void saveViewerState() {
		//	save visible expanded elements and selection
		final StructuredViewer viewer = getViewer();
		if (viewer != null && !viewer.getControl().isDisposed() && viewer instanceof AbstractTreeViewer) {
			//check to see if we should store the checked states of the tree

			final boolean storeChecks = ((SynchronizePageConfiguration)configuration).getViewerStyle() == SynchronizePageConfiguration.CHECKBOX;
			final IResource[][] expandedResources = new IResource[1][0];
			final IResource[][] selectedResources = new IResource[1][0];
			final IResource[][] checkedResources = new IResource[1][0];
			viewer.getControl().getDisplay().syncExec(() -> {
				if (viewer != null && !viewer.getControl().isDisposed()) {
					expandedResources[0] = getExpandedResources();
					selectedResources[0] = getSelectedResources();
					if (storeChecks)
						checkedResources [0] = getCheckedResources();
				}
			});

			// Save expansion and selection
			cacheResources(expandedResources[0], P_VIEWER_EXPANSION_STATE);
			cacheResources(selectedResources[0], P_VIEWER_SELECTION_STATE);
			if (storeChecks)
				cacheResources(checkedResources[0], P_VIEWER_CHECKED_STATE);
		}
	}

	/**
	 * Restore the expansion state and selection of the viewer.
	 * This method must be invoked from within the UI thread.
	 */
	protected void restoreViewerState() {
		// restore expansion state and selection state
		final StructuredViewer viewer = getViewer();
		if (viewer != null && !viewer.getControl().isDisposed() && viewer instanceof AbstractTreeViewer) {
			IResource[] resourcesToExpand = getCachedResources(P_VIEWER_EXPANSION_STATE);
			IResource[] resourcesToSelect = getCachedResources(P_VIEWER_SELECTION_STATE);
			if (((SynchronizePageConfiguration)configuration).getViewerStyle() == SynchronizePageConfiguration.CHECKBOX){
				IResource[] resourcesToCheck = getCachedResources(P_VIEWER_CHECKED_STATE);
				checkResources(resourcesToCheck);
			}
			expandResources(resourcesToExpand);
			selectResources(resourcesToSelect);
		}
	}

	/*
	 * Select the given resources in the view. This method can
	 * only be invoked from the UI thread.
	 */
	protected void selectResources(IResource[] resourcesToSelect) {
		StructuredViewer viewer = getViewer();
		final ArrayList<ISynchronizeModelElement> selectedElements = new ArrayList<>();
		for (int i = 0; i < resourcesToSelect.length; i++) {
			IResource resource = resourcesToSelect[i];
			ISynchronizeModelElement[] elements = getModelObjects(resource);
			// Only preserve the selection if there is one element for the resource
			if (elements.length == 1) {
				selectedElements.add(elements[0]);
			}
		}
		if (!selectedElements.isEmpty())
			viewer.setSelection(new StructuredSelection(selectedElements));
	}

	/*
	 * Check the given resources in the view. This method can
	 * only be invoked from the UI thread.
	 */
	protected void checkResources(IResource[] resourcesToCheck) {
		Set<ISynchronizeModelElement> checkedElements = new HashSet<>();
		StructuredViewer viewer = getViewer();
		if (!(viewer instanceof CheckboxTreeViewer))
			return;

		for (int j = 0; j < resourcesToCheck.length; j++) {
			IResource resource = resourcesToCheck[j];
			if (resource.getType() != IResource.FILE)
				continue;

			ISynchronizeModelElement[] elements = getModelObjects(resource);
			// Only expand when there is one element per resource
			if (elements.length == 1) {
				for (int i = 0; i < elements.length; i++) {
					ISynchronizeModelElement element = elements[i];
					checkedElements.add(element);
				}
			}
		}
		if (!checkedElements.isEmpty())
			((CheckboxTreeViewer) viewer).setCheckedElements(checkedElements.toArray());
	}

	/*
	 * Convert a path to a resource by first looking in the resource
	 * tree and, if that fails, by using the path format to create
	 * a handle.
	 */
	private IResource getResourceForPath(IContainer container, String path) {
		IResource resource = container.findMember(path, true /* include phantoms */);
		if (resource == null) {
			try {
				// The resource doesn't have an entry on the resources tree
				// but may still appear in the view so try to deduce the type
				// from the path
				if (path.endsWith(Character.toString(IPath.SEPARATOR))) {
					resource = container.getFolder(new Path(null, path));
				} else {
					resource = container.getFile(new Path(null, path));
				}
			} catch (IllegalArgumentException e) {
				// Couldn't get a resource handle so ignore
			}
		}
		return resource;
	}

	@Override
	public void treeCollapsed(TreeEvent e) {
		clearResourceCache(P_VIEWER_EXPANSION_STATE);
	}

	@Override
	public void treeExpanded(TreeEvent e) {
		clearResourceCache(P_VIEWER_EXPANSION_STATE);
	}

	/**
	 * Return all the model objects in this provider that represent the given resource
	 * @param resource the resource
	 * @return the model objects for the resource
	 */
	protected abstract ISynchronizeModelElement[] getModelObjects(IResource resource);

	@Override
	public void saveState() {
		saveViewerState();
	}

	/**
	 * Method invoked when a sync element is added or removed or its state changes.
	 * This method can be invoked from the UI thread or a background thread.
	 * @param element synchronize element
	 * @param clear <code>true</code> if the conflict bit of the element was cleared
	 * (i.e. the element has been deleted)
	 */
	protected void propogateConflictState(ISynchronizeModelElement element, boolean clear) {
		boolean isConflict = clear ? false : isConflicting(element);
		boolean wasConflict = element.getProperty(ISynchronizeModelElement.PROPAGATED_CONFLICT_PROPERTY);
		// Only propagate and update parent labels if the state of the element has changed
		if (isConflict != wasConflict) {
			element.setPropertyToRoot(ISynchronizeModelElement.PROPAGATED_CONFLICT_PROPERTY, isConflict);
			updateHandler.updateParentLabels(element);
		}
	}

	/**
	 * Return whether the given model element represents a conflict.
	 * @param element the element being tested
	 * @return whether the element is a conflict
	 */
	protected boolean isConflicting(ISynchronizeModelElement element) {
		return (element.getKind() & SyncInfo.DIRECTION_MASK) == SyncInfo.CONFLICTING;
	}

	/**
	 * Dispose of the provider
	 */
	@Override
	public void dispose() {
		// Only dispose the update handler if it is
		// directly associated with this provider
		if (isRootProvider()) {
			updateHandler.dispose();
			getTree().removeTreeListener(this);
		} else {
			set.removeSyncSetChangedListener(this);
		}
		if (actionGroup != null) {
			Utils.syncExec((Runnable) () -> actionGroup.dispose(), getViewer());
		}
		this.disposed = true;
	}

	private boolean isRootProvider() {
		return updateHandler.getProvider() == this;
	}

	/**
	 * Return whether this provide has been disposed.
	 * @return whether this provide has been disposed
	 */
	public boolean isDisposed() {
		return disposed;
	}

	/**
	 * Return the closest parent elements that represents a model element that
	 * could contains the given resource. Multiple elements need only be returned
	 * if two or more logical views are being shown and each view has an element
	 * that could contain the resource.
	 * @param resource the resource
	 * @return one or more lowest level parents that could contain the resource
	 */
	public abstract ISynchronizeModelElement[] getClosestExistingParents(IResource resource);

	/**
	 * Handle the changes made to the viewer's <code>SyncInfoSet</code>.
	 * This method delegates the changes to the three methods <code>handleResourceChanges(ISyncInfoSetChangeEvent)</code>,
	 * <code>handleResourceRemovals(ISyncInfoSetChangeEvent)</code> and
	 * <code>handleResourceAdditions(ISyncInfoSetChangeEvent)</code>.
	 * @param event
	 *            the event containing the changed resources.
	 */
	protected void handleChanges(ISyncInfoTreeChangeEvent event, IProgressMonitor monitor) {
		handleResourceChanges(event);
		handleResourceRemovals(event);
		handleResourceAdditions(event);
	}

	/**
	 * Update the viewer for the sync set additions in the provided event. This
	 * method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>.
	 * Subclasses may override.
	 * @param event
	 */
	protected abstract void handleResourceAdditions(ISyncInfoTreeChangeEvent event);

	/**
	 * Update the viewer for the sync set changes in the provided event. This
	 * method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>.
	 * Subclasses may override.
	 * @param event
	 */
	protected abstract void handleResourceChanges(ISyncInfoTreeChangeEvent event);

	/**
	 * Update the viewer for the sync set removals in the provided event. This
	 * method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>.
	 * Subclasses may override.
	 * @param event
	 */
	protected abstract void handleResourceRemovals(ISyncInfoTreeChangeEvent event);

	@Override
	public void syncInfoChanged(final ISyncInfoSetChangeEvent event, final IProgressMonitor monitor) {
		if (! (event instanceof ISyncInfoTreeChangeEvent)) {
			reset();
		} else {
			updateHandler.runViewUpdate(() -> handleChanges((ISyncInfoTreeChangeEvent)event, monitor), true /* preserve expansion */);
		}
	}

	@Override
	public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) {
		// Not handled

	}

	@Override
	public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) {
		reset();
	}

	protected void addToViewer(ISynchronizeModelElement node) {
		if (DEBUG) {
			System.out.println("Adding model element " + node.getName()); //$NON-NLS-1$
		}
		propogateConflictState(node, false);
		// Set the marker property on this node.
		// There is no need to propagate this to the parents
		// as they will be displaying the proper marker already
		String property = calculateProblemMarker(node);
		if (property != null) {
			node.setProperty(property, true);
			// Parent resource nodes would have been properly calculated when they were added.
			// However, non-resource nodes would not so we need to propagate the marker to them
			propogateMarkerPropertyToParent(node, property);
		}
		if (Utils.canUpdateViewer(getViewer())) {
			doAdd((SynchronizeModelElement)node.getParent(), node);
		}
		updateHandler.nodeAdded(node, this);
	}

	/*
	 * Propagate the marker property to the parent if it is not already there.
	 * Only propagate warnings if the parent isn't an error already.
	 */
	private void propogateMarkerPropertyToParent(ISynchronizeModelElement node, String property) {
		ISynchronizeModelElement parent = (ISynchronizeModelElement)node.getParent();
		if (parent != null
				&& !parent.getProperty(property)
				&& !parent.getProperty(ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY)) {
			parent.setProperty(property, true);
			propogateMarkerPropertyToParent(parent, property);
		}
	}

	/**
	 * Remove any traces of the model element and any of it's descendants in the
	 * hierarchy defined by the content provider from the content provider and
	 * the viewer it is associated with.
	 * @param nodes the model elements to remove
	 */
	protected void removeFromViewer(ISynchronizeModelElement[] nodes) {
		List<ISynchronizeModelElement> rootsToClear = new ArrayList<>();
		for (int i = 0; i < nodes.length; i++) {
			ISynchronizeModelElement node = nodes[i];
			if (DEBUG) {
				System.out.println("Removing model element " + node.getName()); //$NON-NLS-1$
			}
			ISynchronizeModelElement rootToClear= getRootToClear(node);
			if (DEBUG) {
				if (rootToClear != node) {
					System.out.println("Removing parent element " + rootToClear.getName()); //$NON-NLS-1$
				}
			}
			propogateConflictState(rootToClear, true /* clear the conflict */);
			clearModelObjects(rootToClear);
			rootsToClear.add(rootToClear);
		}
		ISynchronizeModelElement[] roots = rootsToClear.toArray(new ISynchronizeModelElement[rootsToClear.size()]);
		if (Utils.canUpdateViewer(getViewer())) {
			doRemove(roots);
		}
		for (int i = 0; i < roots.length; i++) {
			ISynchronizeModelElement element = roots[i];
			updateHandler.nodeRemoved(element, this);
		}
	}

	/**
	 * Clear the model objects from the diff tree, cleaning up any cached state
	 * (such as resource to model object map). This method recurses deeply on
	 * the tree to allow the cleanup of any cached state for the children as
	 * well.
	 * @param node the root node
	 */
	protected final void clearModelObjects(ISynchronizeModelElement node) {
		// When clearing model objects, any parents of the node
		// That are not out-of-sync, not the model root and that would
		// be empty as a result of this clear, should also be cleared.
		ISynchronizeModelElement rootToClear = getRootToClear(node);
		// Recursively clear the nodes from the root
		recursiveClearModelObjects(rootToClear);
		if (node == getModelRoot()) {
			IDiffElement[] children = node.getChildren();
			for (int i = 0; i < children.length; i++) {
				IDiffElement element = children[i];
				((SynchronizeModelElement)node).remove(element);
			}
		} else {
			SynchronizeModelElement parent = ((SynchronizeModelElement)node.getParent());
			if (parent != null) parent.remove(node);
		}
	}

	/**
	 * Method that subclasses can override when clearing model objects.
	 * @param node the node to be cleared recursively
	 */
	protected void recursiveClearModelObjects(ISynchronizeModelElement node) {
		// Clear all the children of the node
		IDiffElement[] children = node.getChildren();
		for (int i = 0; i < children.length; i++) {
			IDiffElement element = children[i];
			if (element instanceof ISynchronizeModelElement) {
				ISynchronizeModelElement sme = (ISynchronizeModelElement) element;
				ISynchronizeModelProvider provider = getProvider(sme);
				if (provider != null && provider instanceof AbstractSynchronizeModelProvider) {
					((AbstractSynchronizeModelProvider)provider).recursiveClearModelObjects(sme);
				} else {
					recursiveClearModelObjects(sme);
				}
			}
		}
		// Notify the update handler that the node has been cleared
		if (node != getModelRoot())
			updateHandler.modelObjectCleared(node);
	}

	/*
	 * Remove to root should only remove to the root of the provider and not the
	 * diff tree.
	 */
	private ISynchronizeModelElement getRootToClear(ISynchronizeModelElement node) {
		if (node == getModelRoot()) return node;
		ISynchronizeModelElement parent = (ISynchronizeModelElement)node.getParent();
		if (parent != null && parent != getModelRoot() && !isOutOfSync(parent) && parent.getChildren().length == 1) {
			return getRootToClear(parent);
		}
		return node;
	}

	/*
	 * Return whether the node represents an out-of-sync resource.
	 */
	protected boolean isOutOfSync(ISynchronizeModelElement node) {
		SyncInfo info = Utils.getSyncInfo(node);
		return (info != null && info.getKind() != SyncInfo.IN_SYNC);
	}

	protected boolean isOutOfSync(IResource resource) {
		SyncInfo info = getSyncInfoSet().getSyncInfo(resource);
		return (info != null && info.getKind() != SyncInfo.IN_SYNC);
	}

	/**
	 * Return the provider that created and manages the given
	 * model element. The default is to return the receiver.
	 * Subclasses may override.
	 * @param element the synchronize model element
	 * @return the provider that created the element
	 */
	protected ISynchronizeModelProvider getProvider(ISynchronizeModelElement element) {
		return this;
	}

	/**
	 * Add the element to the viewer.
	 * @param parent the parent of the element which is already added to the viewer
	 * @param element the element to be added to the viewer
	 */
	protected void doAdd(ISynchronizeModelElement parent, ISynchronizeModelElement element) {
		updateHandler.doAdd(parent, element);
	}

	/**
	 * Remove the element from the viewer
	 * @param elements the elements to be removed
	 */
	protected void doRemove(ISynchronizeModelElement[] elements) {
		AbstractTreeViewer viewer = (AbstractTreeViewer)getViewer();
		try {
			viewer.remove(elements);
		} catch (SWTException e) {
			// The remove failed due to an SWT exception. Log it and continue
			TeamUIPlugin.log(IStatus.ERROR, "An error occurred removing elements from the synchronize view", e); //$NON-NLS-1$
		}
		if (DEBUG) {
			for (int i = 0; i < elements.length; i++) {
				ISynchronizeModelElement element = elements[i];
				System.out.println("Removing view item " + element.getName()); //$NON-NLS-1$
			}
		}
	}

	/**
	 * This is a callback from the model update handler that gets invoked
	 * when a node is added to the viewer. It is only invoked for the
	 * root level model provider.
	 * @param node
	 * @param provider the provider that added the node
	 */
	protected void nodeAdded(ISynchronizeModelElement node, AbstractSynchronizeModelProvider provider) {
		// Default is to do nothing
	}

	/**
	 * This is a callback from the model update handler that gets invoked
	 * when a node is removed from the viewer. It is only invoked for the
	 * root level model provider. A removed node may have children for
	 * which a <code>nodeRemoved</code> callback is not received (see
	 * <code>modelObjectCleared</code>).
	 * @param node
	 */
	protected void nodeRemoved(ISynchronizeModelElement node, AbstractSynchronizeModelProvider provider) {
		// Default is to do nothing
	}

	/**
	 * This is a callback from the model update handler that gets invoked
	 * when a node is cleared from the model. It is only invoked for the
	 * root level model provider. This callback is deep in the sense that
	 * a callback is sent for each node that is cleared.
	 * @param node the node that was cleared.
	 */
	public void modelObjectCleared(ISynchronizeModelElement node) {
		// Default is to do nothing
	}

	@Override
	public void addPropertyChangeListener(IPropertyChangeListener listener) {
		synchronized (this) {
			if (listeners == null) {
				listeners = new ListenerList<>(ListenerList.IDENTITY);
			}
			listeners.add(listener);
		}

	}
	@Override
	public void removePropertyChangeListener(IPropertyChangeListener listener) {
		if (listeners != null) {
			synchronized (this) {
				listeners.remove(listener);
				if (listeners.isEmpty()) {
					listeners = null;
				}
			}
		}
	}

	protected void firePropertyChange(String key, Object oldValue, Object newValue) {
		Object[] allListeners;
		synchronized(this) {
			allListeners = listeners.getListeners();
		}
		final PropertyChangeEvent event = new PropertyChangeEvent(this, key, oldValue, newValue);
		for (int i = 0; i < allListeners.length; i++) {
			final IPropertyChangeListener listener = (IPropertyChangeListener)allListeners[i];
			SafeRunner.run(new ISafeRunnable() {
				@Override
				public void handleException(Throwable exception) {
					// Error is logged by platform
				}
				@Override
				public void run() throws Exception {
					listener.propertyChange(event);
				}
			});
		}
	}

	/**
	 * Wait until the provider is done processing any events and
	 * the page content are up-to-date.
	 * This method is for testing purposes only.
	 * @param monitor
	 */
	public void waitUntilDone(IProgressMonitor monitor) {
		monitor.worked(1);
		// wait for the event handler to process changes.
		while(updateHandler.getEventHandlerJob().getState() != Job.NONE) {
			monitor.worked(1);
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
			}
			Policy.checkCanceled(monitor);
		}
		monitor.worked(1);
	}

	@Override
	public String toString() {
		ISynchronizeModelElement element = getModelRoot();
		String name = getClass().getName();
		int index = name.lastIndexOf("."); //$NON-NLS-1$
		if (index != -1) {
			name = name.substring(index + 1);
		}
		String name2 = element.getName();
		if (name2.length() == 0) {
			name2 = "/"; //$NON-NLS-1$
		}
		return name + ": " + name2; //$NON-NLS-1$
	}

	/**
	 * Execute a runnable which performs an update of the model being displayed
	 * by this provider. The runnable should be executed in a thread-safe manner
	 * which results in the view being updated.
	 * @param runnable the runnable which updates the model.
	 * @param preserveExpansion whether the expansion of the view should be preserver
	 * @param runInUIThread
	 */
	public void performUpdate(IWorkspaceRunnable runnable, boolean preserveExpansion, boolean runInUIThread) {
		updateHandler.performUpdate(runnable, preserveExpansion, runInUIThread);
	}
}
