/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ui;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.mapping.ModelProvider;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.resources.mapping.ResourceMappingContext;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.diff.IThreeWayDiff;
import org.eclipse.team.core.history.IFileHistoryProvider;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.core.mapping.IResourceDiff;
import org.eclipse.team.core.mapping.ISynchronizationScope;
import org.eclipse.team.core.synchronize.FastSyncInfoFilter;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.variants.IResourceVariant;
import org.eclipse.team.internal.core.mapping.CompoundResourceTraversal;
import org.eclipse.team.internal.ui.history.FileRevisionEditorInput;
import org.eclipse.team.internal.ui.synchronize.SyncInfoModelElement;
import org.eclipse.team.ui.TeamImages;
import org.eclipse.team.ui.TeamUI;
import org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter;
import org.eclipse.team.ui.synchronize.ISynchronizeManager;
import org.eclipse.team.ui.synchronize.ISynchronizeModelElement;
import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
import org.eclipse.team.ui.synchronize.ISynchronizeParticipant;
import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput;
import org.eclipse.ui.IContributorResourceAdapter;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IContributorResourceAdapter2;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.internal.ErrorEditorPart;
import org.eclipse.ui.internal.registry.EditorDescriptor;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
import org.osgi.framework.Bundle;

public class Utils {

	/**
	 * Constant used to indicate that tests are being run. This field
	 * should be the same as the corresponding field on
	 * org.eclipse.compare.internal.Utilities
	 */
	public static boolean RUNNING_TESTS = false;

	/**
	 * Constant used while testing the indicate that changes should be flushed
	 * when the compare input changes and a viewer is dirty. This field
	 * should be the same as the corresponding field on
	 * org.eclipse.compare.internal.Utilities
	 */
	public static boolean TESTING_FLUSH_ON_COMPARE_INPUT_CHANGE = false;

	/**
	 * The SortOperation takes a collection of objects and returns a sorted
	 * collection of these objects. Concrete instances of this class provide
	 * the criteria for the sorting of the objects based on the type of the
	 * objects.
	 */
	static public abstract class Sorter {

		/**
		 * Returns true is elementTwo is 'greater than' elementOne This is the
		 * 'ordering' method of the sort operation. Each subclass overrides this
		 * method with the particular implementation of the 'greater than'
		 * concept for the objects being sorted.
		 * @param elementOne element 1
		 * @param elementTwo element 2
		 * @return whether element 2 is greater that element 1
		 */
		public abstract boolean compare(Object elementOne, Object elementTwo);

		/**
		 * Sort the objects in sorted collection and return that collection.
		 */
		private Object[] quickSort(Object[] sortedCollection, int left, int right) {
			int originalLeft = left;
			int originalRight = right;
			Object mid = sortedCollection[(left + right) >>> 1];
			do {
				while (compare(sortedCollection[left], mid))
					left++;
				while (compare(mid, sortedCollection[right]))
					right--;
				if (left <= right) {
					Object tmp = sortedCollection[left];
					sortedCollection[left] = sortedCollection[right];
					sortedCollection[right] = tmp;
					left++;
					right--;
				}
			} while (left <= right);
			if (originalLeft < right)
				sortedCollection = quickSort(sortedCollection, originalLeft, right);
			if (left < originalRight)
				sortedCollection = quickSort(sortedCollection, left, originalRight);
			return sortedCollection;
		}

		/**
		 * Return a new sorted collection from this unsorted collection. Sort
		 * using quick sort.
		 * @param unSortedCollection the original collection
		 * @return the sorted collection
		 */
		public Object[] sort(Object[] unSortedCollection) {
			int size = unSortedCollection.length;
			Object[] sortedCollection = new Object[size];
			//copy the array so can return a new sorted collection
			System.arraycopy(unSortedCollection, 0, sortedCollection, 0, size);
			if (size > 1)
				quickSort(sortedCollection, 0, size - 1);
			return sortedCollection;
		}
	}

	public static final Comparator<IResource> resourceComparator = new Comparator<IResource>() {
		@Override
		public boolean equals(Object obj) {
			return false;
		}
		@Override
		public int compare(IResource o1, IResource o2) {
				return o1.getFullPath().toString().compareTo(o2.getFullPath().toString());
		}
	};

