/*******************************************************************************
 * Copyright (c) 2000, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.core;

import java.net.URI;
import java.util.*;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.*;
import org.eclipse.core.resources.team.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
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.*;

/**
 * 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:
 * <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>
 * <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 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(new IResourceProxyVisitor() {
					public boolean visit(IResourceProxy proxy) throws CoreException {
						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()
	 */
	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()}
	 */
	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() {
			public IStatus validateSave(IFile file) {
				return fileModificationValidator.validateSave(file);
			}
			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
	 */
	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 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 (String[]) 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.
	 * </p>
	 * @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
        }
    }

    /*
	 * @see IProjectNature#getProject()
	 */
	public IProject getProject() {
		return project;
	}

	/*
	 * @see IProjectNature#setProject(IProject)
	 */
	public void setProject(IProject project) {
		this.project = project;
	}
	
	private static List initializeAllProviderTypes() {
		List 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
	 */
	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() }
	 */
	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;
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class 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;
	}
}	
