/*******************************************************************************
 * Copyright (c) 2001, 2008 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.internal.operations;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.wst.common.frameworks.internal.operations.IHeadlessRunnableWithProgress;
import org.eclipse.wst.validation.ValidationFramework;
import org.eclipse.wst.validation.internal.FilterUtil;
import org.eclipse.wst.validation.internal.IProjectValidationHelper;
import org.eclipse.wst.validation.internal.InternalValidatorManager;
import org.eclipse.wst.validation.internal.ReferencialFileValidatorRegistryReader;
import org.eclipse.wst.validation.internal.RegistryConstants;
import org.eclipse.wst.validation.internal.ResourceConstants;
import org.eclipse.wst.validation.internal.ResourceHandler;
import org.eclipse.wst.validation.internal.TaskListUtility;
import org.eclipse.wst.validation.internal.Tracing;
import org.eclipse.wst.validation.internal.ValManager;
import org.eclipse.wst.validation.internal.ValidationRegistryReader;
import org.eclipse.wst.validation.internal.ValidatorMetaData;
import org.eclipse.wst.validation.internal.core.IFileDelta;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.core.ValidatorLauncher;
import org.eclipse.wst.validation.internal.plugin.ValidationHelperRegistryReader;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
import org.eclipse.wst.validation.internal.provisional.core.IValidator;
import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;

/**
 * Implemented Validators methods must not be called directly by anyone other than this class, since
 * some initialization of the validator is done here (via the getProject() method). The
 * initialization is separated because the IProject isn't known until runtime.
 * <p>
 * This operation is not intended to be subclassed outside of the validation framework.
 */
public abstract class ValidationOperation implements IWorkspaceRunnable, IHeadlessRunnableWithProgress {
	// Since IResourceConstants don't have a "no delta" flag, let this constant be the flag.
	public static final int NO_DELTA_CHANGE = -1; 
	private static final String DELTA_AS_STRING = "IFileDelta[{0}] '{'{1}'}'"; //$NON-NLS-1$
	private static final String COMMA = ", "; //$NON-NLS-1$
	
	// For the depreciated constructors, by default the operation will not fork. 
	protected static final boolean DEFAULT_ASYNC = true;
	
	protected static final boolean DEFAULT_FORCE = true;
	
	private static ValidationLauncherJob launcherJob = new ValidationLauncherJob();
	
	private static final int jobsPerProcessor = 3;
	
	private static class ValidationLauncherJob extends Job {
	    private Queue<Job> validationJobs = new LinkedList<Job>();
	    public ValidationLauncherJob() {
            super(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_VALIDATION_JOB_MSG));
            setSystem(true);
            setRule(ResourcesPlugin.getWorkspace().getRoot());
	    }
	    
	    protected IStatus run(IProgressMonitor monitor) {
			int processors = Runtime.getRuntime().availableProcessors();
			int totalInitialJobs = processors * jobsPerProcessor;
    		synchronized (validationJobs) {
    			// never schedule more than 3 validation jobs per processor at a time
    			for (int i=0; i< totalInitialJobs; i++) {
    				Job validationJob = validationJobs.poll();
    				if (validationJob == null) break;
    				addJobChangeAdapter(validationJob);
    				validationJob.schedule();
    			}
    		}
            return Status.OK_STATUS;
	    }
	    
	    private void addJobChangeAdapter(Job job) {
	    	job.addJobChangeListener(new JobChangeAdapter(){
	    		// when done, see if there is another validation job to schedule
				public void done(IJobChangeEvent event) {
					synchronized (validationJobs) {
						Job validationJob = validationJobs.poll();
						if (validationJob != null) {
							addJobChangeAdapter(validationJob);
							validationJob.schedule();
						}
					}
				}
			});
	    }
	    
	    @Override
	    public boolean belongsTo(Object family) {
			if (family == ResourcesPlugin.FAMILY_MANUAL_BUILD)return true;
			if (family == ValidationBuilder.FAMILY_VALIDATION_JOB){
				return true;
			}
			return super.belongsTo(family);
	    }
	    
