/*******************************************************************************
 * Copyright (c) 2007, 2011 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.wst.validation;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.wst.validation.Validator.V1;
import org.eclipse.wst.validation.internal.ConfigurationManager;
import org.eclipse.wst.validation.internal.ContentTypeWrapper;
import org.eclipse.wst.validation.internal.DebugConstants;
import org.eclipse.wst.validation.internal.DependencyIndex;
import org.eclipse.wst.validation.internal.DisabledResourceManager;
import org.eclipse.wst.validation.internal.DisabledValidatorManager;
import org.eclipse.wst.validation.internal.GlobalConfiguration;
import org.eclipse.wst.validation.internal.MarkerManager;
import org.eclipse.wst.validation.internal.Misc;
import org.eclipse.wst.validation.internal.PerformanceMonitor;
import org.eclipse.wst.validation.internal.ProjectUnavailableError;
import org.eclipse.wst.validation.internal.ValManager;
import org.eclipse.wst.validation.internal.ValOperation;
import org.eclipse.wst.validation.internal.ValPrefManagerGlobal;
import org.eclipse.wst.validation.internal.ValPrefManagerProject;
import org.eclipse.wst.validation.internal.ValType;
import org.eclipse.wst.validation.internal.ValidationRunner;
import org.eclipse.wst.validation.internal.ValidatorMetaData;
import org.eclipse.wst.validation.internal.ValidatorMutable;
import org.eclipse.wst.validation.internal.ValManager.UseProjectPreferences;
import org.eclipse.wst.validation.internal.model.GlobalPreferences;
import org.eclipse.wst.validation.internal.model.GlobalPreferencesValues;
import org.eclipse.wst.validation.internal.model.ProjectPreferences;
import org.eclipse.wst.validation.internal.operations.ValidationBuilder;
import org.eclipse.wst.validation.internal.operations.ValidatorManager;
import org.eclipse.wst.validation.internal.operations.WorkbenchReporter;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;


/**
 * The central class of the Validation Framework.
 * <p>
 * This is a singleton class that is accessed through the getDefault() method. 
 * <p>
 * <b>Provisional API:</b> This class/interface is part of an interim API that is still under development and expected to 
 * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
 * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
 * (repeatedly) as the API evolves.
 * </p>
 * @author karasiuk
 *
 */
public final class ValidationFramework {
	
	private volatile IDependencyIndex 	_dependencyIndex;
	private IPerformanceMonitor			_performanceMonitor;
	
	private Set<IProject> 				_suspendedProjects;
	private boolean 					_suspendAllValidation;

	/** 
	 * Answer the singleton, default instance of this class.
	 */
	public static ValidationFramework getDefault(){
		return Singleton.vf;
	}
	
	private ValidationFramework(){}
	
	/**
	 * Add the validation builder to the project, so that the project can support
	 * build time validation. It is safe to call this method, if the builder was
	 * previously added to the project. It will not be added more than once.
	 * 
	 * @param project The project that the builder is added to.
	 */
	public void addValidationBuilder(IProject project){
		ValidatorManager.addProjectBuildValidationSupport(project);
	}
	
	/**
	 * Clear any validation markers that may have been set by this validator.
	 * 
	 * @param resource
	 * 		The resource that may have it's markers cleared.
	 * @param validatorId
	 * 		The id of validator that created the marker.
	 */
	public void clearMessages(IResource resource, String validatorId) throws CoreException {
		Validator v = getValidator(validatorId, null);
		if (v != null)MarkerManager.getDefault().clearMarker(resource, v);
	}
	
	/**
	 * Disable all validation for the given resource. This method instructs
	 * the framework to not run any validators on the given resource or any of
	 * it's children. This setting is persistent. Currently this only works with version 2
	 * validators.
	 * <p>
	 * Use the enableValidation method to restore validation.
	 * </p>
	 * 
	 * @param resource
	 *            The resource that is having validation disabled. It must be an IFolder or an IFile.
	 * 
	 * @see #enableValidation(IResource)
	 */
	public void disableValidation(IResource resource){
		assert resource != null;
		DisabledResourceManager.getDefault().disableValidation(resource);
	}
	
