/*******************************************************************************
 * Copyright (c) 2001, 2004 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.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;

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.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jem.util.logger.LogEntry;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.wst.common.frameworks.internal.operations.IHeadlessRunnableWithProgress;
import org.eclipse.wst.validation.core.IFileDelta;
import org.eclipse.wst.validation.core.IMessage;
import org.eclipse.wst.validation.core.IReporter;
import org.eclipse.wst.validation.core.IValidator;
import org.eclipse.wst.validation.core.MessageLimitException;
import org.eclipse.wst.validation.core.ValidationException;
import org.eclipse.wst.validation.internal.FilterUtil;
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.TimeEntry;
import org.eclipse.wst.validation.internal.VThreadManager;
import org.eclipse.wst.validation.internal.ValidationRegistryReader;
import org.eclipse.wst.validation.internal.ValidatorMetaData;
import org.eclipse.wst.validation.plugin.ValidationPlugin;
import org.eclispe.wst.validation.internal.core.FileDelta;
import org.eclispe.wst.validation.internal.core.Message;
import org.eclispe.wst.validation.internal.core.ValidatorLauncher;

/**
 * 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.
 * 
 * This operation is not intended to be subclassed outside of the validation framework.
 */
public abstract class ValidationOperation implements IWorkspaceRunnable, IHeadlessRunnableWithProgress {
	public static final int NO_DELTA_CHANGE = -1; // Since IResourceConstants
	// doesn't have a "no delta"
	// flag, let this constant be
	// the flag.
	private static final String DELTA_AS_STRING = "IFileDelta[{0}] '{'{1}'}'"; //$NON-NLS-1$
	private static final String COMMA = ", "; //$NON-NLS-1$
	protected static final boolean DEFAULT_ASYNC = false; // For the deprecated
	// constructors, by
	// default the
	// operation will not
	// fork.
	protected static final boolean DEFAULT_FORCE = true; // By default, run the
	// operation whether
	// or not it needs to
	/**
	 * @deprecated Will be removed in Milestone 3. Use DEFAULT_ASYNC
	 */
	protected static final boolean DEFAULT_FORK = false; // @deprecated
	private IProject _project = null; // project to be validated
	private int _ruleGroup = RegistryConstants.ATT_RULE_GROUP_DEFAULT; // which
	// pass
	// should
	// the
	// validation
	// invoke
	private boolean _fork = DEFAULT_ASYNC; // do not fork the validation into a
	// different thread by default
	private Map _fileDeltas = null; // To reduce object creation,
	private IResourceDelta _delta = null;
	// 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 _enabledValidators = null;
	private boolean _force = DEFAULT_FORCE; // force this operation to run even
	// if it doesn't need to?
	private boolean _isFullValidate = false; // Run a full validation or an
	// incremental? (true = full)
	private Boolean _isAutoBuild = null; // Is the global auto-build preference
	// enabled?
	private Set _launchedValidators = null; // A list of the validators that