	    public void addValidationJob(Job validationJob) {
	    	synchronized (validationJobs) {
	    		validationJobs.add(validationJob);
	    		// schedule the job if we were empty
	    		if (validationJobs.size() == 1) {
	    			this.schedule();
	    		}
	    	}
	    }
	}
	
	/**
	 * @deprecated Will be removed in Milestone 3. Use DEFAULT_ASYNC
	 */
	protected static final boolean DEFAULT_FORK = false; // @deprecated
	private IProject 		_project; // project to be validated
	private int 			_ruleGroup = RegistryConstants.ATT_RULE_GROUP_DEFAULT;
	private boolean _fork = DEFAULT_ASYNC; // do not fork the validation into a
	// different thread by default
	private Map<ValidatorMetaData, Set<IFileDelta>> _fileDeltas; // To reduce object creation,
	private IResourceDelta _delta;
	
	// the resource delta tree to be processed, or null if a full build/menu
	// option was triggered. This value is cached so that validation can be run
	// either from a builder, or from a menu item. (The Operation interface
	// doesn't allow any parameter on execute except the IProgressMonitor.)
	private Set<ValidatorMetaData> _enabledValidators;
	
	private boolean _force = DEFAULT_FORCE; // force this operation to run even if it doesn't need to?
	private boolean _isFullValidate; 	// Run a full validation or an incremental? (true = full)
	private Boolean _isAutoBuild; 		// Is the global auto-build preference enabled?
	private Set<ValidatorMetaData> _launchedValidators;
	
	protected IWorkbenchContext context;

	// are enabled and were launched (i.e., that have input to validate). For internal
	// validation framework use only;
	// it's needed for the automatic tests.
	/**
	 * This method is used for FINEST logging, to report exactly what deltas were about to be
	 * validated.
	 */
	private static final String getDeltaAsString(IFileDelta[] delta) {
		String args = ""; //$NON-NLS-1$
		int numArgs = 0;
		if (delta != null) {
			numArgs = delta.length;
			StringBuffer buffer = new StringBuffer();
			for (int i = 0; i < delta.length; i++) {
				buffer.append(COMMA);
				buffer.append(delta[i].toString());
			}
			buffer.replace(0, 1, ""); //$NON-NLS-1$ // magic numbers 0 and 1 => Remove first COMMA from the list (hence index 0); length of COMMA is 2, hence index 0, 1.
			args = buffer.toString();
		}
		return MessageFormat.format(DELTA_AS_STRING, new Object[]{String.valueOf(numArgs), args});
	}

	protected static void checkCanceled(WorkbenchReporter reporter) throws OperationCanceledException {
		if (reporter == null)return;
		else if (reporter.getProgressMonitor().isCanceled()) {
			throw new OperationCanceledException(""); //$NON-NLS-1$
		}
	}

	protected static boolean shouldForce(IResourceDelta delta) {
		return ((delta == null) ? DEFAULT_FORCE : false);
	}

	protected static boolean shouldForce(Object[] changedResources) {
		return (((changedResources == null) || (changedResources.length == 0)) ? DEFAULT_FORCE : false);
	}

	/**
	 * @deprecated. Will be removed in Milestone 3. Use ValidationOperation(project, boolean)
	 */
	public ValidationOperation(IProject project) {
		this(project, DEFAULT_ASYNC, DEFAULT_FORCE);
	}

	/**
	 * Internal.
	 */
	public ValidationOperation(IProject project, boolean force, boolean async) {
		this(project, null, null, RegistryConstants.ATT_RULE_GROUP_DEFAULT, force, async);
	}

	/**
	 * @deprecated. Will be removed in Milestone 3. Use ValidationOperation(project, int, boolean)
	 */
	public ValidationOperation(IProject project, int ruleGroup) {
		this(project, null, null, ruleGroup, DEFAULT_FORCE, DEFAULT_ASYNC);
	}

	/**
	 * @deprecated. Will be removed in Milestone 3. Use ValidationOperation(IProject,
	 *              IResourceDelta, Boolean, int, boolean, boolean)
	 */
	public ValidationOperation(IProject project, IResourceDelta delta, boolean isAutoBuild, int ruleGroup, boolean force, boolean fork) {
		this(project, delta, ((isAutoBuild) ? Boolean.TRUE : Boolean.FALSE), ruleGroup, fork, force);
	}

	/**
	 * Internal.
	 */
	protected ValidationOperation(IProject project, IResourceDelta delta, Boolean isAutoBuild, int ruleGroup, boolean force, boolean fork) {
		super();
		_project = project;
		_delta = delta;
		_isAutoBuild = isAutoBuild;
		_ruleGroup = ruleGroup;
		_fork = fork;
		_force = force;
		_enabledValidators = new HashSet<ValidatorMetaData>();
	}
	
	/**
	 * Internal.
	 */
	protected ValidationOperation(IProject project, IWorkbenchContext aContext, IResourceDelta delta, Boolean isAutoBuild, int ruleGroup, boolean force, boolean fork) {
		super();
		_project = project;
		_delta = delta;
		_isAutoBuild = isAutoBuild;
		_ruleGroup = ruleGroup;
		_fork = fork;
		_force = force;
		_enabledValidators = new HashSet<ValidatorMetaData>();
		context = aContext;
	}

	/**
	 * @deprecated Will be removed in Milestone 3.
	 */
	protected void terminateCleanup(WorkbenchReporter reporter) {
		for (ValidatorMetaData vmd : getEnabledValidators()) {
			reporter.displaySubtask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_CLEANUP, new String[]{vmd.getValidatorDisplayName()}));
			try {
				reporter.removeAllMessages(vmd.getValidator());
			} catch (InstantiationException e) {
				// Remove the vmd from the reader's list
				ValidationRegistryReader.getReader().disableValidator(vmd);
				ValidationPlugin.getPlugin().handleException(e);
				continue;
			}
			addCancelTask(vmd);
			reporter.displaySubtask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED, new String[]{getProject().getName(), vmd.getValidatorDisplayName()}));
		}
	} 
	

	/**
	 * @param vmd
	 * @param delta
	 * @param logger
	 * @param start
	 */
//	private void logValidationInfo(ValidatorMetaData vmd, IFileDelta[] delta, Logger logger, long start) {
//		long finish = System.currentTimeMillis();
//		TimeEntry entry = ValidationPlugin.getTimeEntry();
//		entry.setSourceID("ValidationOperation.launchValidator"); //$NON-NLS-1$
//		entry.setProjectName(getProject().getName());
//		entry.setToolName(vmd.getValidatorUniqueName());
//		entry.setElapsedTime(finish - start);
//		if (logger.isLoggingLevel(Level.FINE)) {
//			StringBuffer buffer = new StringBuffer();
//			if (isFullValidate()) {
//				buffer.append("EVERYTHING"); //$NON-NLS-1$
//			} else {
//				if (delta.length == 0) {
//					buffer.append("NOTHING"); //$NON-NLS-1$
//				} else {
//					buffer.append(getDeltaAsString(delta));
//				}
//			}
//			entry.setDetails(buffer.toString());
//		}
//		logger.write(Level.INFO, entry);
//	}

	/**
	 * @param reporter
	 * @param vmd
	 * @param logger
	 * @param exc
	 */
//	private void handleThrowables(WorkbenchReporter reporter, ValidatorMetaData vmd, Logger logger, Throwable exc) {
//		// If a runtime exception has occured, e.g. NullPointer or ClassCast,
//		// display it with the "A runtime exception has occurred " messsage.
//		// This will provide more information to the user when he/she calls IBM
//		// Service.
//		if (logger.isLoggingLevel(Level.SEVERE)) {
//			LogEntry entry = ValidationPlugin.getLogEntry();
//			entry.setSourceID("ValidationOperation::launchValidator"); //$NON-NLS-1$
//			entry.setTargetException(exc);
//			logger.write(Level.SEVERE, entry);
//		}
//		String[] msgParm = {exc.getClass().getName(), vmd.getValidatorDisplayName(), (exc.getMessage() == null ? "" : exc.getMessage())}; //$NON-NLS-1$
//		Message message = ValidationPlugin.getMessage();
//		message.setSeverity(IMessage.NORMAL_SEVERITY);
//		message.setId(ResourceConstants.VBF_EXC_RUNTIME);
//		message.setParams(msgParm);
//		try {
//			reporter.addMessage(vmd.getValidator(), message);
//		} catch (InstantiationException exc2) {
//			handleInstantiationException(vmd, logger, exc2);
//		} catch (MessageLimitException e) {
//			throw e;
//		}
//		return;
//	}

	/**
	 * @param vmd
	 * @param logger
	 * @param exc2
	 */
//	private void handleInstantiationException(ValidatorMetaData vmd, Logger logger, InstantiationException exc2) {
//		// Remove the vmd from the reader's list
//		ValidationRegistryReader.getReader().disableValidator(vmd);
//		// Log the reason for the disabled validator
//		if (logger.isLoggingLevel(Level.SEVERE)) {
//			LogEntry entry = ValidationPlugin.getLogEntry();
//			entry.setSourceID("ValidationOperation::launchValidator (deprecated)"); //$NON-NLS-1$
//			entry.setTargetException(exc2);
//			logger.write(Level.SEVERE, entry);
//		}
//	}

	/**
	 * @param reporter
	 * @param vmd
	 * @param logger
	 * @param exc
	 */