	/**
	 * Enable validation for the given resource. If the resource was not
	 * previously disabled this method call has no effect. Currently this only
	 * works with version 2 validators.
	 * 
	 * @param resource
	 * 		The resource that is having validation re-enabled.
	 * 
	 * @see #disableValidation(IResource)
	 */
	public void enableValidation(IResource resource){
		DisabledResourceManager.getDefault().enableValidation(resource);
	}
	
	/**
	 * Answer the dependency index. Validators can use this to determine which resources depend on which
	 * other resources.
	 */
	public IDependencyIndex getDependencyIndex(){
		// note how the _dependencyIndex is volatile so that this double checking approach can be used.
		if (_dependencyIndex == null){
			synchronized(this){
				if (_dependencyIndex == null)_dependencyIndex = new DependencyIndex();
			}
		}
		return _dependencyIndex;
	}

	/**
	 * Answer a performance monitor for the validators.
	 */
	public synchronized IPerformanceMonitor getPerformanceMonitor(){
		if (_performanceMonitor == null){
			boolean traceTimes = Misc.debugOptionAsBoolean(DebugConstants.TraceTimes);
			String traceFile = Platform.getDebugOption(DebugConstants.TraceTimesFile);
			boolean useDoubles = Misc.debugOptionAsBoolean(DebugConstants.TraceTimesUseDoubles);

			_performanceMonitor = PerformanceMonitor.create(traceTimes, traceFile, useDoubles);
		}
		return _performanceMonitor;
	}
	
	/**
	 * Answer the preference store that holds the persisted global validation settings.
	 */
	public IEclipsePreferences getPreferenceStore(){
		return new InstanceScope().getNode(ValidationPlugin.PLUGIN_ID);
	}
	
	public IReporter getReporter(IProject project, IProgressMonitor monitor){
		return new WorkbenchReporter(project, monitor);
	}
	
	/**
	 * Answer all the validators that are applicable for the given resource. A validator is
	 * still returned even if it has been turned off by the user.
	 * <p>
	 * The caller may still need to test if the validator has been turned off by
	 * the user, by using the isBuildValidation() and isManualValidation()
	 * methods.
	 * </p>
	 * 
	 * @param resource
	 * 		The resource that determines which validators are applicable.
	 * 
	 * @param isManual
	 * 		If true then the validator must be turned on for manual validation.
	 * 		If false then the isManualValidation setting isn't used to filter
	 * 		out validators.
	 * 
	 * @param isBuild
	 * 		If true then the validator must be turned on for build based
	 * 		validation. If false then the isBuildValidation setting isn't used
	 * 		to filter out validators.
	 * 
	 * @see Validator#isBuildValidation()
	 * @see Validator#isManualValidation()
	 */
	public Validator[] getValidatorsFor(IResource resource, boolean isManual, boolean isBuild){
		IProject project = resource.getProject();
		List<Validator> list = new LinkedList<Validator>();
		ContentTypeWrapper ctw = new ContentTypeWrapper();
		for (Validator val : ValManager.getDefault().getValidators(project)){
			if (val.shouldValidate(resource, isManual, isBuild, ctw))list.add(val);
		}
		
		Validator[] result = new Validator[list.size()];
		list.toArray(result);
		return result;
	}
	
	/**
	 * Answer all the validators that should not validate the resource, either
	 * because their filters don't support the resource, or the validator has
	 * been disabled for both build validation and manual validation.
	 * 
	 * @param resource
	 * 		The resource this is being tested.
	 */
	public Set<Validator> getDisabledValidatorsFor(IResource resource){
		return DisabledValidatorManager.getDefault().getDisabledValidatorsFor(resource);
	}
	
	/**
	 * Answer the global validator with the given id.
	 * 
	 * @deprecated Use getValidator(String id, IProject project) with a null project instead.
	 * 
	 * @param id
	 * @return null if the validator is not found
	 */
	public Validator getValidator(String id){
		return ValManager.getDefault().getValidatorWithId(id, null);
	}
	
