/*******************************************************************************
 * 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.core;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFileModificationValidator;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.resources.IProjectNatureDescriptor;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.team.FileModificationValidationContext;
import org.eclipse.core.resources.team.FileModificationValidator;
import org.eclipse.core.resources.team.IMoveDeleteHook;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.history.IFileHistoryProvider;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.internal.core.Messages;
import org.eclipse.team.internal.core.PessimisticResourceRuleFactory;
import org.eclipse.team.internal.core.RepositoryProviderManager;
import org.eclipse.team.internal.core.TeamHookDispatcher;
import org.eclipse.team.internal.core.TeamPlugin;

/**
 * A concrete subclass of <code>RepositoryProvider</code> is created for each
 * project that is associated with a repository provider. The lifecycle of these
 * instances is is similar to that of the platform's 'nature' mechanism.
 * <p>
 * To create a repository provider and have it registered with the platform, a
 * client must minimally:
 * </p>
 * <ol>
 * <li>extend <code>RepositoryProvider</code>
 * <li>define a repository extension in <code>plugin.xml</code>. Here is an
 * example extension point definition:
 *
 * <code>
 *	<br>&lt;extension point="org.eclipse.team.core.repository"&gt;
 *  <br>&nbsp;&lt;repository
 *  <br>&nbsp;&nbsp;class="org.eclipse.myprovider.MyRepositoryProvider"
 *  <br>&nbsp;&nbsp;id="org.eclipse.myprovider.myProviderID"&gt;
 *  <br>&nbsp;&lt;/repository&gt;
 *	<br>&lt;/extension&gt;
 *  </code>
 * </ol>
 * <p>
 * Once a repository provider is registered with Team, then you can associate a
 * repository provider with a project by invoking
 * <code>RepositoryProvider.map()</code>.
 * </p>
 * 
 * @see RepositoryProvider#map(IProject, String)
 *
 * @since 2.0
 */
public abstract class RepositoryProvider implements IProjectNature, IAdaptable {

	private final static String TEAM_SETID = "org.eclipse.team.repository-provider"; //$NON-NLS-1$

	private final static List<String> AllProviderTypeIds = initializeAllProviderTypes();

	// the project instance that this nature is assigned to
	private IProject project;

	// lock to ensure that map/unmap and getProvider support concurrency
	private static final ILock mappingLock = Job.getJobManager().newLock();

	// Session property used to identify projects that are not mapped
	private static final Object NOT_MAPPED = new Object();