	// 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 String[]{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();
	}

	/**
	 * @deprecated Will be removed in Milestone 3.
	 */
	protected void terminateCleanup(WorkbenchReporter reporter) {
		Set enabledValidators = getEnabledValidators();
		Iterator iterator = enabledValidators.iterator();
		ValidatorMetaData vmd = null;
		try {
			while (iterator.hasNext()) {
				vmd = (ValidatorMetaData) iterator.next();
				reporter.displaySubtask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_CLEANUP, new String[]{vmd.getValidatorDisplayName()}));
				try {
					reporter.removeAllMessages(vmd.getValidator());
				} catch (InstantiationException exc) {
					// Remove the vmd from the reader's list
					ValidationRegistryReader.getReader().disableValidator(vmd);
					// Log the reason for the disabled validator
					final Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
					if (logger.isLoggingLevel(Level.SEVERE)) {
						LogEntry entry = ValidationPlugin.getLogEntry();
						entry.setSourceID("ValidationOperation::terminateCleanup"); //$NON-NLS-1$
						entry.setTargetException(exc);
						logger.write(Level.SEVERE, entry);
					}
					continue;
				}
				addCancelTask(vmd);
				reporter.displaySubtask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_VALIDATOR_TERMINATED, new String[]{getProject().getName(), vmd.getValidatorDisplayName()}));
			}
		} catch (MessageLimitException e) {
			ValidatorManager.getManager().addMessageLimitExceeded(getProject());
		}
	}

	/**
	 * @deprecated Will be removed in Milestone 3. Should not be called outside of the validation
	 *             framework.
	 */
	protected final void launchValidator(WorkbenchReporter reporter, ValidatorMetaData vmd, IWorkbenchHelper helper, IFileDelta[] delta) {
		if (reporter == null) {
			return;
		}
		checkCanceled(reporter);
		Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
		// 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 AWorkbenchHelper) {
				// Initialize the "loadRuleGroup" method with the group of
				// rules
				// which the validator should validate.
				((AWorkbenchHelper) helper).setRuleGroup(getRuleGroup());
			}
			long start = System.currentTimeMillis();
			String message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_STARTING_VALIDATION, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(message);
			ValidatorLauncher.getLauncher().start(helper, vmd.getValidator(), reporter, delta);
			if (logger.isLoggingLevel(Level.INFO)) {
				logValidationInfo(vmd, delta, logger, start);
			}
			message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(message);
		} catch (MessageLimitException exc) {
			throw exc;
		} catch (OperationCanceledException exc) {
			throw exc;
		} catch (ValidationException exc) {
			handleValidationExceptions(reporter, vmd, logger, exc);
		} catch (Throwable exc) {
			handleThrowables(reporter, vmd, logger, exc);
		} finally {
			try {
				vmd.getValidator().cleanup(reporter);
			} catch (MessageLimitException e) {
				throw e;
			} catch (OperationCanceledException e) {
				throw e;
			} catch (Throwable exc) {
				handleThrowables(reporter, vmd, logger, exc);
				return;
			}
			try {
				helper.cleanup(reporter);
			} catch (MessageLimitException e) {
				throw e;
			} catch (Throwable exc) {
				handleHelperCleanupExceptions(reporter, vmd, logger, exc);
				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.length); // One unit of
			// work = 1
			// (i.e., 1
			// resource)
		}
	}

	/**
	 * @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:
		//    1. auto-validation has run and the validator is incremental,
		//    2. There are no files for the validator to validate.
		// There are files to validate if this is a full validation or if the
		// validator filtered in some of the deltas.
		boolean autoValidateRan = false;
		if (_isAutoBuild != null) {
			// User set the autoBuild default, so check if validation is
			// necessary or not.
			autoValidateRan = ValidatorManager.getManager().isAutoValidate(getProject(), _isAutoBuild.booleanValue()) && vmd.isIncremental();
		}
		boolean hasFiles = (isFullValidate() || (delta.length > 0));
		return (!autoValidateRan && hasFiles);
	}

	/**
	 * 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 enabledValidators = getEnabledValidators();
		if ((enabledValidators == null) || (enabledValidators.size() == 0)) {
			return false;
		}
		if (isFullValidate()) {
			return true;
		}
		Iterator iterator = enabledValidators.iterator();
		while (iterator.hasNext()) {
			ValidatorMetaData vmd = (ValidatorMetaData) iterator.next();
			if (isValidationNecessary(vmd, getFileDeltas(monitor, vmd))) {
				return true;
			}
		}
		return false;
	}

	private Map getFileDeltas(IProgressMonitor monitor) throws CoreException {
		if (_fileDeltas == null) {
			loadFileDeltas(monitor);
		}
		return _fileDeltas;
	}

	private IFileDelta[] getFileDeltas(IProgressMonitor monitor, ValidatorMetaData vmd) throws CoreException {
		Set result = (Set) 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 IWorkbenchHelper 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 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 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 getLaunchedValidators() {
		if (_launchedValidators == null) {
			_launchedValidators = new HashSet();
		}
		return _launchedValidators;
	}

	protected void setEnabledValidators(Set 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();
		Iterator iterator = evmds.iterator();
		while (iterator.hasNext()) {
			ValidatorMetaData vmd = (ValidatorMetaData) iterator.next();
			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 {
		long start = System.currentTimeMillis();
		final Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
		try {
			// In order to check whether or not the monitor has been cancelled,
			// the monitor must not be null.
			if (progressMonitor == null) {
				return;
			}
			if (ValidatorManager.getManager().isSuspended(getProject())) {
				return;
			}
			if (!areValidatorsEnabled()) {
				// save some processing time...
				return;
			}
			if (ValidatorManager.getManager().getMaximumMessagesAllowed(getProject()) == 0) {
				// save some processing time
				return;
			}
			final WorkbenchReporter reporter = new WorkbenchReporter(getProject(), progressMonitor);

			try {
				// Periodically check if the user has cancelled the operation
				checkCanceled(reporter);
				preValidate(reporter);
				validate(reporter);
				validateReferencialFiles(reporter);
			} catch (CoreException exc) {
				if (logger.isLoggingLevel(Level.SEVERE)) {
					LogEntry entry = ValidationPlugin.getLogEntry();
					entry.setSourceID("ValidationOperation.run"); //$NON-NLS-1$
					entry.setTargetException(exc);
					logger.write(Level.SEVERE, entry);
				}
			}
		} finally {
			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);
			}
		}
	}

	/**
	 * @param reporter
	 */
	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);
				}
			}
		}
	}

	/**
	 * @param reporter
	 * @param referencialFileValidator
	 */
	private void refFileValidateFileDelta(WorkbenchReporter reporter, ReferencialFileValidator refFileValidator) {
		IResourceDelta[] resourceDelta = _delta.getAffectedChildren(IResourceDelta.ADDED | IResourceDelta.CHANGED | IResourceDelta.REMOVED);
		List inputFiles = new ArrayList();
		List referencingFiles = new ArrayList();
		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 rFilesToValidate = refFileValidator.getReferencedFile(inputFiles);
			if (rFilesToValidate != null && !rFilesToValidate.isEmpty())
				referencingFiles.addAll(rFilesToValidate);
			try {
				if (!referencingFiles.isEmpty())
					validateReferencingFiles(reporter, referencingFiles);
			} catch (Exception e) {
				Logger.getLogger().log(e);
			}
		}
	}

	/**
	 * @param delta
	 * @return
	 */
	private void getFileResourceDeltaInFolder(IResourceDelta delta, List 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);
		}
	}

	/**
	 * @param reporter
	 * @param referencialFileValidator
	 */
	private void postValidateProject(WorkbenchReporter reporter, ReferencialFileValidator refFileValidator) {
		Set set = ValidationRegistryReader.getReader().getValidatorMetaData(_project);
		Iterator it = set.iterator();
		while (it.hasNext()) {
			ValidatorMetaData data = (ValidatorMetaData) it.next();
			List filters = data.getNameFilters();
			List files = getAllFilesForFilter(filters);
			if (!files.isEmpty()) {
				List fileForValidation = refFileValidator.getReferencedFile(files);
				try {
					validateReferencingFiles(reporter, fileForValidation);
				} catch (Exception e) {
					Logger.getLogger().log(e);
				}
			}
		}
	}

	/**
	 * @param filters
	 * @return
	 */
	private List getAllFilesForFilter(List filters) {
		if (!filters.isEmpty()) {
			List allProjectFiles = ReferencialFileValidatorHelper.getAllProjectFiles(_project);
			List filterFiles = new ArrayList();
			for (int i = 0; i < filters.size(); i++) {
				String fileName = (String) filters.get(i);
				if (fileName == null)
					continue;
				for (int j = 0; j < allProjectFiles.size(); j++) {
					IFile projectFile = (IFile) allProjectFiles.get(j);
					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 Collections.EMPTY_LIST;
	}

	private void validateReferencingFiles(IReporter reporter, List referencingFiles) throws Exception {
		HashSet validatedFiles = new HashSet();
		for (int i = 0; i < referencingFiles.size(); i++) {
			IFile refFile = (IFile) referencingFiles.get(i);
			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 set = ValidationRegistryReader.getReader().getValidatorMetaData(project);
					IFileDelta[] changedfiles = new FileDelta[]{new WorkbenchFileDelta(refFile.getProjectRelativePath().toString(), IFileDelta.CHANGED, refFile)};
					Iterator it = set.iterator();
					while (it.hasNext()) {
						ValidatorMetaData data = (ValidatorMetaData) it.next();
						if (data.isApplicableTo(refFile)) {
							IValidator validator = data.getValidator();
							validator.validate(data.getHelper(project), reporter, changedfiles);
							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());
		IWorkbenchHelper helper = null;
		IValidator validator = null;
		ValidatorMetaData vmd = null;
		Iterator iterator = null;
		WorkbenchReporter nullReporter = new WorkbenchReporter(getProject(), new NullProgressMonitor());
		final Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
		IFileDelta[] delta = null;
		try {
			iterator = getEnabledValidators().iterator();
			// In order to allow validators to run, must first check if there's
			// space for new markers.
			// But we don't want the old markers to prevent validation from
			// running again, so delete all
			// of the old markers first, and then run validation.
			while (iterator.hasNext()) {
				vmd = (ValidatorMetaData) iterator.next();
				// 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 plugin
				try {
					delta = getFileDeltas(reporter.getProgressMonitor(), vmd);
					boolean willRun = (isForce() || isValidationNecessary(vmd, delta));
					if (logger.isLoggingLevel(Level.FINEST)) {
						TimeEntry entry = ValidationPlugin.getTimeEntry();
						entry.setSourceID("ValidationOperation.validate(WorkbenchReporter)"); //$NON-NLS-1$
						entry.setProjectName(getProject().getName());
						entry.setToolName(vmd.getValidatorUniqueName());
						entry.setElapsedTime(0);
						StringBuffer buffer = new StringBuffer();
						buffer.append("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$
						boolean autoBuild = (_isAutoBuild == null) ? ValidatorManager.getManager().isGlobalAutoBuildEnabled() : _isAutoBuild.booleanValue();
						buffer.append(ValidatorManager.getManager().isAutoValidate(getProject(), autoBuild));
						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));
							}
						}
						entry.setDetails(buffer.toString());
						logger.write(Level.FINEST, entry);
					}
					if (!willRun) {
						continue;
					}
				} catch (CoreException exc) {
					if (logger.isLoggingLevel(Level.SEVERE)) {
						LogEntry entry = ValidationPlugin.getLogEntry();
						entry.setSourceID("ValidationOperation.validate(WorkbenchReporter)"); //$NON-NLS-1$
						entry.setTargetException(exc);
						logger.write(Level.SEVERE, entry);
					}
					String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
					reporter.displaySubtask(mssg);
					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);
					continue;
				}
				try {
					helper = vmd.getHelper(getProject());
					validator = vmd.getValidator();
				} catch (InstantiationException exc) {
					// 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::validate(WorkbenchReporter)"); //$NON-NLS-1$
						entry.setTargetException(exc);
						logger.write(Level.SEVERE, entry);
					}
					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, helper, delta, iterator));
				} else {
					internalValidate(reporter, validator, vmd, helper, delta);
				}
			}
		} catch (OperationCanceledException exc) {
			handleOperationCancelledValidateException(reporter, validator, vmd, iterator, logger, exc);
		}
	}

	/**
	 * @param reporter
	 * @param validator
	 * @param vmd
	 * @param iterator
	 * @param logger
	 * @param exc
	 */
	private void handleOperationCancelledValidateException(WorkbenchReporter reporter, IValidator validator, ValidatorMetaData vmd, Iterator iterator, final Logger logger, 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);
				// Log the reason for the disabled validator
				if (logger.isLoggingLevel(Level.SEVERE)) {
					LogEntry entry = ValidationPlugin.getLogEntry();
					entry.setSourceID("ValidationOperation::validate(WorkbenchReporter)"); //$NON-NLS-1$
					entry.setTargetException(exc2);
					logger.write(Level.SEVERE, entry);
				}
				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 "cancelled"
		// message in the dialog

	}

	/* package */
	void internalValidate(final WorkbenchReporter reporter, final IValidator validator, final ValidatorMetaData vmd, final IWorkbenchHelper helper, final IFileDelta[] delta) throws OperationCanceledException {
		final Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
		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, helper, delta);
		} catch (OperationCanceledException exc) {
			// This is handled in the validate(WorkbenchReporter) method.
			throw exc;
		} catch (MessageLimitException exc) {
			// Let the finally block handle this case.
			// handleMessageLimit();
		} catch (Throwable exc) {
			// If there is a problem with this particular validator, log the
			// error and continue
			// with the next validator.
			// 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.internalValidate"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);
			}
			String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(mssg);
			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.
			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);
		Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
		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
							// all
							// messages
							// from
							// this
							// resource
						} 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 (Throwable exc) {
			// If there is a problem with this particular validator, log the
			// error and continue
			// with the next validator.
			// 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.validate(WorkbenchMonitor)"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);
			}
			String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(mssg);
			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);
			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, IWorkbenchHelper helper, IFileDelta[] delta) {
		if (reporter == null) {
			return;
		}
		checkCanceled(reporter);
		Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
		// 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 AWorkbenchHelper) {
				// Initialize the "loadRuleGroup" method with the group of
				// rules
				// which the validator should validate.
				((AWorkbenchHelper) helper).setRuleGroup(getRuleGroup());
			}
			long start = System.currentTimeMillis();
			String message = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_STARTING_VALIDATION, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(message);
			if (logger.isLoggingLevel(Level.FINEST)) {
				// This internal "launched validators" value is used only in
				// tests.
				getLaunchedValidators().add(vmd);
			}
			ValidatorLauncher.getLauncher().start(helper, validator, reporter, delta);
			long finish = System.currentTimeMillis();
			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 (MessageLimitException exc) {
			throw exc;
		} 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 MessageLimitException) {
					MessageLimitException mssgExc = (MessageLimitException) exc.getAssociatedException();
					throw mssgExc;
				} else 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,
			// set
			// the
			// class
			// loader,
			// so
			// that
			// the
			// exception's
			// getMessage()
			// method
			// can
			// retrieve
			// the
			// resource
			// bundle
			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) {
				reporter.addMessage(validator, exc.getAssociatedMessage());
			}
		} catch (Throwable exc) {
			// If there is a problem with this particular validator, log the
			// error and continue
			// with the next validator.
			// 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.validate(WorkbenchMonitor)"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);
			}
			String mssg = ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_ENDING_VALIDATION_ABNORMALLY, new String[]{getProject().getName(), vmd.getValidatorDisplayName()});
			reporter.displaySubtask(mssg);
			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 (MessageLimitException e) {
				throw e;
			} catch (OperationCanceledException e) {
				throw e;
			} catch (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(validator, message);
				} catch (MessageLimitException e) {
					throw e;
				}
				return;
			}
			try {
				helper.cleanup(reporter);
			} catch (MessageLimitException e) {
				throw e;
			} catch (OperationCanceledException e) {
				throw e;
			} catch (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(validator, message);
				} catch (MessageLimitException e) {
					throw 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)); // One
			// unit
			// of
			// work
			// = 1
			// (i.e.,
			// 1
			// resource)
		}
	}

	private Runnable wrapInRunnable(final WorkbenchReporter reporter, final IValidator validator, final ValidatorMetaData vmd, final IWorkbenchHelper 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,
	 * IWorkbenchHelper 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 = null;
		private IValidator _validator = null;
		private ValidatorMetaData _vmd = null;
		private IWorkbenchHelper _helper = null;
		private IFileDelta[] __delta = null;

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

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

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