	/**
	 * Answer the validator with the given id that is in effect for the given
	 * project.
	 * <p>
	 * Individual projects may override the global validation preference
	 * settings. If this is allowed and if the project has it's own settings,
	 * then those validators are returned via this method.
	 * </p>
	 * <p>
	 * The following approach is used. For version 1 validators, the validator
	 * is only returned if it is defined to operate on this project type. This
	 * is the way that the previous version of the framework did it. For version
	 * 2 validators, they are all returned.
	 * </p>
	 * 
	 * @param id
	 * 		Validator id.
	 * @param project
	 * 		This can be null, in which case all the registered validators are
	 * 		checked.
	 * @return null if the validator is not found
	 */
	public Validator getValidator(String id, IProject project){
		return ValManager.getDefault().getValidatorWithId(id, project);
	}
	
	/**
	 * Answer copies of all the registered validators.
	 * 
	 * @return Answer an empty array if there are no validators.
	 */
	public Validator[] getValidators(){
		return ValManager.getDefault().getValidatorsCopy();
	}
		
	/**
	 * Answer the validation settings that have been defined on the
	 * project. To "activate" any changes to these settings, the
	 * {@link #applyChanges(MutableProjectSettings, boolean)} method needs to be
	 * called.
	 * 
	 * @param project The project who's settings you wish to examine or change.
	 * @return Validation settings that apply to the given project.
	 */
	public MutableProjectSettings getProjectSettings(IProject project){
		ProjectPreferences pp = ValManager.getDefault().getProjectPreferences(project);
		Validator[] vals = pp.getValidators();
		ValidatorMutable[] vms = new ValidatorMutable[vals.length];
		for (int i=0; i<vals.length; i++)vms[i] = new ValidatorMutable(vals[i]);

		MutableProjectSettings mps = new MutableProjectSettings(project, vms);
		mps.setOverride(pp.getOverride());
		mps.setSuspend(pp.getSuspend());
		return mps;
	}
	
	/**
	 * Answer the validation settings that have been defined at the workspace level.
	 * To "activate" any changes to these settings, the
	 * {@link #applyChanges(MutableWorkspaceSettings, boolean)} method needs to be
	 * called.
	 * 
	 * @return Validation settings that apply to the entire workspace.
	 */
	public MutableWorkspaceSettings getWorkspaceSettings() throws InvocationTargetException{
		
		ValManager vm = ValManager.getDefault();
		GlobalPreferences gp = vm.getGlobalPreferences();
		
		Validator[] vals = vm.getValidators();		
		ValidatorMutable[] vms = new ValidatorMutable[vals.length];
		for (int i=0; i<vals.length; i++)vms[i] = new ValidatorMutable(vals[i]);

		MutableWorkspaceSettings mws = new MutableWorkspaceSettings(vms, gp.asValues());
		return mws;
	}
		
	/**
	 * Apply the changes that have been been to the validation settings.
	 * 
	 * @param settings
	 *            The project settings.
	 * @param persist
	 *            If true then the changes are persisted to the property files.
	 *            If false the changes are applied to the validators, but are
	 *            not persisted.
	 */
	public void applyChanges(MutableProjectSettings settings, boolean persist){
		ValPrefManagerProject vpm = new ValPrefManagerProject(settings.getProject());
		vpm.savePreferences(settings, persist);
	}
	
	/**
	 * Apply the changes that have been been to the validation settings.
	 * 
	 * @param settings
	 *            The workspace settings.
	 * @param persist
	 *            If true then the changes are persisted to the property files.
	 *            If false the changes are applied to the validators, but are
	 *            not persisted.
	 */
	public void applyChanges(MutableWorkspaceSettings settings, boolean persist){
		
		ValManager vm = ValManager.getDefault();
		GlobalPreferencesValues gpv = settings.getGlobalPreferencesValues();
		vm.replace(gpv);
		
		IMutableValidator[] mvs = settings.getValidators();
		ValidatorMutable[] vals = new ValidatorMutable[mvs.length];
		for (int i=0; i<mvs.length; i++)vals[i] = (ValidatorMutable)mvs[i];
		ValPrefManagerGlobal.getDefault().savePreferences(vm.getGlobalPreferences(), vals, persist);
		ValPrefManagerGlobal.saveV1Preferences(vals, persist);		
	}
	