	/**
	 * Instantiate a new RepositoryProvider with concrete class by given providerID
	 * and associate it with project.
	 *
	 * @param project the project to be mapped
	 * @param id the ID of the provider to be mapped to the project
	 * @throws TeamException if
	 * <ul>
	 * <li>There is no provider by that ID.</li>
	 * <li>The project is already associated with a repository provider and that provider
	 * prevented its unmapping.</li>
	 * </ul>
	 * @see RepositoryProvider#unmap(IProject)
	 */
	public static void map(IProject project, String id) throws TeamException {
		ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(project);
		try {
			// Obtain a scheduling rule on the project before obtaining the
			// mappingLock. This is required because a caller of getProvider
			// may hold a scheduling rule before getProvider is invoked but
			// getProvider itself does not (and can not) obtain a scheduling rule.
			// Thus, the locking order is always scheduling rule followed by
			// mappingLock.
			Job.getJobManager().beginRule(rule, null);
			try {
				mappingLock.acquire();
				RepositoryProvider existingProvider = null;

				if(project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY) != null)
					existingProvider = getProvider(project);	// get the real one, not the nature one

				//if we already have a provider, and its the same ID, we're ok
				//if the ID's differ, unmap the existing.
				if(existingProvider != null) {
					if(existingProvider.getID().equals(id))
						return;	//nothing to do
					else
						unmap(project);
				}

				// Create the provider as a session property before adding the persistent
				// property to ensure that the provider can be instantiated
				RepositoryProvider provider = mapNewProvider(project, id);

				//mark it with the persistent ID for filtering
				try {
					project.setPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY, id);
				} catch (CoreException outer) {
					// couldn't set the persistent property so clear the session property
					try {
						project.setSessionProperty(TeamPlugin.PROVIDER_PROP_KEY, null);
					} catch (CoreException inner) {
						// something is seriously wrong
						TeamPlugin.log(IStatus.ERROR, NLS.bind(Messages.RepositoryProvider_couldNotClearAfterError, new String[] { project.getName(), id }), inner);
					}
					throw outer;
				}

				provider.configure();

				//adding the nature would've caused project description delta, so trigger one
				project.touch(null);

				// Set the rule factory for the provider after the touch
				// so the touch does not fail due to incompatible modify rules
				TeamHookDispatcher.setProviderRuleFactory(project, provider.getRuleFactory());

				// Notify any listeners
				RepositoryProviderManager.getInstance().providerMapped(provider);
			} finally {
				mappingLock.release();
			}
		} catch (CoreException e) {
			throw TeamPlugin.wrapException(e);
		} finally {
			Job.getJobManager().endRule(rule);
		}
	}

	/*
	 * Instantiate the provider denoted by ID and store it in the session property.
	 * Return the new provider instance. If a TeamException is thrown, it is
	 * guaranteed that the session property will not be set.
	 *
	 * @param project
	 * @param id
	 * @return RepositoryProvider
	 * @throws TeamException we can't instantiate the provider, or if the set
	 * session property fails from core
	 */
	private static RepositoryProvider mapNewProvider(final IProject project, final String id) throws TeamException {
		final RepositoryProvider provider = newProvider(id); 	// instantiate via extension point

		if(provider == null)
			throw new TeamException(NLS.bind(Messages.RepositoryProvider_couldNotInstantiateProvider, new String[] { project.getName(), id }));

		// validate that either the provider supports linked resources or the project has no linked resources
		if (!provider.canHandleLinkedResourceURI()) {
			try {
				project.accept(proxy -> {
					if (proxy.isLinked()) {
						if (!provider.canHandleLinkedResources() ||
								proxy.requestFullPath().segmentCount() > 2 ||
								!EFS.SCHEME_FILE.equals(proxy.requestResource().getLocationURI().getScheme()))
							throw new TeamException(new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, NLS.bind(Messages.RepositoryProvider_linkedURIsExist, new String[] { project.getName(), id }), null));
					}
					return true;
				}, IResource.NONE);
			} catch (CoreException e) {
				if (e instanceof TeamException) {
					TeamException te = (TeamException) e;
					throw te;
				}
				throw new TeamException(e);
			}
		}
		if (!provider.canHandleLinkedResources()) {
			try {
				IResource[] members = project.members();
				for (int i = 0; i < members.length; i++) {
					IResource resource = members[i];
					if (resource.isLinked()) {
						throw new TeamException(new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, NLS.bind(Messages.RepositoryProvider_linkedResourcesExist, new String[] { project.getName(), id }), null));
					}
				}
			} catch (CoreException e) {
				throw TeamPlugin.wrapException(e);
			}
		}

		//store provider instance as session property
		try {
			project.setSessionProperty(TeamPlugin.PROVIDER_PROP_KEY, provider);
			provider.setProject(project);
		} catch (CoreException e) {
			throw TeamPlugin.wrapException(e);
		}
		return provider;
	}

	private static RepositoryProvider mapExistingProvider(IProject project, String id) throws TeamException {
		try {
			// Obtain the mapping lock before creating the instance so we can make sure
			// that a disconnect is not happening at the same time
			mappingLock.acquire();
			try {
				// Ensure that the persistent property is still set
				// (i.e. an unmap may have come in since we checked it last
				String currentId = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY);
				if (currentId == null) {
					// The provider has been unmapped
					return null;
				}
				if (!currentId.equals(id)) {
					// A provider has been disconnected and another connected
					// Since mapping creates the session property, we
					// can just return it
					return lookupProviderProp(project);
				}
			} catch (CoreException e) {
				throw TeamPlugin.wrapException(e);
			}
			return mapNewProvider(project, id);
		} finally {
			mappingLock.release();
		}
	}
	/**
	 * Disassociates project with the repository provider its currently mapped to.
	 * @param project
	 * @throws TeamException The project isn't associated with any repository provider.
	 */
	public static void unmap(IProject project) throws TeamException {
		ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(project);
		try{
			// See the map(IProject, String) method for a description of lock ordering
			Job.getJobManager().beginRule(rule, null);
			try {
				mappingLock.acquire();
				String id = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY);

				//If you tried to remove a non-existant nature it would fail, so we need to as well with the persistent prop
				if(id == null) {
					throw new TeamException(NLS.bind(Messages.RepositoryProvider_No_Provider_Registered, new String[] { project.getName() }));
				}

				//This will instantiate one if it didn't already exist,
				//which is ok since we need to call deconfigure() on it for proper lifecycle
				RepositoryProvider provider = getProvider(project);
				if (provider == null) {
					// There is a persistent property but the provider cannot be obtained.
					// The reason could be that the provider's plugin is no longer available.
					// Better log it just in case this is unexpected.
					TeamPlugin.log(IStatus.ERROR, NLS.bind(Messages.RepositoryProvider_couldNotInstantiateProvider, new String[] { project.getName(), id }), null);
				}

				if (provider != null) provider.deconfigure();

				project.setSessionProperty(TeamPlugin.PROVIDER_PROP_KEY, null);
				project.setPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY, null);

				if (provider != null) provider.deconfigured();

				//removing the nature would've caused project description delta, so trigger one
				project.touch(null);

				// Change the rule factory after the touch in order to
				// avoid rule incompatibility
				TeamHookDispatcher.setProviderRuleFactory(project, null);

				// Notify any listeners
				RepositoryProviderManager.getInstance().providerUnmapped(project);
			} finally {
				mappingLock.release();
			}
		} catch (CoreException e) {
			throw TeamPlugin.wrapException(e);
		} finally {
			Job.getJobManager().endRule(rule);
		}
	}

	/*
	 * Return the provider mapped to project, or null if none;
	 */
	private static RepositoryProvider lookupProviderProp(IProject project) throws CoreException {
		Object provider = project.getSessionProperty(TeamPlugin.PROVIDER_PROP_KEY);
		if (provider instanceof RepositoryProvider) {
			return (RepositoryProvider) provider;
		}
		return null;
	}


	/**
	 * Default constructor required for the resources plugin to instantiate this class from
	 * the nature extension definition.
	 */
	public RepositoryProvider() {
	}

	/**
	 * Configures the provider for the given project. This method is called after <code>setProject</code>.
	 * If an exception is generated during configuration
	 * of the project, the provider will not be assigned to the project.
	 *
	 * @throws CoreException if the configuration fails.
	 */
	abstract public void configureProject() throws CoreException;

	/**
	 * Configures the nature for the given project. This is called by <code>RepositoryProvider.map()</code>
	 * the first time a provider is mapped to a project. It is not intended to be called by clients.
	 *
	 * @throws CoreException if this method fails. If the configuration fails the provider will not be
	 * associated with the project.
	 *
	 * @see RepositoryProvider#configureProject()
	 */
	@Override
	final public void configure() throws CoreException {
		try {
			configureProject();
		} catch(CoreException e) {
			try {
				RepositoryProvider.unmap(getProject());
			} catch(TeamException e2) {
				throw new CoreException(new Status(IStatus.ERROR, TeamPlugin.ID, 0, Messages.RepositoryProvider_Error_removing_nature_from_project___1 + getID(), e2));
			}
			throw e;
		}
	}

	/**
	 * Method deconfigured is invoked after a provider has been unmaped. The
	 * project will no longer have the provider associated with it when this
	 * method is invoked. It is a last chance for the provider to clean up.
	 */
	protected void deconfigured() {
	}

	/**
	 * Answer the id of this provider instance. The id should be the repository provider's
	 * id as defined in the provider plugin's plugin.xml.
	 *
	 * @return the nature id of this provider
	 */
	abstract public String getID();

	/**
	 * Returns an <code>IFileModificationValidator</code> for pre-checking operations
	 * that modify the contents of files.
	 * Returns <code>null</code> if the provider does not wish to participate in
	 * file modification validation.
	 * @return an <code>IFileModificationValidator</code> for pre-checking operations
	 * that modify the contents of files
	 *
	 * @see org.eclipse.core.resources.IFileModificationValidator
	 * @deprecated use {@link #getFileModificationValidator2()}
	 */
	@Deprecated
	public IFileModificationValidator getFileModificationValidator() {
		return null;
	}

	/**
	 * Returns a {@link FileModificationValidator} for pre-checking operations
	 * that modify the contents of files. Returns <code>null</code> if the
	 * provider does not wish to participate in file modification validation. By
	 * default, this method wraps the old validator returned from
	 * {@link #getFileModificationValidator()}. Subclasses that which to remain
	 * backwards compatible while providing this new API should override
	 * {@link #getFileModificationValidator2()} to return a subclass of
	 * {@link FileModificationValidator} and should return the same
	 * validator from {@link #getFileModificationValidator()}.
	 * <p>
	 * This method is not intended to be called by clients. Clients should
	 * use the {@link IWorkspace#validateEdit(IFile[], Object)} method instead.
	 *
	 * @return an <code>FileModificationValidator</code> for pre-checking
	 *         operations that modify the contents of files
	 *
	 * @see FileModificationValidator
	 * @see IWorkspace#validateEdit(IFile[], Object)
	 * @since 3.3
	 */
	public FileModificationValidator getFileModificationValidator2() {
		final IFileModificationValidator fileModificationValidator = getFileModificationValidator();
		if (fileModificationValidator == null)
			return null;
		return new FileModificationValidator() {
			@Override
			public IStatus validateSave(IFile file) {
				return fileModificationValidator.validateSave(file);
			}
			@Override
			public IStatus validateEdit(IFile[] files,
					FileModificationValidationContext context) {
				// Extract the shell from the context in order to invoke the old API
				Object shell;
				if (context == null)
					shell = null;
				else
					shell = context.getShell();
				return fileModificationValidator.validateEdit(files, shell);
			}
		};
	}

	/**
	 * Returns an <code>IFileHistoryProvider</code> which can be used to access
	 * file histories. By default, returns <code>null</code>. Subclasses may override.
	 * @return an <code>IFileHistoryProvider</code> which can be used to access
	 * file histories.
	 * @since 3.2
	 */
	public IFileHistoryProvider getFileHistoryProvider(){
		return null;
	}

	/**
	 * Returns an <code>IMoveDeleteHook</code> for handling moves and deletes
	 * that occur within projects managed by the provider. This allows providers
	 * to control how moves and deletes occur and includes the ability to prevent them.
	 * <p>
	 * Returning <code>null</code> signals that the default move and delete behavior is desired.
	 * @return an <code>IMoveDeleteHook</code> for handling moves and deletes
	 * that occur within projects managed by the provider
	 *
	 * @see org.eclipse.core.resources.team.IMoveDeleteHook
	 */
	public IMoveDeleteHook getMoveDeleteHook() {
		return null;
	}

	/**
	 * Returns a brief description of this provider. The exact details of the
	 * representation are unspecified and subject to change, but the following
	 * may be regarded as typical:
	 *
	 * "SampleProject:org.eclipse.team.cvs.provider"
	 *
	 * @return a string description of this provider
	 */
	@Override
	public String toString() {
		return NLS.bind(Messages.RepositoryProvider_toString, new String[] { getProject().getName(), getID() });
	}

	/**
	 * Returns all known (registered) RepositoryProvider ids.
	 *
	 * @return an array of registered repository provider ids.
	 */
	final public static String[] getAllProviderTypeIds() {
		IProjectNatureDescriptor[] desc = ResourcesPlugin.getWorkspace().getNatureDescriptors();
		Set<String> teamSet = new HashSet<>();

		teamSet.addAll(AllProviderTypeIds);	// add in all the ones we know via extension point

		//fall back to old method of nature ID to find any for backwards compatibility
		for (int i = 0; i < desc.length; i++) {
			String[] setIds = desc[i].getNatureSetIds();
			for (int j = 0; j < setIds.length; j++) {
				if(setIds[j].equals(TEAM_SETID)) {
					teamSet.add(desc[i].getNatureId());
				}
			}
		}
		return teamSet.toArray(new String[teamSet.size()]);
	}

	/**
	 * Returns the provider for a given IProject or <code>null</code> if a provider is not associated with
	 * the project or if the project is closed or does not exist. This method should be called if the caller
	 * is looking for <b>any</b> repository provider. Otherwise call <code>getProvider(project, id)</code>
	 * to look for a specific repository provider type.
	 * @param project the project to query for a provider
	 * @return the repository provider associated with the project
	 */
	final public static RepositoryProvider getProvider(IProject project) {
		try {
			if (project.isAccessible()) {

				//-----------------------------
				//First, look for the session property
				RepositoryProvider provider = lookupProviderProp(project);
				if(provider != null)
					return provider;
				// Do a quick check to see it the project is known to be unshared.
				// This is done to avoid accessing the persistent property store
				if (isMarkedAsUnshared(project))
					return null;

				// -----------------------------
				//Next, check if it has the ID as a persistent property, if yes then instantiate provider
				String id = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY);
				if(id != null)
					return mapExistingProvider(project, id);

				//Couldn't find using new method, fall back to lookup using natures for backwards compatibility
				//-----------------------------
				IProjectDescription projectDesc = project.getDescription();
				String[] natureIds = projectDesc.getNatureIds();
				IWorkspace workspace = ResourcesPlugin.getWorkspace();
				// for every nature id on this project, find it's natures sets and check if it is
				// in the team set.
				for (int i = 0; i < natureIds.length; i++) {
					IProjectNatureDescriptor desc = workspace.getNatureDescriptor(natureIds[i]);
					// The descriptor can be null if the nature doesn't exist
					if (desc != null) {
						String[] setIds = desc.getNatureSetIds();
						for (int j = 0; j < setIds.length; j++) {
							if(setIds[j].equals(TEAM_SETID)) {
								return getProvider(project, natureIds[i]);
							}
						}
					}
				}
				markAsUnshared(project);
			}
		} catch(CoreException e) {
			if (!isAcceptableException(e)) {
				TeamPlugin.log(e);
			}
			markAsUnshared(project);
		}
		return null;
	}

	/*
	 * Return whether the given exception is acceptable during a getProvider().
	 * If the exception is acceptable, it is assumed that there is no provider
	 * on the project.
	 */
	private static boolean isAcceptableException(CoreException e) {
		return e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND;
	}

	/**
	 * Returns a provider of type with the given id if associated with the given project
	 * or <code>null</code> if the project is not associated with a provider of that type
	 * or the nature id is that of a non-team repository provider nature.
	 *
	 * @param project the project to query for a provider
	 * @param id the repository provider id
	 * @return the repository provider
	 */
	final public static RepositoryProvider getProvider(IProject project, String id) {
		try {
			if (project.isAccessible()) {
				// Look for an existing provider first to avoid accessing persistent properties
				RepositoryProvider provider = lookupProviderProp(project);  //throws core, we will reuse the catching already here
				if(provider != null) {
					if (provider.getID().equals(id)) {
						return provider;
					} else {
						return null;
					}
				}
				// Do a quick check to see it the project is known to be unshared.
				// This is done to avoid accessing the persistent property store
				if (isMarkedAsUnshared(project))
					return null;

				// There isn't one so check the persistent property
				String existingID = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY);
				if(id.equals(existingID)) {
					// The ids are equal so instantiate and return
					RepositoryProvider newProvider = mapExistingProvider(project, id);
					if (newProvider!= null && newProvider.getID().equals(id)) {
						return newProvider;
					} else {
						// The id changed before we could create the desired provider
						return null;
					}
				}

				//couldn't find using new method, fall back to lookup using natures for backwards compatibility
				//-----------------------------

				// if the nature id given is not in the team set then return
				// null.
				IProjectNatureDescriptor desc = ResourcesPlugin.getWorkspace().getNatureDescriptor(id);
				if(desc == null) //for backwards compatibility, may not have any nature by that ID
					return null;

				String[] setIds = desc.getNatureSetIds();
				for (int i = 0; i < setIds.length; i++) {
					if(setIds[i].equals(TEAM_SETID)) {
						return (RepositoryProvider)project.getNature(id);
					}
				}
				markAsUnshared(project);
			}
		} catch(CoreException e) {
			if (!isAcceptableException(e)) {
				TeamPlugin.log(e);
			}
			markAsUnshared(project);
		}
		return null;
	}

	/**
	 * Returns whether the given project is shared or not. This is a lightweight
	 * method in that it will not instantiate a provider instance (as
	 * <code>getProvider</code> would) if one is not already instantiated.
	 *
	 * Note that IProject.touch() generates a project description delta.  This, in combination
	 * with isShared() can be used to be notified of sharing/unsharing of projects.
	 *
	 * @param project the project being tested.
	 * @return boolean
	 *
	 * @see #getProvider(IProject)
	 *
	 * @since 2.1
	 */
	public static boolean isShared(IProject project) {
		if (!project.isAccessible()) return false;
		try {
			if (lookupProviderProp(project) != null) return true;
			// Do a quick check to see it the project is known to be unshared.
			// This is done to avoid accessing the persistent property store
			if (isMarkedAsUnshared(project))
				return false;
			boolean shared = project.getPersistentProperty(TeamPlugin.PROVIDER_PROP_KEY) != null;
			if (!shared)
				markAsUnshared(project);
			return shared;
		} catch (CoreException e) {
			TeamPlugin.log(e);
			return false;
		}
	}

	private static boolean isMarkedAsUnshared(IProject project) {
		try {
			return project.getSessionProperty(TeamPlugin.PROVIDER_PROP_KEY) == NOT_MAPPED;
		} catch (CoreException e) {
			return false;
		}
	}

	private static void markAsUnshared(IProject project) {
		try {
			project.setSessionProperty(TeamPlugin.PROVIDER_PROP_KEY, NOT_MAPPED);
		} catch (CoreException e) {
			// Just ignore the error as this is just an optimization
		}
	}

	@Override
	public IProject getProject() {
		return project;
	}

	@Override
	public void setProject(IProject project) {
		this.project = project;
	}

	private static List<String> initializeAllProviderTypes() {
		List<String> allIDs = new ArrayList<>();

		TeamPlugin plugin = TeamPlugin.getPlugin();
		if (plugin != null) {
			IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.REPOSITORY_EXTENSION);
			if (extension != null) {
				IExtension[] extensions =  extension.getExtensions();
				for (int i = 0; i < extensions.length; i++) {
					IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
					for (int j = 0; j < configElements.length; j++) {
						String extensionId = configElements[j].getAttribute("id"); //$NON-NLS-1$
						allIDs.add(extensionId);
					}
				}
			}
		}
		return allIDs;
	}

	private static RepositoryProvider newProvider(String id) {
		TeamPlugin plugin = TeamPlugin.getPlugin();
		if (plugin != null) {
			IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.REPOSITORY_EXTENSION);
			if (extension != null) {
				IExtension[] extensions =  extension.getExtensions();
				for (int i = 0; i < extensions.length; i++) {
					IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
					for (int j = 0; j < configElements.length; j++) {
						String extensionId = configElements[j].getAttribute("id"); //$NON-NLS-1$
						if (extensionId != null && extensionId.equals(id)) {
							try {
								return (RepositoryProvider) configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
							} catch (CoreException e) {
								TeamPlugin.log(e);
							} catch (ClassCastException e) {
								String className = configElements[j].getAttribute("class"); //$NON-NLS-1$
								TeamPlugin.log(IStatus.ERROR, NLS.bind(Messages.RepositoryProvider_invalidClass, new String[] { id, className }), e);
							}
							return null;
						}
					}
				}
			}
		}
		return null;
	}

	/**
	 * Method validateCreateLink is invoked by the Platform Core TeamHook when a
	 * linked resource is about to be added to the provider's project. It should
	 * not be called by other clients and it should not need to be overridden by
	 * subclasses (although it is possible to do so in special cases).
	 * Subclasses can indicate that they support linked resources by overriding
	 * the <code>canHandleLinkedResources()</code> method.
	 *
	 * @param resource see <code>org.eclipse.core.resources.team.TeamHook</code>
	 * @param updateFlags see <code>org.eclipse.core.resources.team.TeamHook</code>
	 * @param location see <code>org.eclipse.core.resources.team.TeamHook</code>
	 * @return IStatus see <code>org.eclipse.core.resources.team.TeamHook</code>
	 *
	 * @see RepositoryProvider#canHandleLinkedResources()
	 *
	 * @deprecated see {@link #validateCreateLink(IResource, int, URI) } instead
	 * @since 2.1
	 */
	@Deprecated
	public IStatus validateCreateLink(IResource resource, int updateFlags, IPath location) {
		if (canHandleLinkedResources()) {
			return Team.OK_STATUS;
		} else {
			return new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, NLS.bind(Messages.RepositoryProvider_linkedResourcesNotSupported, new String[] { getProject().getName(), getID() }), null);
		}
	}

	/**
	 * Method validateCreateLink is invoked by the Platform Core TeamHook when a
	 * linked resource is about to be added to the provider's project. It should
	 * not be called by other clients and it should not need to be overridden by
	 * subclasses (although it is possible to do so in special cases).
	 * Subclasses can indicate that they support linked resources by overriding
	 * the <code>canHandleLinkedResourcesAtArbitraryDepth()</code> method.
	 *
	 * @param resource see <code>org.eclipse.core.resources.team.TeamHook</code>
	 * @param updateFlags see <code>org.eclipse.core.resources.team.TeamHook</code>
	 * @param location see <code>org.eclipse.core.resources.team.TeamHook</code>
	 * @return IStatus see <code>org.eclipse.core.resources.team.TeamHook</code>
	 *
	 * @see RepositoryProvider#canHandleLinkedResourceURI()
	 *
	 * @since 3.2
	 */
	public IStatus validateCreateLink(IResource resource, int updateFlags, URI location) {
		if (resource.getProjectRelativePath().segmentCount() == 1 && EFS.SCHEME_FILE.equals(location.getScheme())) {
			// This is compatible with the old style link so invoke the old
			// validateLink
			return validateCreateLink(resource, updateFlags, URIUtil.toPath(location));
		}
		if (canHandleLinkedResourceURI()) {
			return Team.OK_STATUS;
		} else {
			return new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, NLS.bind(Messages.RepositoryProvider_linkedURIsNotSupported, new String[] { getProject().getName(), getID() }), null);
		}
	}

	/**
	 * Method canHandleLinkedResources should be overridden by subclasses who
	 * support linked resources. At a minimum, supporting linked resources
	 * requires changes to the move/delete hook
	 * {@link org.eclipse.core.resources.team.IMoveDeleteHook}. This method is
	 * called after the RepositoryProvider is instantiated but before
	 * <code>setProject()</code> is invoked so it will not have access to any
	 * state determined from the <code>setProject()</code> method.
	 * @return boolean
	 *
	 * @see org.eclipse.core.resources.team.IMoveDeleteHook
	 *
	 * @since 2.1
	 *
	 * @deprecated see {@link #canHandleLinkedResourceURI() }
	 */
	@Deprecated
	public boolean canHandleLinkedResources() {
		return canHandleLinkedResourceURI();
	}

	/**
	 * Return whether this repository provider can handle linked resources that
	 * are located via a URI (i.e. may not be on the local file system) or occur
	 * at an arbitrary depth in the project. This should be overridden by
	 * subclasses who support linked resources at arbitrary depth and/or in
	 * non-local file systems. This is not enabled by default since linked
	 * resources previously only occurred at the root of a project but now can
	 * occur anywhere within a project. This method is called after the
	 * RepositoryProvider is instantiated but before <code>setProject()</code>
	 * is invoked so it will not have access to any state determined from the
	 * <code>setProject()</code> method.
	 *
	 * @return whether this repository provider can handle linked resources that
	 *         are located via a URI or occur at an arbitrary depth in the
	 *         project
	 *
	 * @see #validateCreateLink(IResource, int, URI)
	 *
	 * @since 3.2
	 */
	public boolean canHandleLinkedResourceURI() {
		return false;
	}

	@Override
	public <T> T getAdapter(Class<T> adapter) {
		return null;
	}

	/**
	 * Return the resource rule factory for this provider. This factory
	 * will be used to determine the scheduling rules that are to be obtained
	 * when performing various resource operations (e.g. move, copy, delete, etc.)
	 * on the resources in the project the provider is mapped to.
	 * <p>
	 * By default, the factory returned by this method is pessimistic and
	 * obtains the workspace lock for all operations that could result in a
	 * callback to the provider (either through the <code>IMoveDeleteHook</code>
	 * or <code>IFileModificationValidator</code>). This is done to ensure that
	 * older providers are not broken. However, providers should override this
	 * method and provide a subclass of {@link org.eclipse.core.resources.team.ResourceRuleFactory}
	 * that provides rules of a more optimistic granularity (e.g. project
	 * or lower).
	 * @return the rule factory for this provider
	 * @since 3.0
	 * @see org.eclipse.core.resources.team.ResourceRuleFactory
	 */
	public IResourceRuleFactory getRuleFactory() {
		return new PessimisticResourceRuleFactory();
	}

	/**
	 * Return a {@link Subscriber} that describes the synchronization state
	 * of the resources contained in the project associated with this
	 * provider. The subscriber is obtained from the {@link RepositoryProviderType}
	 * associated with a provider and is thus shared for all providers of the
	 * same type.
	 * @return a subscriber that provides resource synchronization state or <code>null</code>
	 * @since 3.2
	 */
	public final Subscriber getSubscriber() {
		RepositoryProviderType type = RepositoryProviderType.getProviderType(getID());
		if (type != null)
			return type.getSubscriber();
		return null;
	}
}