//	private void handleValidationExceptions(WorkbenchReporter reporter, ValidatorMetaData vmd, Logger logger, ValidationException exc) {
//		// First, see if a validator just caught all Throwables and
//		// accidentally wrapped a MessageLimitException instead of propagating
//		// it.
//		if (exc.getAssociatedException() != null) {
//			if (exc.getAssociatedException() instanceof MessageLimitException) {
//				MessageLimitException mssgExc = (MessageLimitException) exc.getAssociatedException();
//				throw mssgExc;
//			} else if (exc.getAssociatedException() instanceof ValidationException) {
//				try {
//					ValidationException vexc = (ValidationException) exc.getAssociatedException();
//					vexc.setClassLoader(vmd.getValidator().getClass().getClassLoader()); // first,
//					// set the class loader,so that the exception's getMessage() method can retrieve
//					// the resource bundle
//				} catch (InstantiationException exc2) {
//					handleInstantiationException(vmd, logger, exc2);
//				}
//			}
//		}
//		// If there is a problem with this particular validator, log the error
//		// and continue
//		// with the next validator.
//		try {
//			exc.setClassLoader(vmd.getValidator().getClass().getClassLoader()); // first,
//			// set the class loader,so that the exception's getMessage() method can retrieve the
//			// resource bundle
//		} catch (InstantiationException exc2) {
//			handleInstantiationException(vmd, logger, exc2);
//		}
//		if (logger.isLoggingLevel(Level.SEVERE)) {
//			LogEntry entry = ValidationPlugin.getLogEntry();
//			entry.setSourceID("ValidationOperation.validate(WorkbenchMonitor)"); //$NON-NLS-1$
//			entry.setTargetException(exc);
//			logger.write(Level.SEVERE, entry);
//			if (exc.getAssociatedException() != null) {
//				entry.setTargetException(exc.getAssociatedException());
//				logger.write(Level.SEVERE, entry);
//			}
//		}
//		String message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
//		reporter.displaySubtask(message);
//		if (exc.getAssociatedMessage() != null) {
//			try {
//				reporter.addMessage(vmd.getValidator(), exc.getAssociatedMessage());
//			} catch (InstantiationException exc2) {
//				handleInstantiationException(vmd, logger, exc2);
//			}
//		}
//	}

	/**
	 * @param reporter
	 * @param vmd
	 * @param logger
	 * @param exc
	 */