	/**
	 * Validators can use project level settings (Project natures and facets) to
	 * determine if they are applicable to the project or not.
	 * 
	 * @param project
	 *            The project that the configuration is based on.
	 * @return The copies of the validators that are configured to run on this project based
	 *         on the project level settings.
	 * @throws ProjectUnavailableError
	 */
	public Validator[] getValidatorsConfiguredForProject(IProject project) throws ProjectUnavailableError {
		Validator[] orig = ValManager.getDefault().getValidatorsConfiguredForProject(project, UseProjectPreferences.Normal);
		Validator[] copy = new Validator[orig.length];
		for (int i=0; i<orig.length; i++)copy[i] = orig[i].copy();
		return copy;
	}
	
	/**
	 * Answer all the validators that are applicable for the given resource.
	 * 
	 * @param resource the resource that determines which validators are applicable.
	 */
	public Validator[] getValidatorsFor(IResource resource){
		List<Validator> list = new LinkedList<Validator>();
		for (Validator v : getValidatorsFor(resource, false, false)){
			if (v.isBuildValidation() || v.isManualValidation())list.add(v);
		}
		Validator[] vals = new Validator[list.size()];
		return list.toArray(vals);
	}
	
	/**
	 * Answer true if the resource has any enabled validators.
	 * 
	 * @param resource
	 * 		A file, folder or project.
	 * 
	 * @param isManual
	 * 		If true then the validator must be turned on for manual validation.
	 * 		If false then the isManualValidation setting isn't used to filter
	 * 		out validators.
	 * 
	 * @param isBuild
	 * 		If true then the validator must be turned on for build based
	 * 		validation. If false then the isBuildValidation setting isn't used
	 * 		to filter out validators.
	 */
	public boolean hasValidators(IResource resource, boolean isManual, boolean isBuild){
		return ValManager.getDefault().hasValidators(resource, isManual, isBuild);
	}
	
	/**
	 * Answer whether or not the validator has been activated, i.e. has the
	 * bundle that defines the validator been loaded. We do not want to cause
	 * unnecessary bundle loading, so this check can be performed by third party
	 * callers, to prevent making other calls that will force the validator to
	 * be loaded.
	 * 
	 * @param validator
	 *            The validator that is being tested.
	 * @return true if the validator has already been loaded.
	 */
	public boolean isLoaded(Validator validator){
		return validator.isLoaded();
	}
	