	/**
	 * Shows the given errors to the user.
	 * @param shell
	 *            the shell to open the error dialog in
	 * @param exception
	 *            the exception containing the error
	 * @param title
	 *            the title of the error dialog
	 * @param message
	 *            the message for the error dialog
	 */
	public static void handleError(Shell shell, Exception exception, String title, String message) {
		IStatus status = null;
		boolean log = false;
		boolean dialog = false;
		Throwable t = exception;
		if (exception instanceof TeamException) {
			status = ((TeamException) exception).getStatus();
			log = false;
			dialog = true;
		} else if (exception instanceof InvocationTargetException) {
			t = ((InvocationTargetException) exception).getTargetException();
			if (t instanceof TeamException) {
				status = ((TeamException) t).getStatus();
				log = false;
				dialog = true;
			} else if (t instanceof CoreException) {
				status = ((CoreException) t).getStatus();
				log = true;
				dialog = true;
			} else if (t instanceof InterruptedException) {
				return;
			} else {
				status = new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, TeamUIMessages.TeamAction_internal, t);
				log = true;
				dialog = true;
			}
		}
		if (status == null)
			return;
		if (!status.isOK()) {
			IStatus toShow = status;
			if (status.isMultiStatus()) {
				IStatus[] children = status.getChildren();
				if (children.length == 1) {
					toShow = children[0];
				}
			}
			if (title == null) {
				title = status.getMessage();
			}
			if (message == null) {
				message = status.getMessage();
			}
			if (dialog && shell != null) {
				ErrorDialog.openError(shell, title, message, toShow);
			}
			if (log || shell == null) {
				TeamUIPlugin.log(toShow.getSeverity(), message, t);
			}
		}
	}

	public static void runWithProgress(Shell parent, boolean cancelable, final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
		boolean createdShell = false;
		try {
			if (parent == null || parent.isDisposed()) {
				Display display = Display.getCurrent();
				if (display == null) {
					// cannot provide progress (not in UI thread)
					runnable.run(new NullProgressMonitor());
					return;
				}
				// get the active shell or a suitable top-level shell
				parent = display.getActiveShell();
				if (parent == null) {
					parent = new Shell(display);
					createdShell = true;
				}
			}
			// pop up progress dialog after a short delay
			final Exception[] holder = new Exception[1];
			BusyIndicator.showWhile(parent.getDisplay(), () -> {
				try {
					runnable.run(new NullProgressMonitor());
				} catch (InvocationTargetException e1) {
					holder[0] = e1;
				} catch (InterruptedException e2) {
					holder[0] = e2;
				}
			});
			if (holder[0] != null) {
				if (holder[0] instanceof InvocationTargetException) {
					throw (InvocationTargetException) holder[0];
				} else {
					throw (InterruptedException) holder[0];
				}
			}
			//new TimeoutProgressMonitorDialog(parent, TIMEOUT).run(true
			// /*fork*/, cancelable, runnable);
		} finally {
			if (createdShell)
				parent.dispose();
		}
	}

	public static Shell getShell(IWorkbenchSite site) {
		return getShell(site, false);
	}

	public static Shell getShell(IWorkbenchSite site, boolean syncIfNecessary) {
		if(site != null) {
			Shell shell = site.getShell();
			if (!shell.isDisposed())
				return shell;
		}
		IWorkbench workbench = TeamUIPlugin.getPlugin().getWorkbench();
		if (workbench != null) {
			IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
			if (window != null) {
				return window.getShell();
			}
		}
		// Fallback to using the display
		Display display = Display.getCurrent();
		if (display == null) {
			display = Display.getDefault();
			if (display.isDisposed()) return null;
			if (syncIfNecessary) {
				final Shell[] result = new Shell[] { null };
				Runnable r = () -> result[0] = new Shell(Display.getDefault());
				display.syncExec(r);
				return result[0];
			}
		}
		if (display.isDisposed()) return null;
		return new Shell(display);
	}
	/*
	 * This method is only for use by the Target Management feature (see bug
	 * 16509). @param t
	 */
	public static void handle(final Throwable exception) {
		TeamUIPlugin.getStandardDisplay().asyncExec(() -> {
			IStatus error = null;
			Throwable t = exception;
			if (t instanceof InvocationTargetException) {
				t = ((InvocationTargetException) t).getTargetException();
			}
			if (t instanceof CoreException) {
				error = ((CoreException) t).getStatus();
			} else if (t instanceof TeamException) {
				error = ((TeamException) t).getStatus();
			} else {
				error = new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, TeamUIMessages.simpleInternal, t);
			}
			Shell shell = new Shell(Display.getDefault());
			if (error.getSeverity() == IStatus.INFO) {
				MessageDialog.openInformation(shell, TeamUIMessages.information, error.getMessage());
			} else {
				ErrorDialog.openError(shell, TeamUIMessages.exception, null, error);
			}
			shell.dispose();
			// Let's log non-team exceptions
			if (!(t instanceof TeamException)) {
				TeamUIPlugin.log(error.getSeverity(), error.getMessage(), t);
			}
		});
	}

	public static Shell findShell() {
		Display display = TeamUIPlugin.getStandardDisplay();
		Shell activeShell = display.getActiveShell();
		if (activeShell != null)
			return activeShell;
		// worst case, just create our own.
		return new Shell(display);
	}

	public static void initAction(IAction a, String prefix) {
		Utils.initAction(a, prefix, Policy.getActionBundle());
	}

	public static void initAction(IAction a, String prefix, ResourceBundle bundle) {
		Utils.initAction(a, prefix, bundle, null);
	}

	public static void updateLabels(SyncInfo sync, CompareConfiguration config, IProgressMonitor monitor) {
		final IResourceVariant remote = sync.getRemote();
		final IResourceVariant base = sync.getBase();
		String baseAuthor = null;
		String remoteAuthor = null;
		String localAuthor = null;
		String localContentId = sync.getLocalContentIdentifier();
		String remoteContentId= remote != null ? remote.getContentIdentifier() : null;
		String baseContentId= base != null ? base.getContentIdentifier() : null;
		if (isShowAuthor()) {
			baseAuthor = getAuthor(base, monitor);
			if (baseContentId != null && baseContentId.equals(remoteContentId))
				remoteAuthor= baseAuthor;
			else
				remoteAuthor= getAuthor(remote, monitor);

			if (localContentId != null) {
				if (localContentId.equals(baseContentId))
					localAuthor= baseAuthor;
				else if (localContentId.equals(remoteAuthor))
					localAuthor= remoteAuthor;
				else
					localAuthor= sync.getLocalAuthor(monitor);
			}
		}
		if (localContentId != null) {
			if (localAuthor != null) {
				config.setLeftLabel(NLS.bind(TeamUIMessages.SyncInfoCompareInput_localLabelAuthorExists, new String[] { localContentId, localAuthor }));
			} else {
				config.setLeftLabel(NLS.bind(TeamUIMessages.SyncInfoCompareInput_localLabelExists, new String[] { localContentId }));
			}
		} else {
			config.setLeftLabel(TeamUIMessages.SyncInfoCompareInput_localLabel);
		}
		if (remote != null) {
			if (remoteAuthor != null) {
				config.setRightLabel(NLS.bind(TeamUIMessages.SyncInfoCompareInput_remoteLabelAuthorExists, new String[] { remoteContentId, remoteAuthor }));
			} else {
				config.setRightLabel(NLS.bind(TeamUIMessages.SyncInfoCompareInput_remoteLabelExists, new String[] { remoteContentId }));
			}
		} else {
			config.setRightLabel(TeamUIMessages.SyncInfoCompareInput_remoteLabel);
		}
		if (base != null) {
			if (baseAuthor != null) {
				config.setAncestorLabel(NLS.bind(TeamUIMessages.SyncInfoCompareInput_baseLabelAuthorExists, new String[] { baseContentId, baseAuthor }));
			} else {
				config.setAncestorLabel(NLS.bind(TeamUIMessages.SyncInfoCompareInput_baseLabelExists, new String[] { baseContentId }));
			}
		} else {
			config.setAncestorLabel(TeamUIMessages.SyncInfoCompareInput_baseLabel);
		}
	}

	/**
	 * DO NOT REMOVE, used in a product.
	 *
	 * @deprecated As of 3.5, replaced by
	 *             {@link #updateLabels(SyncInfo, CompareConfiguration, IProgressMonitor)}
	 */
	@SuppressWarnings("javadoc")
	@Deprecated
	public static void updateLabels(SyncInfo sync, CompareConfiguration config) {
		updateLabels(sync, config, null);
	}

	public static boolean isShowAuthor() {
		IPreferenceStore store = TeamUIPlugin.getPlugin().getPreferenceStore();
		return store.getBoolean(IPreferenceIds.SHOW_AUTHOR_IN_COMPARE_EDITOR);
	}

	private static String getAuthor(IResourceVariant variant,
			IProgressMonitor monitor) {
		String author = null;
		if (variant instanceof IAdaptable) {
			IAdaptable adaptable = (IAdaptable) variant;
			IFileRevision revision = adaptable.getAdapter(IFileRevision.class);
			if (revision == null)
				return null;
			try {
				IFileRevision complete = revision.withAllProperties(monitor);
				if (complete != null) {
					author = complete.getAuthor();
				}
			} catch (CoreException e) {
				TeamUIPlugin.log(e);
			}
		}
		return author;
	}

	public static String getLocalContentId(IDiff diff) {
		if (diff instanceof IThreeWayDiff) {
			IThreeWayDiff twd = (IThreeWayDiff) diff;
			diff = twd.getLocalChange();
			if (diff == null)
				diff = twd.getRemoteChange();
		}
		if (diff instanceof IResourceDiff) {
			IResourceDiff rd = (IResourceDiff) diff;
			IResource resource = rd.getResource();
			IFileHistoryProvider provider = getHistoryProvider(resource);
			if (provider != null) {
				IFileRevision revision = provider.getWorkspaceFileRevision(resource);
				if (revision != null)
					return revision.getContentIdentifier();
			}
		}
		return null;
	}

	public static IFileHistoryProvider getHistoryProvider(IResource resource) {
		RepositoryProvider rp = RepositoryProvider.getProvider(resource.getProject());
		if (rp != null)
			return rp.getFileHistoryProvider();
		return null;
	}

	public static IFileRevision getBase(IDiff diff) {
		if (diff instanceof IThreeWayDiff) {
			IThreeWayDiff twd = (IThreeWayDiff) diff;
			IDiff remoteChange = twd.getRemoteChange();
			if (remoteChange instanceof IResourceDiff) {
				IResourceDiff rd = (IResourceDiff) remoteChange;
				return rd.getBeforeState();
			}
			IDiff localChange = twd.getLocalChange();
			if (localChange instanceof IResourceDiff) {
				IResourceDiff ld = (IResourceDiff) localChange;
				return ld.getBeforeState();
			}
		}
		return null;
	}

	public static IFileRevision getRemote(IDiff diff) {
		if (diff instanceof IResourceDiff) {
			IResourceDiff rd = (IResourceDiff) diff;
			return rd.getAfterState();
		}
		if (diff instanceof IThreeWayDiff) {
			IThreeWayDiff twd = (IThreeWayDiff) diff;
			IDiff remoteChange = twd.getRemoteChange();
			if (remoteChange instanceof IResourceDiff) {
				IResourceDiff rd = (IResourceDiff) remoteChange;
				return rd.getAfterState();
			}
			IDiff localChange = twd.getLocalChange();
			if (localChange instanceof IResourceDiff) {
				IResourceDiff ld = (IResourceDiff) localChange;
				return ld.getBeforeState();
			}
		}
		return null;
	}

	/**
	 * Initialize the given Action from a ResourceBundle.
	 * @param a the action
	 * @param prefix the bundle key prefix
	 * @param bundle the bundle
	 * @param bindings additional input to the action label
	 */
	public static void initAction(IAction a, String prefix, ResourceBundle bundle, String[] bindings) {
		String labelKey = "label"; //$NON-NLS-1$
		String tooltipKey = "tooltip"; //$NON-NLS-1$
		String imageKey = "image"; //$NON-NLS-1$
		String descriptionKey = "description"; //$NON-NLS-1$
		if (prefix != null && prefix.length() > 0) {
			labelKey = prefix + labelKey;
			tooltipKey = prefix + tooltipKey;
			imageKey = prefix + imageKey;
			descriptionKey = prefix + descriptionKey;
		}
		String s = null;
		if(bindings != null) {
			s = NLS.bind(getString(labelKey, bundle), bindings);
		} else {
			s = getString(labelKey, bundle);
		}
		if (s != null)
			a.setText(s);
		s = getString(tooltipKey, bundle);
		if (s != null)
			a.setToolTipText(s);
		s = getString(descriptionKey, bundle);
		if (s != null)
			a.setDescription(s);
		String relPath = getString(imageKey, bundle);
		if (relPath != null && !relPath.equals(imageKey) && relPath.trim().length() > 0) {
			String dPath;
			String ePath;
			if (relPath.indexOf("/") >= 0) { //$NON-NLS-1$
				String path = relPath.substring(1);
				dPath = 'd' + path;
				ePath = 'e' + path;
			} else {
				dPath = "dlcl16/" + relPath; //$NON-NLS-1$
				ePath = "elcl16/" + relPath; //$NON-NLS-1$
			}
			ImageDescriptor id = TeamImages.getImageDescriptor(dPath);
			if (id != null)
				a.setDisabledImageDescriptor(id);
			id = TeamUIPlugin.getImageDescriptor(ePath);
			if (id != null)
				a.setImageDescriptor(id);
		}
	}

	public static String getString(String key, ResourceBundle b) {
		try {
			return b.getString(key);
		} catch (MissingResourceException e) {
			return key;
		} catch (NullPointerException e) {
			return "!" + key + "!"; //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	public static String modeToString(int mode) {
		switch (mode) {
		case ISynchronizePageConfiguration.INCOMING_MODE :
			return TeamUIMessages.Utils_22;
		case ISynchronizePageConfiguration.OUTGOING_MODE :
			return TeamUIMessages.Utils_23;
		case ISynchronizePageConfiguration.BOTH_MODE :
			return TeamUIMessages.Utils_24;
		case ISynchronizePageConfiguration.CONFLICTING_MODE :
			return TeamUIMessages.Utils_25;
		default:
			return TeamUIMessages.Utils_26;
		}
	}

	/**
	 * Returns the list of resources contained in the given elements.
	 * @param elements
	 * @return the list of resources contained in the given elements.
	 */
	private static IResource[] getResources(Object[] elements, List<Object> nonResources,
			boolean isContributed, boolean includeMappingResources) {
		List<IResource> resources = new ArrayList<>();
		for (int i = 0; i < elements.length; i++) {
			Object element = elements[i];
			boolean isResource = false;
			if (element instanceof IResource) {
				resources.add((IResource) element);
				isResource = true;
			} else if (element instanceof ISynchronizeModelElement){
				IResource resource = ((ISynchronizeModelElement) element).getResource();
				if (resource != null) {
					resources.add(resource);
					isResource = true;
				}
			} else if (element instanceof ResourceMapping) {
				if (includeMappingResources) {
					isResource = true;
					getResources((ResourceMapping)element, resources);
				}
			} else if (element != null) {
				Object adapted;
				if (isContributed) {
					adapted = getResource(element);
				} else {
					adapted = Adapters.adapt(element, IResource.class);
				}
				if (adapted instanceof IResource) {
					IResource resource = (IResource) adapted;
					isResource = true;
					if (resource.getType() != IResource.ROOT) {
						resources.add(resource);
					}
				} else {
					if (isContributed) {
						adapted = getResourceMapping(element);
					} else {
						adapted = Adapters.adapt(element, ResourceMapping.class);
					}
					if (adapted instanceof ResourceMapping && includeMappingResources) {
						isResource = true;
						getResources((ResourceMapping) adapted, resources);
					}
				}
			}
			if (!isResource) {
				if (nonResources != null)
					nonResources.add(element);
			}
		}
		return resources.toArray(new IResource[resources.size()]);
	}

	private static void getResources(ResourceMapping element, List<IResource> resources) {
		try {
			ResourceTraversal[] traversals = element.getTraversals(ResourceMappingContext.LOCAL_CONTEXT, null);
			for (int k = 0; k < traversals.length; k++) {
				ResourceTraversal traversal = traversals[k];
				IResource[] resourceArray = traversal.getResources();
				for (int j = 0; j < resourceArray.length; j++) {
					IResource resource = resourceArray[j];
					resources.add(resource);
				}
			}
		} catch (CoreException e) {
			TeamUIPlugin.log(new Status(IStatus.ERROR, TeamUIPlugin.ID, 0, "Error traversing resource mapping", e)); //$NON-NLS-1$
		}
	}

	public static Object[] getNonResources(Object[] elements) {
		List<Object> nonResources = new ArrayList<>();
		getResources(elements, nonResources, false, false);
		return nonResources.toArray();
	}

	public static IResource[] getResources(Object[] element) {
		return getResources(element, null, false /* isContributed */, false /* includeMappingResources */);
	}

	public static IResource[] getContributedResources(Object[] elements) {
		return getResources(elements, null, true /* isContributed */, true /* isIncudeMappings */);
	}

	/**
	 * Return whether any sync nodes in the given selection or their
	 * descendants match the given filter.
	 * @param selection a selection
	 * @param filter a sync info filter
	 * @return whether any sync nodes in the given selection or their
	 * descendants match the given filter
	 */
	public static boolean hasMatchingDescendant(IStructuredSelection selection, FastSyncInfoFilter filter) {
		for (Iterator iter = selection.iterator(); iter.hasNext();) {
			Object o = iter.next();
			if (o instanceof ISynchronizeModelElement) {
				if (hasMatchingDescendant((ISynchronizeModelElement)o, filter)) {
					return true;
				}
			}
		}
		return false;
	}

	private static boolean hasMatchingDescendant(ISynchronizeModelElement element, FastSyncInfoFilter filter) {
		if (element.getKind() != SyncInfo.IN_SYNC && element instanceof SyncInfoModelElement) {
			SyncInfo info = ((SyncInfoModelElement) element).getSyncInfo();
			if (info != null && filter.select(info)) {
				return true;
			}
		}
		IDiffElement[] children = element.getChildren();
		for (int i = 0; i < children.length; i++) {
			IDiffElement child = children[i];
			if (child instanceof ISynchronizeModelElement) {
				if (hasMatchingDescendant((ISynchronizeModelElement)child, filter)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * This method returns all out-of-sync SyncInfos that are in the current
	 * selection.
	 * @param selected the selected objects
	 *
	 * @return the list of selected sync infos
	 */
	public static IDiffElement[] getDiffNodes(Object[] selected) {
		Set<IDiffElement> result = new HashSet<>();
		for (int i = 0; i < selected.length; i++) {
			Object object = selected[i];
			if(object instanceof IDiffElement) {
				collectAllNodes((IDiffElement)object, result);
			}
		}
		return result.toArray(new IDiffElement[result.size()]);
	}

	private static void collectAllNodes(IDiffElement element, Set<IDiffElement> nodes) {
		if (element.getKind() != SyncInfo.IN_SYNC) {
			nodes.add(element);
		}
		if(element instanceof IDiffContainer) {
			IDiffElement[] children = ((IDiffContainer)element).getChildren();
			for (int i = 0; i < children.length; i++) {
				collectAllNodes(children[i], nodes);
			}
		}
	}

	public static void schedule(Job job, IWorkbenchSite site) {
		if (site != null) {
			IWorkbenchSiteProgressService siteProgress = site.getAdapter(IWorkbenchSiteProgressService.class);
			if (siteProgress != null) {
				siteProgress.schedule(job, 0, true /* use half-busy cursor */);
				return;
			}
		}
		job.schedule();
	}

	public static byte[] readBytes(InputStream in) {
		ByteArrayOutputStream bos= new ByteArrayOutputStream();
		try {
			while (true) {
				int c= in.read();
				if (c == -1)
					break;
				bos.write(c);
			}

		} catch (IOException ex) {
			return null;

		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException x) {
					// silently ignored
				}
			}
			try {
				bos.close();
			} catch (IOException x) {
				// silently ignored
			}
		}
		return bos.toByteArray();
	}

	public static boolean equalObject(Object o1, Object o2) {
		if (o1 == null && o2 == null) return true;
		if (o1 == null || o2 == null) return false;
		return o1.equals(o2);
	}

	public static String getKey(String id, String secondaryId) {
		return secondaryId == null ? id : id + '/' + secondaryId;
	}

	public static String convertSelection(IResource[] resources) {
		StringBuilder  buffer = new StringBuilder();
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			if(i > 0) buffer.append(", "); //$NON-NLS-1$
			buffer.append(resource.getFullPath());
		}
		return buffer.toString();
	}

	/**
	 * Shorten the given text <code>t</code> so that its length
	 * doesn't exceed the given width. This implementation
	 * replaces characters in the center of the original string with an
	 * ellipsis ("...").
	 * @param maxWidth the maximum length for the text
	 * @param textValue the text to be shortened
	 * @return the shortened text
	 */
	public static String shortenText(int maxWidth, String textValue) {
		int length = textValue.length();
		if (length < maxWidth)
			return textValue;
		String ellipsis = "..."; //$NON-NLS-1$
		int subStrLen = (maxWidth - ellipsis.length()) / 2;
		int addtl = (maxWidth - ellipsis.length()) % 2;

		StringBuilder sb = new StringBuilder();
		sb.append(textValue.substring(0, subStrLen));
		sb.append(ellipsis);
		sb.append(textValue.substring(length - subStrLen - addtl));
		return sb.toString();
	}

	public static String getTypeName(ISynchronizeParticipant participant) {
		ISynchronizeManager manager = TeamUI.getSynchronizeManager();
		return manager.getParticipantDescriptor(participant.getId()).getName();
	}

	/**
	 * The viewer will only be updated if the viewer is not null, the control is not disposed, and
	 * this code is being run from the UI thread.
	 * @param viewer the viewer to be updated
	 * @return whether it is safe to update the viewer
	 */
	public static boolean canUpdateViewer(StructuredViewer viewer) {
		if(viewer == null || viewer.getControl().isDisposed()) return false;
		Display display = viewer.getControl().getDisplay();
		if (display == null) return false;
		if (display.getThread() != Thread.currentThread ()) return false;
		return true;
	}

	public static void asyncExec(final Runnable r, StructuredViewer v) {
		if(v == null) return;
		final Control ctrl = v.getControl();
		if (ctrl != null && !ctrl.isDisposed()) {
			ctrl.getDisplay().asyncExec(() -> {
				if (!ctrl.isDisposed()) {
					BusyIndicator.showWhile(ctrl.getDisplay(), r);
				}
			});
		}
	}

	public static void syncExec(final Runnable r, StructuredViewer v) {
		if(v == null) return;
		final Control ctrl = v.getControl();
		syncExec(r, ctrl);
	}

	public static void syncExec(final Runnable r, final Control ctrl) {
		if (ctrl != null && !ctrl.isDisposed()) {
			ctrl.getDisplay().syncExec(() -> {
				if (!ctrl.isDisposed()) {
					BusyIndicator.showWhile(ctrl.getDisplay(), r);
				}
			});
		}
	}

	public static void asyncExec(final Runnable r, final Control ctrl) {
		if (ctrl != null && !ctrl.isDisposed()) {
			ctrl.getDisplay().asyncExec(() -> {
				if (!ctrl.isDisposed()) {
					BusyIndicator.showWhile(ctrl.getDisplay(), r);
				}
			});
		}
	}

	public static SyncInfo getSyncInfo(ISynchronizeModelElement node) {
		if (node instanceof IAdaptable) {
			return ((IAdaptable) node).getAdapter(SyncInfo.class);
		}
		return null;
	}

	public static ISynchronizationCompareAdapter getCompareAdapter(Object element) {
		ModelProvider provider = getModelProvider(element);
		if (provider != null) {
			Object o = provider.getAdapter(ISynchronizationCompareAdapter.class);
			if (o instanceof ISynchronizationCompareAdapter) {
				return (ISynchronizationCompareAdapter) o;
			}
		}
		return null;
	}

	public static ModelProvider getModelProvider(Object o) {
		if (o instanceof ModelProvider) {
			return (ModelProvider) o;
		}
		ResourceMapping mapping = getResourceMapping(o);
		if (mapping != null)
			return mapping.getModelProvider();
		return null;
	}

	public static IResource getResource(Object o) {
		IResource resource = null;
		if (o instanceof IResource) {
			resource = (IResource) o;
		} else if (o instanceof IAdaptable) {
			IAdaptable adaptable = (IAdaptable) o;
			resource = adaptable.getAdapter(IResource.class);
			if (resource == null) {
				IContributorResourceAdapter adapter = adaptable.getAdapter(IContributorResourceAdapter.class);
				if (adapter != null)
					resource = adapter.getAdaptedResource(adaptable);
			}
		}
		return resource;
	}


	public static ResourceMapping getResourceMapping(Object o) {
		if (o instanceof ResourceMapping) {
			return (ResourceMapping) o;
		}
		if (o instanceof IAdaptable) {
			IAdaptable adaptable = (IAdaptable) o;
			Object adapted = adaptable.getAdapter(ResourceMapping.class);
			if (adapted instanceof ResourceMapping) {
				return(ResourceMapping) adapted;
			}
			adapted = adaptable.getAdapter(IContributorResourceAdapter.class);
			if (adapted instanceof IContributorResourceAdapter2) {
				IContributorResourceAdapter2 cra = (IContributorResourceAdapter2) adapted;
				return cra.getAdaptedResourceMapping(adaptable);
			}
		} else {
			Object adapted = Platform.getAdapterManager().getAdapter(o, ResourceMapping.class);
			if (adapted instanceof ResourceMapping) {
				return(ResourceMapping) adapted;
			}
		}
		return null;
	}

	public static ResourceMapping[] getResourceMappings(Object[] objects) {
		List<ResourceMapping> result = new ArrayList<>();
		for (int i = 0; i < objects.length; i++) {
			Object object = objects[i];
			ResourceMapping mapping = getResourceMapping(object);
			if (mapping != null)
				result.add(mapping);
		}
		return result.toArray(new ResourceMapping[result.size()]);
	}

	public static String getLabel(ResourceMapping mapping) {
		ModelProvider provider = mapping.getModelProvider();
		ISynchronizationCompareAdapter adapter = getCompareAdapter(provider);
		if (adapter == null)
			return ""; //$NON-NLS-1$
		String pathString = adapter.getPathString(mapping);
		if (pathString == null || pathString.length() == 0)
			return adapter.getName(mapping);
		return pathString;
	}

	public static String getLabel(ModelProvider provider) {
		ResourceMapping mapping = Utils.getResourceMapping(provider);
		if (mapping != null) {
			String base = Utils.getLabel(mapping);
			if (base != null && base.length() > 0)
				return base;
		}
		return provider.getDescriptor().getLabel();
	}

	public static String getScopeDescription(ISynchronizationScope scope) {
		ResourceMapping[] mappings = scope.getInputMappings();
		if (mappings.length == 1) {
			String label = getLabel(mappings[0]);
			if (label == null)
				return TeamUIMessages.Utils_19;
			else
				return label;
		}
		String desc = convertSelection(mappings);
		if (desc.length() > 0)
			return shortenText(30, desc);
		return NLS.bind(TeamUIMessages.Utils_18, Integer.valueOf(mappings.length));
	}

	public static String convertSelection(ResourceMapping[] mappings) {
		StringBuilder  buffer = new StringBuilder();
		boolean hadOne = false;
		for (int i = 0; i < mappings.length; i++) {
			ResourceMapping resourceMapping = mappings[i];
			String label = getLabel(resourceMapping);
			if (label != null) {
				if(hadOne) buffer.append(", "); //$NON-NLS-1$
				hadOne = true;
				buffer.append(label);
			}
		}
		return buffer.toString();
	}

	public static ResourceTraversal[] getTraversals(Object[] elements) throws CoreException {
		CompoundResourceTraversal traversal = new CompoundResourceTraversal();
		for (int i = 0; i < elements.length; i++) {
			Object object = elements[i];
			ResourceMapping mapping = getResourceMapping(object);
			if (mapping != null) {
				traversal.addTraversals(mapping.getTraversals(ResourceMappingContext.LOCAL_CONTEXT, null));
			}
		}
		return traversal.asTraversals();
	}

	/**
	 * Return whether the editor associated with a descriptor is a text editor
	 * (i.e. an instance of AbstractDecoratedTextEditor).
	 * See bug 99568 for a request to move the createEditor method to IEditorDescriptor.
	 * @param descriptor
	 * @return whether the editor associated with a descriptor is a text editor
	 * @throws CoreException
	 */
	public static boolean isTextEditor(IEditorDescriptor descriptor) throws CoreException {
		if (!(descriptor instanceof EditorDescriptor))
			return false;

		EditorDescriptor desc = (EditorDescriptor) descriptor;
		String className = desc.getClassName();
		String contributor = desc.getPluginId();

		if (className == null || contributor == null)
			return false;

		try {
			Bundle bundle= Platform.getBundle(contributor);
			if (bundle != null) {
				Class clazz= bundle.loadClass(className);
				return AbstractDecoratedTextEditor.class.isAssignableFrom(clazz);
			}
		} catch (ClassNotFoundException e) {
			// fallback and create editor
		}

		IEditorPart editor= desc.createEditor();
		editor.dispose();
		return editor instanceof AbstractDecoratedTextEditor;
	}

	public static IEditorPart openEditor(IWorkbenchPage page, IFileRevision revision, IProgressMonitor monitor) throws CoreException {
		IStorage file = revision.getStorage(monitor);
		if (file instanceof IFile) {
			//if this is the current workspace file, open it
			return IDE.openEditor(page, (IFile)file, OpenStrategy.activateOnOpen());
		} else {
			FileRevisionEditorInput fileRevEditorInput = FileRevisionEditorInput.createEditorInputFor(revision, monitor);
			IEditorPart	part = openEditor(page, fileRevEditorInput);
			return part;
		}
	}

	public static IEditorPart openEditor(IWorkbenchPage page,
			FileRevisionEditorInput editorInput) throws PartInitException {
		String id = getEditorId(editorInput);
		return openEditor(page, editorInput, id);
	}

	public static IEditorPart openEditor(IWorkbenchPage page,
			FileRevisionEditorInput editorInput, String editorId)
			throws PartInitException {
		try {
			IEditorPart part = page.openEditor(editorInput, editorId,
					OpenStrategy.activateOnOpen());
			// See bug 90582 for the reasons behind this discouraged access
			if (part instanceof ErrorEditorPart) {
				page.closeEditor(part, false);
				part = null;
			}
			if (part == null) {
				throw new PartInitException(NLS.bind(TeamUIMessages.Utils_17,
						editorId));
			}
			return part;
		} catch (PartInitException e) {
			if (editorId.equals("org.eclipse.ui.DefaultTextEditor")) { //$NON-NLS-1$
				throw e;
			} else {
				return page.openEditor(editorInput,
						"org.eclipse.ui.DefaultTextEditor"); //$NON-NLS-1$
			}
		}
	}

	public static IEditorDescriptor[] getEditors(IFileRevision revision) {
		String name= revision.getName();
		IEditorRegistry registry = PlatformUI.getWorkbench()
				.getEditorRegistry();
		// so far only the revision name is used to find editors
		IEditorDescriptor[] editorDescs= registry.getEditors(name/* , getContentType(revision) */);
		return IDE.overrideEditorAssociations(name, null, editorDescs);
	}

	public static IEditorDescriptor getDefaultEditor(IFileRevision revision) {
		String name= revision.getName();
		// so far only the revision name is used to find the default editor
		try {
			return IDE.getEditorDescriptor(name);
		} catch (PartInitException e) {
			// Fallback to old way of getting the editor
			IEditorRegistry registry= PlatformUI.getWorkbench().getEditorRegistry();
			return registry.getDefaultEditor(name);
		}
	}

	private static String getEditorId(FileRevisionEditorInput editorInput) {
		String id= getEditorId(editorInput, getContentType(editorInput));
		return id;
	}

	private static IContentType getContentType(FileRevisionEditorInput editorInput) {
		IContentType type = null;
		try {
			InputStream contents = editorInput.getStorage().getContents();
			try {
				type = getContentType(editorInput.getFileRevision().getName(), contents);
			} finally {
				try {
					contents.close();
				} catch (IOException e) {
					// ignore
				}
			}
		} catch (CoreException e) {
			TeamUIPlugin.log(IStatus.ERROR, NLS.bind("An error occurred reading the contents of file {0}", new String[] { editorInput.getName() }), e); //$NON-NLS-1$
		}
		return type;
	}

	private static IContentType getContentType(String fileName, InputStream contents) {
		IContentType type = null;
		if (contents != null) {
			try {
				type = Platform.getContentTypeManager().findContentTypeFor(contents, fileName);
			} catch (IOException e) {
				TeamUIPlugin.log(IStatus.ERROR, NLS.bind("An error occurred reading the contents of file {0}", fileName), e); //$NON-NLS-1$
			}
		}
		if (type == null) {
			type = Platform.getContentTypeManager().findContentTypeFor(fileName);
		}
		return type;
	}

	private static String getEditorId(FileRevisionEditorInput editorInput, IContentType type) {
		String fileName= editorInput.getFileRevision().getName();
		IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
		IEditorDescriptor descriptor = registry.getDefaultEditor(fileName, type);
		IDE.overrideDefaultEditorAssociation(editorInput, type, descriptor);
		String id;
		if (descriptor == null || descriptor.isOpenExternal()) {
			id = "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$
		} else {
			id = descriptor.getId();
		}
		return id;
	}

	/**
	 * Returns an editor that can be re-used. An open compare editor that has
	 * un-saved changes cannot be re-used.
	 *
	 * @param input
	 *            the input being opened
	 * @param page
	 * @param editorInputClasses
	 * @return an EditorPart or <code>null</code> if none can be found
	 */
	public static IEditorPart findReusableCompareEditor(
			CompareEditorInput input, IWorkbenchPage page,
			Class[] editorInputClasses) {
		IEditorReference[] editorRefs = page.getEditorReferences();
		// first loop looking for an editor with the same input
		for (int i = 0; i < editorRefs.length; i++) {
			IEditorPart part = editorRefs[i].getEditor(false);
			if (part != null && part instanceof IReusableEditor) {
				for (int j = 0; j < editorInputClasses.length; j++) {
					// check if the editor input type
					// complies with the types given by the caller
					if (editorInputClasses[j].isInstance(part.getEditorInput())
							&& part.getEditorInput().equals(input))
						return part;
				}
			}
		}
		// if none found and "Reuse open compare editors" preference is on use
		// a non-dirty editor
		if (TeamUIPlugin.getPlugin().getPreferenceStore()
				.getBoolean(IPreferenceIds.REUSE_OPEN_COMPARE_EDITOR)) {
			for (int i = 0; i < editorRefs.length; i++) {
				IEditorPart part = editorRefs[i].getEditor(false);
				if (part != null
						&& (part.getEditorInput() instanceof SaveableCompareEditorInput)
						&& part instanceof IReusableEditor && !part.isDirty()) {
					return part;
				}
			}
		}

		// no re-usable editor found
		return null;
	}

}