//	private void handleHelperCleanupExceptions(WorkbenchReporter reporter, ValidatorMetaData vmd, Logger logger, Throwable exc) {
//		// If a runtime exception has occured, e.g. NullPointer or ClassCast,
//		// display it with the "A runtime exception has occurred " messsage.
//		// This will provide more information to the user when he/she calls IBM
//		// Service.
//		if (logger.isLoggingLevel(Level.SEVERE)) {
//			LogEntry entry = ValidationPlugin.getLogEntry();
//			entry.setSourceID("ValidationOperation::launchValidator"); //$NON-NLS-1$
//			entry.setTargetException(exc);
//			logger.write(Level.SEVERE, entry);
//		}
//		String[] msgParm = {exc.getClass().getName(), vmd.getValidatorDisplayName(), (exc.getMessage() == null ? "" : exc.getMessage())}; //$NON-NLS-1$
//		Message message = ValidationPlugin.getMessage();
//		message.setSeverity(IMessage.NORMAL_SEVERITY);
//		message.setId(ResourceConstants.VBF_EXC_RUNTIME);
//		message.setParams(msgParm);
//		try {
//			reporter.addMessage(vmd.getValidator(), message);
//		} catch (InstantiationException exc2) {
//			handleInstantiationException(vmd, logger, exc2);
//		} catch (MessageLimitException e) {
//			throw e;
//		}
//		return;
//	}

	public boolean isFork() {
		return _fork;
	}

	public boolean isForce() {
		return _force;
	}

	public void setForce(boolean force) {
		_force = force;
	}

	/**
	 * If the code that invoked this operation suspended auto-build before invoking this operation,
	 * the user's auto-build setting is stored in the following methods.
	 */
	public boolean isAutoBuild() {
		if (_isAutoBuild == null) {
			return ValidatorManager.getManager().isGlobalAutoBuildEnabled();
		}
		return _isAutoBuild.booleanValue();
	}

	protected void setAutoBuild(boolean autoOn) {
		_isAutoBuild = ((autoOn) ? Boolean.TRUE : Boolean.FALSE);
	}

	protected boolean isFullValidate() {
		return _isFullValidate;
	}

	private void setFullValidate(boolean b) {
		_isFullValidate = b;
	}

	protected int getRuleGroup() {
		return _ruleGroup;
	}

	/**
	 * Return true if the given validator must run (i.e., it has changes to validate, and it was not
	 * run automatically.)
	 */
	private boolean isValidationNecessary(ValidatorMetaData vmd, IFileDelta[] delta) {
		// Validation is not necessary if there are no files for the validator to validate.
		return isFullValidate() || (delta.length > 0);
	}

	/**
	 * Return true if, given the enabled validators and file deltas, there is work for this
	 * operation to do.
	 */
	public boolean isNecessary(IProgressMonitor monitor) throws CoreException, OperationCanceledException {
		Set<ValidatorMetaData> enabledValidators = getEnabledValidators();
		if ((enabledValidators == null) || (enabledValidators.size() == 0)) {
			return false;
		}
		if (isFullValidate())return true;
		
		for (ValidatorMetaData vmd : enabledValidators) {
			if (isValidationNecessary(vmd, getFileDeltas(monitor, vmd)))return true;
		}
		return false;
	}

	private Map<ValidatorMetaData, Set<IFileDelta>> getFileDeltas(IProgressMonitor monitor) throws CoreException {
		if (_fileDeltas == null)loadFileDeltas(monitor);
		return _fileDeltas;
	}

	private IFileDelta[] getFileDeltas(IProgressMonitor monitor, ValidatorMetaData vmd) throws CoreException {
		Set<IFileDelta> result = getFileDeltas(monitor).get(vmd);
		if (result == null)return new IFileDelta[0];
		
		IFileDelta[] temp = new IFileDelta[result.size()];
		result.toArray(temp);
		return temp;
	}

	/**
	 * Store the file deltas (VMD <=>Set[IFileDelta]) if the file deltas haven't been loaded. If the
	 * deltas have already been loaded, return without doing anything.
	 */
	private void loadFileDeltas(IProgressMonitor monitor) throws CoreException {
		// Although, for a full build, we don't build up a list of changed
		// files, we do need to notify each IWorkbenchContext that an
		// IResource has been filtered in.
		// It's a full validation if the IResourceDelta is null and the
		// Object[] (or IResource[]) is also null.
		// i.e., it's a full validation if no incremental input has been set.
		setFullValidate((getDelta() == null) && (_fileDeltas == null));
		if (isFullValidate()) {
			_fileDeltas = FilterUtil.loadDeltas(monitor, getEnabledValidators(), getProject());
		} else {
			_fileDeltas = FilterUtil.loadDeltas(monitor, getEnabledValidators(), getDelta()); // traverse,
			// and process, each resource in the delta tree
		}
	}

	protected void setFileDeltas(Map<ValidatorMetaData, Set<IFileDelta>> deltas) {
		_fileDeltas = deltas;
	}

	protected IResourceDelta getDelta() {
		return _delta;
	}

	protected void setDelta(IResourceDelta delta) {
		_delta = delta;
	}

	protected boolean areValidatorsEnabled() {
		return (getEnabledValidators().size() != 0);
	}

	/**
	 * Return the validators which are both configured on this type of project, (as stored in
	 * getProject()), and enabled by the user on this project.
	 */
	public Set<ValidatorMetaData> getEnabledValidators() {
		return _enabledValidators;
	}

	/**
	 * This is an internal method, subject to change without notice. It is provided only for the
	 * automated validation framework tests.
	 */
	public Set<ValidatorMetaData> getLaunchedValidators() {
		if (_launchedValidators == null) {
			_launchedValidators = new HashSet<ValidatorMetaData>();
		}
		return _launchedValidators;
	}

	protected void setEnabledValidators(Set<ValidatorMetaData> evmds) {
		// Check that every VMD in the set is configured on this project.
		// Necessary because the user can manually choose which validators
		// to launch, and the validator may not be installed.
		_enabledValidators.clear();
		for (ValidatorMetaData vmd : evmds) {
			if (ValidationRegistryReader.getReader().isConfiguredOnProject(vmd, getProject())) {
				_enabledValidators.add(vmd);
			}
		}
	}

	/**
	 * This method returns the IProject that this ValidationOperation was created with.
	 */
	public IProject getProject() {
		return _project;
	}

	protected int getUnitsOfWork() {
		/*
		 * Let one unit of work equal one resource. number of enabled validators. i.e., each
		 * enabled validator must process (at most) each resource in the project; count each process
		 * as one unit of work. Note that this is a ceiling number, because if we're doing an
		 * incremental validation, not all resources will be validated.
		 * setNumResources(countResources(getProject())); getEnabledValidators().size();
		 */
		// Until the validators can report units-of-work complete,
		// initialize the monitor with an unknown amount of work.
		// (So the user will see movement in the progress bar, even
		// if the movement doesn't indicate the amount of work done.)
		return IProgressMonitor.UNKNOWN;
	}

	/**
	 * If the user is cancelling validation on the current project/resource, Add an information task
	 * to the task list informing the user that validation has not been run on the current project.
	 */
	protected void addCancelTask(ValidatorMetaData vmd) {
		InternalValidatorManager.getManager().addOperationTask(getProject(), vmd, ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
	}

	/**
	 * This method starts the validation of each configured enabled validator on the current
	 * project.
	 * 
	 * The IProgressMonitor passed in must not be null.
	 */
	public void run(IProgressMonitor progressMonitor) throws OperationCanceledException {
		try {
			// In order to check whether or not the monitor has been canceled, the monitor must not be null.
			if (progressMonitor == null)return;
			IProject project = getProject();
			if (ValidationFramework.getDefault().isSuspended(project))return;
			if (ValManager.getDefault().isDisabled(project))return;
			
			if (!areValidatorsEnabled()) {
				// save some processing time...
				return;
			}
			
			final WorkbenchReporter reporter = new WorkbenchReporter(getProject(), progressMonitor);

			try {
				// Periodically check if the user has canceled the operation
				checkCanceled(reporter);
				preValidate(reporter);
				validate(reporter);
				validateReferencialFiles(reporter);
			} catch (CoreException e) {
				ValidationPlugin.getPlugin().handleException(e);
			}
		} finally {
			//TODO GRK determine if timing info should be added here
//			if (logger.isLoggingLevel(Level.FINE)) {
//				long finish = System.currentTimeMillis();
//				TimeEntry entry = ValidationPlugin.getTimeEntry();
//				entry.setSourceID("ValidationOperation.run(WorkbenchMonitor)"); //$NON-NLS-1$
//				entry.setProjectName(getProject().getName());
//				entry.setToolName("ValidationOperation"); //$NON-NLS-1$
//				entry.setElapsedTime(finish - start);
//				logger.write(Level.FINE, entry);
//			}
		}
	}

	private void validateReferencialFiles(WorkbenchReporter reporter) {
		ReferencialFileValidatorRegistryReader reader = ReferencialFileValidatorRegistryReader.getInstance();
		if (reader != null) {
			reader.readRegistry();
			ReferencialFileValidator refFileValidator = reader.getReferencialFileValidator();
			if (refFileValidator != null) {
				if (_delta != null) {
					refFileValidateFileDelta(reporter, refFileValidator);
				} else if (_project != null) {
					postValidateProject(reporter, refFileValidator);
				}
			}
		}
	}

	private void refFileValidateFileDelta(WorkbenchReporter reporter, ReferencialFileValidator refFileValidator) {
		IResourceDelta[] resourceDelta = _delta.getAffectedChildren(IResourceDelta.ADDED | IResourceDelta.CHANGED | IResourceDelta.REMOVED);
		List<IResource> inputFiles = new ArrayList<IResource>();
		
		List<IFile> referencingFiles = new ArrayList<IFile>();
		if (resourceDelta != null && resourceDelta.length > 0) {
			for (int i = 0; i < resourceDelta.length; i++) {
				IResource resource = resourceDelta[i].getResource();
				if (resource instanceof IFolder) {
					getFileResourceDeltaInFolder(resourceDelta[i], inputFiles);
				} else if (resource instanceof IFile)
					inputFiles.add(resource);
			}
			List<IFile> rFilesToValidate = refFileValidator.getReferencedFile(inputFiles);
			if (rFilesToValidate != null && !rFilesToValidate.isEmpty())
				referencingFiles.addAll(rFilesToValidate);
			try {
				if (!referencingFiles.isEmpty())
					validateReferencingFiles(reporter, referencingFiles);
			} catch (Exception e) {
				ValidationPlugin.getPlugin().handleException(e);
			}
		}
	}

	private void getFileResourceDeltaInFolder(IResourceDelta delta, List<IResource> inputFiles) {
		IResourceDelta[] resourceDelta = delta.getAffectedChildren();
		for (int i = 0; i < resourceDelta.length; i++) {
			IResource resource = resourceDelta[i].getResource();
			if (resource instanceof IFile)inputFiles.add(resource);
			else if (resource instanceof IFolder)getFileResourceDeltaInFolder(resourceDelta[i], inputFiles);
		}
	}

	private void postValidateProject(WorkbenchReporter reporter, ReferencialFileValidator refFileValidator) {
		Set<ValidatorMetaData> set = ValidationRegistryReader.getReader().getValidatorMetaData(_project);
		for (ValidatorMetaData data : set) {
			List<String> filters = data.getNameFilters();
			List<IFile> files = getAllFilesForFilter(filters);
			if (!files.isEmpty()) {
				List<IFile> fileForValidation = refFileValidator.getReferencedFile(files);
				try {
					validateReferencingFiles(reporter, fileForValidation);
				} catch (Exception e) {
					ValidationPlugin.getPlugin().handleException(e);
				}
			}
		}
	}

	private List<IFile> getAllFilesForFilter(List<String> filters) {
		if (!filters.isEmpty()) {
			List<IFile> allProjectFiles = ReferencialFileValidatorHelper.getAllProjectFiles(_project);
			List<IFile> filterFiles = new ArrayList<IFile>();
			for (String fileName : filters) {
				if (fileName == null)continue;
				
				for (IFile projectFile : allProjectFiles) {
					if (fileName.charAt(0) == '*') {
						String extName = fileName.substring(2, fileName.length());
						String ext = projectFile.getFileExtension();
						if (ext != null && ext.equals(extName))filterFiles.add(projectFile);
					} else if (fileName.equals(projectFile.getName()))filterFiles.add(projectFile);
				}
			}
			return filterFiles;
		}
		return new LinkedList<IFile>();
	}

	private void validateReferencingFiles(IReporter reporter, List<IFile> referencingFiles) throws Exception {
		Set<IFile> validatedFiles = new HashSet<IFile>();
		for (IFile refFile : referencingFiles) {
			if (!validatedFiles.contains(refFile)) {
				IResource resource = refFile.getParent();
				IProject project = null;
				if (resource != null && !(resource instanceof IProject))
					project = getProjectContainer(resource);
				else
					project = (IProject) resource;
				if (project != null) {
					Set<ValidatorMetaData> set = ValidationRegistryReader.getReader().getValidatorMetaData(project);
					for (ValidatorMetaData data : set) {
						if (data.isApplicableTo(refFile)) {
							IValidator validator = data.getValidator();
							validator.validate(data.getHelper(project),reporter);
							validatedFiles.add(refFile);
						}
					}
				}
			}
		}
	}

	private IProject getProjectContainer(IResource resource) {
		IResource pResource = resource.getParent();
		if (!(pResource instanceof IProject))
			return getProjectContainer(pResource);
		return (IProject) pResource;
	}

	protected void preValidate(WorkbenchReporter reporter) throws CoreException, OperationCanceledException {
		// Load the input.
		getFileDeltas(reporter.getProgressMonitor());
	}

	/**
	 * Iterate over all of the enabled validators and run the thread-safe validators in a background
	 * thread, and the not-thread-safe validators in this thread.
	 */
	protected void validate(WorkbenchReporter reporter) throws OperationCanceledException {
		if (reporter == null)return;
		checkCanceled(reporter);
		reporter.getProgressMonitor().beginTask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_PROGRESSMONITOR_TITLE), getUnitsOfWork());
		IValidator validator = null;
		Iterator<ValidatorMetaData> iterator = null;
		IFileDelta[] delta = null;
		
		Set<ValidatorMetaData> jobValidators = new HashSet<ValidatorMetaData>();
		Set<ValidatorMetaData> validators = new HashSet<ValidatorMetaData>();
				
		for(ValidatorMetaData vmd : getEnabledValidators()){
			IValidator valInstance = null;
			try {
				valInstance = vmd.getValidator();
			} 
			catch (InstantiationException e1) {
				if(!ValidatorManager.getManager().getProblemValidators().contains(vmd)) {
					ValidatorManager.getManager().getProblemValidators().add(vmd);
					System.out.println(e1.getMessage());
				}
			}
			
			if( isFork() && (valInstance != null) && valInstance instanceof IValidatorJob ){
				try {
					delta = getFileDeltas(reporter.getProgressMonitor(), vmd);
				} catch (CoreException e) {
					e.printStackTrace();
				}
				boolean willRun = (isForce() || isValidationNecessary(vmd, delta));
				if( willRun )jobValidators.add( vmd );
			}
			else if (valInstance != null){
				validators.add( vmd );
			}
		}
		if( jobValidators.size() > 0 ){
			launchJobs( jobValidators, reporter );
		}
				
		ValidatorMetaData currentVmd = null;
		try {
			for (ValidatorMetaData vmd : validators) {
				currentVmd = vmd;
				// Is validation about to be run on this validator?
				// Validation will run either if this operation forces regardless
				// of need, or if the validator was not run automatically.
				// If validation is not about to be run, then don't activate
				// the plug-in
				try {
					delta = getFileDeltas(reporter.getProgressMonitor(), vmd);
					boolean willRun = (isForce() || isValidationNecessary(vmd, delta));
					if (Tracing.isTraceV1()) {
						StringBuffer buffer = new StringBuffer();
						buffer.append("ValidationOperation-01: will run? "); //$NON-NLS-1$
						buffer.append(willRun);
						buffer.append("  "); //$NON-NLS-1$
						buffer.append("is force? "); //$NON-NLS-1$
						buffer.append(isForce());
						buffer.append("  "); //$NON-NLS-1$
						buffer.append("isAutoBuild? "); //$NON-NLS-1$
						buffer.append(_isAutoBuild);
						buffer.append("  "); //$NON-NLS-1$
						buffer.append("isAutoValidate? "); //$NON-NLS-1$
						buffer.append("  "); //$NON-NLS-1$
						buffer.append("isIncremental? "); //$NON-NLS-1$
						buffer.append(vmd.isIncremental());
						buffer.append("  "); //$NON-NLS-1$
						if (isFullValidate()) {
							buffer.append("EVERYTHING"); //$NON-NLS-1$
						} else {
							if (delta.length == 0) {
								buffer.append("NOTHING"); //$NON-NLS-1$
							} else {
								buffer.append(getDeltaAsString(delta));
							}
						}
						Tracing.log(buffer);
					}
					if (!willRun) {
						continue;
					}
				} catch (CoreException e) {
					ValidationPlugin.getPlugin().handleException(e);
					String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
					reporter.displaySubtask(mssg);
					continue;
				}
				try {
					context = vmd.getHelper(getProject());
					initValidateContext(delta);
					validator = vmd.getValidator();
					
					checkCanceled(reporter);
					
				} catch (InstantiationException e) {
					// Remove the vmd from the reader's list
					ValidationRegistryReader.getReader().disableValidator(vmd);
					ValidationPlugin.getPlugin().handleException(e);
					continue;
				}
				
//				if (isFork() && vmd.isAsync()) {
//					// Don't appear to run in the foreground by sending
//					// progress to the IProgressMonitor in the
//					// WorkbenchMonitor. Suppress the status messages by
//					// changing the IProgressMonitor to a
//					// NullProgressMonitor.
//					VThreadManager.getManager().queue(wrapInRunnable(nullReporter, validator, vmd,(WorkbenchContext)getContext(),delta, iterator));
//				} else {
//					internalValidate(reporter, validator, vmd, context, delta);
//				}
				internalValidate(reporter, validator, vmd, context, delta);
			}
		} 
		catch (OperationCanceledException exc) {
			handleOperationCancelledValidateException(reporter, validator, currentVmd, iterator, exc);
		} 
		finally {
			releaseCachedMaps();
		}
	}

	private void releaseCachedMaps() {
		ValidationRegistryReader.getReader().clearCachedMaps();
		IProjectValidationHelper helper = ValidationHelperRegistryReader.getInstance().getValidationHelper();
		if (helper != null)
			helper.disposeInstance();
	}

	private void initValidateContext(IFileDelta[] delta) {
		 if (context instanceof WorkbenchContext) {
			 ((WorkbenchContext)context).setValidationFileURIs(new ArrayList<String>());
			 for(IFileDelta file : delta) {
				 if(file.getDeltaType() != IFileDelta.DELETED ) {
					 ((WorkbenchContext)context).getValidationFileURIs().add(file.getFileName());
				 }
			 } 
		}
	}

	/**
	 * @param reporter
	 * @param validator
	 * @param vmd
	 * @param iterator
	 * @param logger
	 * @param exc
	 */
	private void handleOperationCancelledValidateException(WorkbenchReporter reporter, IValidator validator, 
		ValidatorMetaData vmd, Iterator<ValidatorMetaData> iterator, OperationCanceledException exc) {
		/*
		 * If the user terminates validation (i.e., presses "cancel" on the progress monitor) before
		 * the validation completes, perform clean up on each configured enabled validator.
		 * 
		 * To clean up, several steps are performed: 1. call <code></code> on each configured
		 * enabled validator, so that each validator can perform cleanup that it knows is necessary.
		 * 2. remove all tasks that this validator has added to the task list 3. add another task to
		 * the task list to say that validation, using this validator on this project, was
		 * terminated.
		 * 
		 * Steps 2 and 3 are done so that it's clear what has, and has not, been validated. If these
		 * steps weren't performed, validation could be done on some items in the project, but not
		 * others; and the user could mistakenly believe that those are the only problems with the
		 * project. Unless the user knows that a full verification needs to be done, he/she could
		 * continue to rely on automatic verification, and never know that there are problems with a
		 * resource which hasn't been validated.
		 */
		reporter.displaySubtask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_CLEANUP, new String[]{vmd.getValidatorDisplayName()}));
		reporter.removeAllMessages(validator);
		addCancelTask(vmd);
		reporter.displaySubtask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED, new String[]{getProject().getName(), vmd.getValidatorDisplayName()}));
		while (iterator.hasNext()) {
			vmd = (ValidatorMetaData) iterator.next();
			try {
				validator = vmd.getValidator();
			} catch (InstantiationException exc2) {
				// Remove the vmd from the reader's list
				ValidationRegistryReader.getReader().disableValidator(vmd);
				ValidationPlugin.getPlugin().handleException(exc2);
				continue;
			}
			reporter.displaySubtask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_CLEANUP, new String[]{vmd.getValidatorDisplayName()}));
			reporter.removeAllMessages(validator);
			addCancelTask(vmd);
			reporter.displaySubtask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED, new String[]{getProject().getName(), vmd.getValidatorDisplayName()}));
		}
		throw exc; // propagate the exception up to the framework so that
		// the framework can display the correct "canceled"
		// message in the dialog

	}

	/* package */
	void internalValidate(final WorkbenchReporter reporter, final IValidator validator, final ValidatorMetaData vmd,final IWorkbenchContext aContext, final IFileDelta[] delta) throws OperationCanceledException {
		try {
			checkCanceled(reporter);
			removeOldMessages(reporter, validator, vmd, delta);
			// Do NOT check if the message limit is exceeded before launching
			// the validator.
			// Even if the limit is exceeded when the messages are removed from
			// the delta
			// files, it could be that the validator itself will remove
			// messages before
			// proceeding. Let the validator run so that it can remove messages
			// if it
			// needs to, and if it tries to add a message when the limit is
			// exceeded, let
			// the WorkbenchReporter take care of it.
			launchValidator(reporter, validator, vmd, aContext, delta);
		} catch (OperationCanceledException exc) {
			// This is handled in the validate(WorkbenchReporter) method.
			throw exc;
		}catch (Exception e) {
			// If there is a problem with this particular validator, log the
			// error and continue with the next validator.
			// If a runtime exception has occurred, e.g. NullPointer or
			// ClassCast, display it with the "A runtime exception has occurred" message.
			// This will provide more information to the user when he/she calls Service.
			ValidationPlugin.getPlugin().handleException(e);
			String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(mssg);
			
			/*
			 The code  below  causes bundle not found exception since, the  bundle here is
			 validate_base and we  are  trying to load that bundle from the classloader of 
			 the Validator. 
			  
			String[] msgParm = {exc.getClass().getName(), vmd.getValidatorDisplayName(), (exc.getMessage() == null ? "" : exc.getMessage())}; //$NON-NLS-1$
			Message message = ValidationPlugin.getMessage();
			message.setSeverity(IMessage.NORMAL_SEVERITY);
			message.setId(ResourceConstants.VBF_EXC_RUNTIME);
			message.setParams(msgParm);
			reporter.addMessage(validator, message);
			*/
		} finally {
			// If user fixes problem, and limit exceeded, add "exceeded"
			// message, or
			// if limit not exceeded any more, remove "exceeded" message.
			//Message Limit is removed from the framework
			//ValidatorManager.getManager().checkMessageLimit(getProject(), true);
			reporter.getProgressMonitor().done();
		}
	}

	/**
	 * In order to allow validators to run, must first check if there's space for new markers. But
	 * the old markers must not prevent validation from running again (limit exceeded), so delete
	 * all of the old markers first, and then run validation.
	 */
	private final void removeOldMessages(WorkbenchReporter reporter, IValidator validator, ValidatorMetaData vmd, IFileDelta[] delta) {
		if (reporter == null) {
			return;
		}
		// If the validator has been enabled, remove the "cancel" task.
		// If the validator, on the last run, threw a Throwable, remove the
		// "internal error" task. (For the same reasons we remove the "cancel"
		// task.
		InternalValidatorManager.getManager().removeOperationTasks(getProject(), vmd);
		checkCanceled(reporter);
		try {
			// Check to see if a full build must be performed, or if a delta
			// build is to be performed, if there are files to verify for that
			// validator. (If it's delta, but there are no files, calling
			// validate on that validator starts a full build, instead of just
			// returning.)
			if (isFullValidate()) {
				String message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_START_REMOVING_OLD_MESSAGES, new String[]{vmd.getValidatorDisplayName(), getProject().getName()});
				reporter.displaySubtask(message);
				reporter.removeAllMessages(validator);
				message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_FINISH_REMOVING_OLD_MESSAGES, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
				reporter.displaySubtask(message);
			} else {
				// Don't need to check that there are deltas to validate
				// because that's already checked in isValidationNecessary
				String message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_START_REMOVING_OLD_MESSAGES, new String[]{vmd.getValidatorDisplayName(), getProject().getName()});
				reporter.displaySubtask(message);
				for (int i = 0; i < delta.length; i++) {
					WorkbenchFileDelta fd = (WorkbenchFileDelta) delta[i];
					if (fd.getDeltaType() != IFileDelta.DELETED) {
						// If the file has been deleted, eclipse erases all
						// markers on the file.
						// Also, when a resource doesn't exist,
						// WorkbenchReporter's getMessageResource()
						// returns the IProject, which means that removing the
						// messages from this
						// file removes all of this validator's messages on
						// this IProject (aix defect 206157)
						IResource resource = reporter.getMessageResource(validator, fd);
						if (fd.getObject().equals(fd.getResource())) {
							WorkbenchReporter.removeAllMessages(resource, validator); // remove
						} else {
							reporter.removeAllMessages(validator, fd.getObject());
						}
					}
				}
				message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_FINISH_REMOVING_OLD_MESSAGES, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
				reporter.displaySubtask(message);
			}
		} catch (OperationCanceledException exc) {
			throw exc;
		} catch (Exception e) {
			ValidationPlugin.getPlugin().handleException(e);
			String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(mssg);
			return;
		}
	}

	/**
	 * Whether a full verification or a delta verification is in progress, both will call this
	 * method to process the resource. This method calls the current Validator to filter the
	 * resource (i.e., this method returns if the resource fails the filter test).
	 * <code>process</code> also sends output to the <code>IProgressMonitor</code>, and calls
	 * the current Validator to validate the resource.
	 * 
	 * To process a resource, there are several steps: 1. check if the resource is registered for
	 * this validator (i.e., the validator has either specified it in a filter, or has not filtered
	 * it out explicitly) 2. call <code>isValidationSource</code> on the current validator with
	 * the current resource. This method performs further filtering by the Validator itself, in
	 * addition to the static filtering done by the framework, based on the information in
	 * plugin.xml. 3. If the resource passes both filters, call <code>validate</code> on the
	 * validator, with the resource. 4. When complete (either by failing to pass a filter, or by the
	 * completion of the <code>validate</code>), increment the IProgressMonitor's status by one
	 * (i.e., one resource has been processed.)
	 */
	private final void launchValidator(WorkbenchReporter reporter, IValidator validator, ValidatorMetaData vmd, IWorkbenchContext helper, IFileDelta[] delta) {
		if (reporter == null)return;
		checkCanceled(reporter);
		// Check to see if a full build must be performed, or if a delta
		// build is to be performed, if there are files to verify for that
		// validator. (If it's delta, but there are no files, calling
		// validate on that validator starts a full build, instead of just
		// returning.)
		try {
			// Validate the resource; this step will add errors/warnings to the
			// task list, and remove errors/warnings from the task list.
			if (helper instanceof WorkbenchContext) {
				// Initialize the "loadRuleGroup" method with the group of rules
				// which the validator should validate.
				((WorkbenchContext) helper).setRuleGroup(getRuleGroup());
			}
			String message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_STARTING_VALIDATION, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(message);
			if (Tracing.isLogging()) {
				// This internal "launched validators" value is used only in tests.
				getLaunchedValidators().add(vmd);
			}
			//initValidateContext(delta);
			ValidatorLauncher.getLauncher().start(helper, validator, reporter);
			//TODO GRK determine if timing info should be added here
//			if (logger.isLoggingLevel(Level.INFO)) {
//				TimeEntry entry = ValidationPlugin.getTimeEntry();
//				entry.setSourceID("ValidationOperation.launchValidator"); //$NON-NLS-1$
//				entry.setProjectName(getProject().getName());
//				entry.setToolName(vmd.getValidatorUniqueName());
//				entry.setElapsedTime(finish - start);
//				if (logger.isLoggingLevel(Level.FINE)) {
//					StringBuffer buffer = new StringBuffer();
//					if (isFullValidate()) {
//						buffer.append("EVERYTHING"); //$NON-NLS-1$
//					} else {
//						if (delta.length == 0) {
//							buffer.append("NOTHING"); //$NON-NLS-1$
//						} else {
//							buffer.append(getDeltaAsString(delta));
//						}
//					}
//					entry.setDetails(buffer.toString());
//				}
//				logger.write(Level.INFO, entry);
//			}
			message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(message);
		} catch (OperationCanceledException exc) {
			throw exc;
		} catch (ValidationException exc) {
			// First, see if a validator just caught all Throwables and
			// accidentally wrapped a MessageLimitException instead of
			// propagating it.
			if (exc.getAssociatedException() != null) {
				if (exc.getAssociatedException() instanceof ValidationException) {
					ValidationException vexc = (ValidationException) exc.getAssociatedException();
					vexc.setClassLoader(validator.getClass().getClassLoader()); // first,
					// set the class loader, so that the exception's getMessage() method
					// can retrieve the resource bundle
				}
			}
			// If there is a problem with this particular validator, log the
			// error and continue with the next validator.
			exc.setClassLoader(validator.getClass().getClassLoader()); // first,
			ValidationPlugin.getPlugin().handleException(exc);
			ValidationPlugin.getPlugin().handleException(exc.getAssociatedException());
			String message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(message);
			if (exc.getAssociatedMessage() != null) {
				reporter.addMessage(validator, exc.getAssociatedMessage());
			}
		} catch (Exception e) {
			ValidationPlugin.getPlugin().handleException(e);
			String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(mssg);
			
			/*
			 The code  below  causes bundle not found exception since, the  bundle here is
			 validate_base and we  are  trying to load that bundle from the classloader of 
			 the Validator. 
			 
			String[] msgParm = {exc.getClass().getName(), vmd.getValidatorDisplayName(), (exc.getMessage() == null ? "" : exc.getMessage())}; //$NON-NLS-1$
			Message message = ValidationPlugin.getMessage();
			message.setSeverity(IMessage.NORMAL_SEVERITY);
			message.setId(ResourceConstants.VBF_EXC_RUNTIME);
			message.setParams(msgParm);
			reporter.addMessage(validator, message);
			*/
			
		} finally {
			try {
				validator.cleanup(reporter);
			} catch (OperationCanceledException e) {
				throw e;
			} catch (Exception e) {
				ValidationPlugin.getPlugin().handleException(e);
				return;
			}
			try {
				helper.cleanup(reporter);
			} catch (OperationCanceledException e) {
				throw e;
			} catch (Exception e) {
				ValidationPlugin.getPlugin().handleException(e);
				return;
			} finally {
				// Now that cleanup has been called, set the project to null.
				// This project's
				// resources have been freed so this project should also be
				// cleared on the helper.
				// If it isn't set to null, then the next time that the helper
				// is retrieved from
				// the ValidatorMetaData, the resources allocated for this
				// project, in the
				// helper's initialize method, will not be reallocated if the
				// project is the same.
				helper.setProject(null);
			}
			// Tell the progress monitor that we've completed n units of work
			// (i.e., n resources validated by one validator).
			reporter.getProgressMonitor().worked(((delta == null) ? 1 : delta.length));
		}
	}