	/**
	 * Waits until all the validation jobs and all the other auto build jobs are finished. 
	 * This method will block the
	 * calling thread until all such jobs have finished executing, or until this
	 * thread is interrupted. If there are no relevant jobs that are
	 * currently waiting, running, or sleeping, this method returns immediately.
	 * Feedback on how the join is progressing is provided to the progress
	 * monitor.
	 * <p>
	 * If this method is called while the job manager is suspended, only jobs
	 * that are currently running will be joined. Once there are no jobs in the
	 * family in the {@link Job#RUNNING} state, this method returns.
	 * </p>
	 * <p>
	 * Note that there is a deadlock risk when using join. If the calling thread
	 * owns a lock or object monitor that the joined thread is waiting for,
	 * deadlock will occur. This method can also result in starvation of the
	 * current thread if another thread continues to add jobs of the given
	 * family, or if a job in the given family reschedules itself in an infinite
	 * loop.
	 * </p>
	 * 
	 * <p>If you are interested in only waiting for the validation jobs, see the
	 * joinValidationOnly method.
	 * 
	 * @param monitor
	 * 		Progress monitor for reporting progress on how the wait is
	 * 		progressing, or <code>null</code> if no progress monitoring is
	 * 		required.
	 * @exception InterruptedException
	 * 		if this thread is interrupted while waiting
	 * @exception OperationCanceledException
	 * 		if the progress monitor is canceled while waiting
	 * 
	 * @see #joinValidationOnly(IProgressMonitor)
	 */
	public void join(IProgressMonitor monitor) throws InterruptedException, OperationCanceledException {
		Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, monitor);
		Job.getJobManager().join(ValidationBuilder.FAMILY_VALIDATION_JOB, monitor);
	}
	
	/**
	 * Waits until all the validation jobs are finished. 
	 * This method will block the
	 * calling thread until all such jobs have finished executing, or until this
	 * thread is interrupted. If there are no relevant jobs that are
	 * currently waiting, running, or sleeping, this method returns immediately.
	 * Feedback on how the join is progressing is provided to the progress
	 * monitor.
	 * <p>
	 * If this method is called while the job manager is suspended, only jobs
	 * that are currently running will be joined. Once there are no jobs in the
	 * family in the {@link Job#RUNNING} state, this method returns.
	 * </p>
	 * <p>
	 * Note that there is a deadlock risk when using join. If the calling thread
	 * owns a lock or object monitor that the joined thread is waiting for,
	 * deadlock will occur. This method can also result in starvation of the
	 * current thread if another thread continues to add jobs of the given
	 * family, or if a job in the given family reschedules itself in an infinite
	 * loop.
	 * </p>
	 * 
	 * @param monitor
	 * 		Progress monitor for reporting progress on how the wait is
	 * 		progressing, or <code>null</code> if no progress monitoring is
	 * 		required.
	 * @exception InterruptedException
	 * 		if this thread is interrupted while waiting
	 * @exception OperationCanceledException
	 * 		if the progress monitor is canceled while waiting
	 */
	public void joinValidationOnly(IProgressMonitor monitor) throws InterruptedException, OperationCanceledException {
		Job.getJobManager().join(ValidationBuilder.FAMILY_VALIDATION_JOB, monitor);
	}
	
	/**
	 * Suspends, or undoes the suspension of, validation on the current project.
	 * If <b>suspend</b> is true then validation is suspended and if it's false
	 * then validation is not suspended on the project. The value of this
	 * variable is not persisted.
	 * <p>
	 * Be <b>very careful</b> when you use this method! Turn validation back on in a
	 * finally block because if the code which suspended validation crashes, the
	 * user has no way to reset the suspension. The user will have to shut down
	 * and restart the workbench to get validation to work again.
	 * </p>
	 * 
	 * @param project
	 * 		The project that is to be suspended or unsuspended.
	 * @param suspend
	 * 		If true, validation on the project will be suspend. If false it will
	 * 		not be suspended.
	 */
	public void suspendValidation(IProject project, boolean suspend) {
		if (project == null)return;
		if (suspend)getSuspendedProjects().add(project);
		else getSuspendedProjects().remove(project);
	}
	
	private synchronized Set<IProject> getSuspendedProjects(){
		if (_suspendedProjects == null)_suspendedProjects = Collections.synchronizedSet(new HashSet<IProject>(20));
		return _suspendedProjects;
	}
	
	/**
	 * Save the validators settings into the persistent store, there by making their settings the active settings.
	 * <p>
	 * A common use of this method would be to change whether particular validators are enabled or not. For example
	 * if you only wanted the JSP validator enabled, you could use code similar to this:
	 * <pre>
	 * ValidationFramework vf = ValidationFramework.getDefault();
	 * Validator[] vals = vf.getValidators();
	 * for (Validator v : vals){
	 *   boolean enabled = false;
	 *   if (v.getValidatorClassname().equals("org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator"))enabled = true;
	 *     v.setBuildValidation(enabled);
	 *     v.setManualValidation(enabled);
	 *  }
	 * vf.saveValidators(vals);
	 * </pre>
	 * </p> 
	 * 
	 * @param validators The validators that you are saving.
	 * 
	 * @throws InvocationTargetException
	 */
	public void saveValidators(Validator[] validators) throws InvocationTargetException{
		
		
		ValPrefManagerGlobal gp = ValPrefManagerGlobal.getDefault();
		gp.saveAsPrefs(validators);	
		
		GlobalConfiguration gc = ConfigurationManager.getManager().getGlobalConfiguration();
		
		List<ValidatorMetaData> manual = new LinkedList<ValidatorMetaData>();
		List<ValidatorMetaData> build = new LinkedList<ValidatorMetaData>();
		for (Validator v : validators){
			V1 v1 = v.asV1Validator();
			if (v1 == null)continue;
			if (v1.isManualValidation())manual.add(v1.getVmd());
			if (v1.isBuildValidation())build.add(v1.getVmd());
		}
		
		ValidatorMetaData[] array = new ValidatorMetaData[manual.size()];
		gc.setEnabledManualValidators(manual.toArray(array));
		
		array = new ValidatorMetaData[build.size()];
		gc.setEnabledBuildValidators(build.toArray(array));

		gc.passivate();
		gc.store();		
	}

	/**
	 * Suspends, or undoes the suspension of, validation on all projects in the
	 * workbench. If "suspend" is true then validation is suspended and if it's
	 * "false" then validation is not suspended. The value of this variable is
	 * not persisted.
	 * <p>
	 * Be <b>very careful</b> when you use this method! Turn validation back on in a
	 * finally block because if the code which suspended validation crashes, the
	 * user has no way to reset the suspension. The user will have to shut down
	 * and restart the workbench to get validation to work again.
	 * </p>
	 */
	public void suspendAllValidation(boolean suspend) {
		_suspendAllValidation = suspend;
	}

	/**
	 * Return true if "suspend all" is enabled, false otherwise.
	 */
	public boolean isSuspended() {
		return _suspendAllValidation;
	}

	/**
	 * Returns true if validation will not run on the project because it's been suspended. This
	 * method checks only the suspension status; if validation cannot run for some other reason (for
	 * example, there are no enabled validators), yet the IProject is not suspended, this method
	 * will return true even though validation will not run.
	 */
	public boolean isSuspended(IProject project) {
		if (_suspendAllValidation)return true;
		if (project == null)return false;
		return getSuspendedProjects().contains(project);
	}

	/**
	 * This method should be called by any code that is preparing to suspend validation on a
	 * project. Rather than calling isSuspended(IProject), which will also return true if all validation
	 * has been suspended. 
	 * 
	 * @param project the project that is being tested
	 * @return boolean true if the project has been suspended
	 */
	public boolean isProjectSuspended(IProject project) {
		if (project == null)return false;
		return getSuspendedProjects().contains(project);
	}
	
	/**
	 * Validate the projects. Exactly one of isManual or isBuild needs to be true.
	 * 
	 * @param projects
	 *            The projects to be validated.
	 * 
	 * @param isManual
	 *            Is this being done as part of a manual validation? i.e. did
	 *            the user select the Validate menu item?
	 * 
	 * @param isBuild
	 *            Is this being done as part of a build?
	 * 
	 * @param monitor
	 * 
	 * @return the validation result which is the combined result for all the
	 *         resources that were validated.
	 */
	public ValidationResults validate(IProject[] projects, final boolean isManual, final boolean isBuild,
		IProgressMonitor monitor) throws CoreException{
		ValType type = ValType.Build;
		if (isManual)type = ValType.Manual;
		ValOperation vo = ValidationRunner.validate(createMap(projects), type, monitor, true);
		return vo.getResults();
	}

	/**
	 * Validate a specific file resource.
	 * 
	 * @param file
	 *            The file to be validated.
	 * @param monitor
	 *            Progress monitor.
	 * @return the result of validating the file.
	 */
  public ValidationResults validate(IFile file, IProgressMonitor monitor) throws CoreException{
      ValOperation vo = ValidationRunner.validate(file, ValType.Manual, monitor, true);
      return vo.getResults();
    }
	  
	/**
	 * Answer all the resources in the projects as a map.
	 * @param projects
	 */
	private Map<IProject, Set<IResource>> createMap(IProject[] projects) throws CoreException{
		final HashMap<IProject, Set<IResource>> map = new HashMap<IProject, Set<IResource>>(1000);
			
		for (IProject p : projects){
			Set<IResource> set = new HashSet<IResource>(1000);
			ResourceAdder ra = new ResourceAdder(set);
			p.accept(ra);
			map.put(p, set);
		}
		return map;
	}
	
	public static class ResourceAdder implements IResourceVisitor {
		
		private Set<IResource> _set;
		
		/**
		 * A class that knows how to add resources to a set.
		 * @param set the set where the resources are added.
		 */
		public ResourceAdder(Set<IResource> set){
			_set = set;
		}

		public boolean visit(IResource resource) throws CoreException {
			// [225839] the older validators only expect files and folders.
			int type = resource.getType();
			if (type == IResource.FILE || type == IResource.FOLDER)_set.add(resource);
			return true;
		}
		
	}
	
	/**
	 * Store the singleton for the ValidationFramework. This approach is used to avoid having to synchronize the
	 * ValidationFramework.getDefault() method.
	 * 
	 * @author karasiuk
	 *
	 */
	private static class Singleton {
		static ValidationFramework vf = new ValidationFramework();
	}

}