//	private Runnable wrapInRunnable(final WorkbenchReporter reporter, final IValidator validator, final ValidatorMetaData vmd, final IWorkbenchContext helper, final IFileDelta[] delta, final Iterator iterator) {
//		// Need to create a new Runnable each time because several Runnable
//		// instances may exist at the same time.
//		Runnable runnable = new ProjectRunnable(reporter, validator, vmd, helper, delta, iterator);
//		return runnable;
//	}

	/*
	 * // For convenience, keep this method in the class but commented out. // When async needs to
	 * be tested, this method may be needed again. private static void debug(String prefix,
	 * IWorkbenchContext helper) { IProject hProject = helper.getProject(); System.err.println(prefix +
	 * "Start ValidationOperation "+Thread.currentThread().getName() + "::" + hProject.getName());
	 * if( Thread.currentThread().getName().equals("ValidationThread") &&
	 * (hProject.getName().indexOf("noFork") > -1)) { Thread.dumpStack(); } else
	 * if((!Thread.currentThread().getName().equals("ValidationThread")) &&
	 * (hProject.getName().indexOf("fork") > -1)) { Thread.dumpStack(); } System.err.println(prefix +
	 * "End ValidationOperation"); }
	 */
	public class ProjectRunnable implements Runnable {
		private WorkbenchReporter _reporter;
		private IValidator _validator;
		private ValidatorMetaData _vmd;
		private IFileDelta[] _delta;

		public ProjectRunnable(WorkbenchReporter reporter, IValidator validator, 
			ValidatorMetaData vmd, IWorkbenchContext helper, IFileDelta[] delta, Iterator iterator) {
			_reporter = reporter;
			_validator = validator;
			_vmd = vmd;
			_delta = delta;
		}

		public void run() {
			try {
				internalValidate(_reporter, _validator, _vmd, context,_delta);
			} catch (OperationCanceledException exc) {
				// User can't cancel a job in a background thread, so ignore this exception.
			}
		}

		public IProject getProject() {
			return _reporter.getProject();
		}
	}

	/**
	 * @return Returns the context.
	 */
	public IValidationContext getContext() {
		return context;
	}

	/**
	 * @param context The context to set.
	 */
	public void setContext(IWorkbenchContext context) {
		this.context = context;
	}
	
	void launchJobs(Set<ValidatorMetaData> validators, final WorkbenchReporter reporter) throws OperationCanceledException{
		
		IValidator validator = null;
		IFileDelta[] delta = null;
		IWorkbenchContext workbenchcontext = null;
		
		for (ValidatorMetaData vmd : validators) {
			checkCanceled(reporter);
			
			try {
				delta = getFileDeltas(reporter.getProgressMonitor(), vmd);
				boolean willRun = (isForce() || isValidationNecessary(vmd, delta));
				if (!willRun)continue;

			} catch (CoreException e) {
				ValidationPlugin.getPlugin().handleException(e);
				String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
				reporter.displaySubtask(mssg);
				continue;
			}
			
			try {
				validator = vmd.createValidator();
				workbenchcontext = vmd.createHelper( getProject() );
				initValidateContext( delta, workbenchcontext );
				vmd.addHelper((IValidatorJob)validator, workbenchcontext);				
				checkCanceled(reporter);
				
			} catch (InstantiationException e) {
				// Remove the vmd from the reader's list
				ValidationRegistryReader.getReader().disableValidator(vmd);
				ValidationPlugin.getPlugin().handleException(e);
				continue;
			}
			
			try {
				checkCanceled(reporter);
				removeOldMessages(reporter, validator, vmd, delta);
				
				if( validator instanceof IValidatorJob ){
					launchValidatorJob( reporter, (IValidatorJob)validator, vmd, workbenchcontext, delta);
				}

				
			} catch (OperationCanceledException exc) {
				throw exc;

			} catch (Exception e) {
				ValidationPlugin.getPlugin().handleException(e);
				String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
				reporter.displaySubtask(mssg);
			} catch (Error e) {
				ValidationPlugin.getPlugin().handleException(e);
				String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
				reporter.displaySubtask(mssg);
				throw e;
			} finally {
				// If user fixes problem, and limit exceeded, add "exceeded"
				// message, or if limit not exceeded any more, remove "exceeded" message.
				reporter.getProgressMonitor().done();
			}
		}
	}
		
	private void initValidateContext(IFileDelta[] delta, IWorkbenchContext context ) {
		 if (context instanceof WorkbenchContext) {
			 ((WorkbenchContext)context).setValidationFileURIs(new ArrayList<String>());
			 for(IFileDelta file : delta) {
				 if(file.getDeltaType() != IFileDelta.DELETED ) {
					 ((WorkbenchContext)context).getValidationFileURIs().add(file.getFileName());
				 }
			 } 
		}
	}
						
	private final void launchValidatorJob(WorkbenchReporter reporter,
		IValidatorJob validator, ValidatorMetaData vmd, IWorkbenchContext helper, IFileDelta[] delta) {
		
		if (reporter == null)return;
		checkCanceled(reporter);

		if (helper instanceof WorkbenchContext) {
			((WorkbenchContext) helper).setRuleGroup(getRuleGroup());
		}
		if (Tracing.isLogging()) {
			// This internal "launched validators" value is used only in tests.
			getLaunchedValidators().add(vmd);
		}
		
		ValidatorJob validatorjob = new ValidatorJob( validator, vmd.getValidatorDisplayName(), 
			vmd.getValidatorUniqueName(), helper.getProject(), helper );

		ISchedulingRule schedulingRule = validator.getSchedulingRule(helper);
		validatorjob.setRule( schedulingRule );		
		QualifiedName validatorKey = new QualifiedName(null, "Validator"); //$NON-NLS-1$
		validatorjob.setProperty( validatorKey, validator );
		validatorjob.addJobChangeListener(
			new JobChangeAdapter(){
				
				public void done(IJobChangeEvent event){
					Job job = event.getJob();
					QualifiedName validatorKey = new QualifiedName(null, "Validator"); //$NON-NLS-1$
					IValidatorJob validator = (IValidatorJob)job.getProperty( validatorKey );
					ValidatorManager mgr = ValidatorManager.getManager();
					final List<MessageInfo> list = mgr.getMessages(validator);							
					
					IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
					    public void run(IProgressMonitor monitor) throws CoreException {

							for(MessageInfo info : list){
								try {								
									TaskListUtility.addTask( info.getMessageOwnerId(), info.getResource(),
										info.getLocation(), info.getMsg().getId(), info.getText(),
										info.getMsg().getSeverity(),
										info.getMarkerId(),
										info.getTargetObjectName(),
										info.getMsg().getGroupName(),
										info.getMsg().getOffset(),
										info.getMsg().getLength());								
								} catch (CoreException e) {
									ValidationPlugin.getPlugin().handleException(e);
								}										
							}
					    }
					};
					try {
						
						ResourcesPlugin.getWorkspace().run(runnable, null, IWorkspace.AVOID_UPDATE, null);
					} catch (CoreException e) {
					   e.printStackTrace();
					}
					mgr.clearMessages( validator );
					validator = null;
				}
			}
		);
		validatorjob.setPriority(Job.DECORATE);
		launcherJob.addValidationJob(validatorjob);
	}
		
}
