[261526] More multi-threaded cleanup
diff --git a/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/preferences/ValidationPropertyPage.java b/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/preferences/ValidationPropertyPage.java
index 7324b51..3aa09f8 100644
--- a/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/preferences/ValidationPropertyPage.java
+++ b/plugins/org.eclipse.wst.validation.ui/vf2/org/eclipse/wst/validation/ui/internal/preferences/ValidationPropertyPage.java
@@ -68,6 +68,7 @@
 import org.eclipse.wst.validation.internal.ValManager;
 import org.eclipse.wst.validation.internal.ValPrefManagerProject;
 import org.eclipse.wst.validation.internal.ValidatorMetaData;
+import org.eclipse.wst.validation.internal.ValManager.UseProjectPreferences;
 import org.eclipse.wst.validation.internal.model.ProjectPreferences;
 import org.eclipse.wst.validation.internal.operations.ValidatorManager;
 import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
@@ -180,6 +181,9 @@
 		private Button			_addValidationBuilder;
 		private Table 			_validatorsTable;
 		private Validator[]		_validators;
+		
+		/** Number of things that may have changed. */
+		private int				_changes;
 
 		/**
 		 * This class is provided for the CheckboxTableViewer in the
@@ -263,7 +267,8 @@
 		}
 
 		public Composite createPage(Composite parent) throws InvocationTargetException {
-			_validators = copyValidators(ValManager.getDefault().getValidatorsConfiguredForProject(getProject(), false));
+			_validators = copyValidators(ValManager.getDefault()
+				.getValidatorsConfiguredForProject(getProject(), UseProjectPreferences.MustUse));
 
 			Composite validatorGroup = new Composite(parent, SWT.NONE);
 
@@ -399,6 +404,7 @@
 			_suspend.addSelectionListener(new SelectionAdapter() {
 				public void widgetSelected(SelectionEvent e) {
 					_suspend.setFocus();
+					_changes++;
 					enableDisableWidgets();
 					_validatorList.refresh();
 				}
@@ -511,11 +517,14 @@
 			_override.addSelectionListener(new SelectionAdapter() {
 				public void widgetSelected(SelectionEvent e) {
 					_override.setFocus();
+					_changes++;
 					ValManager vm = ValManager.getDefault();
 					if (vm.getGlobalPreferences().getOverride()){
-						IProject project = getProject();
-						_validators = copyValidators(vm.getValidatorsConfiguredForProject(project, _override.getSelection()));
-						_validatorList.setInput(_validators);
+//						IProject project = getProject();
+//						UseProjectPreferences useProject = UseProjectPreferences.Normal;
+//						if (_override.getSelection())useProject = UseProjectPreferences.MustUse;
+//						_validators = copyValidators(vm.getValidatorsConfiguredForProject(project, useProject));
+//						_validatorList.setInput(_validators);
 						enableDisableWidgets();
 						_validatorList.refresh();
 					}
@@ -568,16 +577,17 @@
 
 			switch (columnToEdit) {
 			case 1:
-				val.setManualValidation(!val.isManualValidation());
+				if (val.setManualValidation(!val.isManualValidation()))_changes++;
 				break;
 			case 2:
-				val.setBuildValidation(!val.isBuildValidation());
+				if (val.setBuildValidation(!val.isBuildValidation()))_changes++;
 				break;
 			case 3:
 				Validator.V2 v2 = val.asV2Validator();
 				if (v2 != null){
 					FilterDialog fd = new FilterDialog(_shell, val, getProject());
 					if (Window.OK == fd.open()){
+						_changes++;
 						val.become(fd.getValidator());
 					}
 				}
@@ -610,7 +620,10 @@
 			    dialog.create();
 			
 			    int result = dialog.open();
-		        if (result == Window.OK)gc.setDelegateUniqueName(vmd, dialog.getDelegateID());
+		        if (result == Window.OK){
+		        	_changes++;
+		        	gc.setDelegateUniqueName(vmd, dialog.getDelegateID());
+		        }
 			}
 			catch (InvocationTargetException e){
 				
@@ -645,19 +658,18 @@
 		public boolean performOk() throws InvocationTargetException {
 			
 			addBuilder();
+			if (_changes == 0)return true;
 			// [213631] this warning should only be shown if the user actually tried to override
 			// the validators
 			if (!ValManager.getDefault().getGlobalPreferences().getOverride() && _override.getSelection()){
-				MessageDialog.openWarning(_shell, ValUIMessages.Validation, 
-					ValUIMessages.ProjectOverridesNotAllowed);
+				MessageDialog.openWarning(_shell, ValUIMessages.Validation, ValUIMessages.ProjectOverridesNotAllowed);
 				return false;
 			}
 			updateV1ProjectSettings();
-			getProjectPreferences().setSuspend(_suspend.getSelection());
-			getProjectPreferences().setOverride(_override.getSelection());
 			IProject project = getProject();
+			ProjectPreferences pp = new ProjectPreferences(project, _override.getSelection(), _suspend.getSelection(), _validators);
 			ValPrefManagerProject vpm = new ValPrefManagerProject(project);
-			vpm.savePreferences(getProjectPreferences(), _validators);
+			vpm.savePreferences(pp);
 			return true;
 		}
 		
@@ -685,7 +697,9 @@
 		}
 
 		public boolean performDefaults() throws InvocationTargetException {
-			_validators = copyValidators(ValManager.getDefaultValidators(getProject()));
+			_validators = copyValidators(ValManager.getDefault()
+				.getValidatorsConfiguredForProject(getProject(), UseProjectPreferences.MustNotUse));
+			_changes++;
 			updateWidgetsForDefaults();
 			getDefaultsButton().setFocus();
 			return true;
@@ -701,8 +715,8 @@
 		private void setAllValidators(boolean bool) {
 			for (TableItem item : _validatorsTable.getItems()) {
 				Validator val = (Validator) item.getData();
-				val.setManualValidation(bool);
-				val.setBuildValidation(bool);
+				if (val.setManualValidation(bool))_changes++;
+				if (val.setBuildValidation(bool))_changes++;
 			}
 		}
 
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ConfigurationManager.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ConfigurationManager.java
index 0c0c0be..a2e370a 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ConfigurationManager.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ConfigurationManager.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2008 IBM Corporation and others.
+ * Copyright (c) 2001, 2009 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
@@ -15,6 +15,7 @@
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Preferences;
 import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
@@ -47,10 +48,7 @@
 			if (!marker.getType().equals(VALIDATION_MARKER))return null;
 
 			Object attrib = marker.getAttribute(VALIDATION_MARKER_OWNER);
-			if (attrib == null) {
-				// owner not set
-				return null;
-			}
+			if (attrib == null)return null;
 			return attrib.toString();
 		} catch (CoreException e) {
 			ValidationPlugin.getPlugin().handleException(e);
@@ -93,7 +91,7 @@
 	 * This method returns the global preferences for the workspace.
 	 */
 	public GlobalConfiguration getGlobalConfiguration() throws InvocationTargetException {
-		IWorkspaceRoot root = ValidationConfiguration.getRoot();
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
 		GlobalConfiguration gp = null;
 		try {
 			gp = (GlobalConfiguration) root.getSessionProperty(USER_PREFERENCE);
@@ -170,8 +168,7 @@
 		try {
 			if (isMigrated(project)) {
 				ProjectConfiguration prjp = ConfigurationManager.getManager().getProjectConfiguration(project);
-				if(!prjp.useGlobalPreference())
-					prjp.store();
+				if(!prjp.useGlobalPreference())prjp.store();
 			}
 		} catch (InvocationTargetException e) {
 			ValidationPlugin.getPlugin().handleException(e);
@@ -180,9 +177,17 @@
 		}
 	}
 
+	/**
+	 * @deprecated this method does not do anything.
+	 * @param project
+	 */
 	public void deleting(IProject project) {
 	}
 
+	/**
+	 * @deprecated this method does not do anything.
+	 * @param project
+	 */
 	public void opening(IProject project) {
 		// Do not load or migrate the project in this method; let the getConfiguration(IProject)
 		// method do that. Do not load the project before it's necessary.
@@ -193,9 +198,7 @@
 	 */
 	public boolean isGlobalMigrated() throws InvocationTargetException {
 		IWorkspaceRoot root = ValidationConfiguration.getRoot();
-		if (root == null) {
-			return false;
-		}
+		if (root == null)return false;
 
 		try {
 			GlobalConfiguration gp = (GlobalConfiguration) root.getSessionProperty(USER_PREFERENCE);
@@ -220,20 +223,17 @@
 	 * Return true if the given project has the current level of metadata, false otherwise.
 	 */
 	public boolean isMigrated(IProject project) throws InvocationTargetException {
-		if (project == null) {
-			return false;
-		}
+		if (project == null)return false;
+		
 		try {
 			if (project.isAccessible()) {
 				ProjectConfiguration prjp = (ProjectConfiguration) project.getSessionProperty(USER_PREFERENCE);
-				if (prjp != null) {
-					return prjp.isVersionCurrent();
-				}
+				if (prjp != null)return prjp.isVersionCurrent();
+				
 				String serializedPrjp = project.getPersistentProperty(USER_PREFERENCE);
 				if (serializedPrjp != null) {
 					prjp = new ProjectConfiguration(project);
-					prjp.getVersion(); // initialize the configuration's
-					// version attribute
+					prjp.getVersion(); 
 					return prjp.isVersionCurrent();
 				}
 			}
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/EventManager.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/EventManager.java
index 3c2ebff..d603b8d 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/EventManager.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/EventManager.java
@@ -80,7 +80,7 @@
 		signal(project, IProjectChangeListener.ProjectOpened);
 
 		// When the project is opened, check for any orphaned tasks or tasks whose owners need to be updated.
-		ConfigurationManager.getManager().opening(project);
+//		ConfigurationManager.getManager().opening(project);
 	}
 
 	public void closing(IProject project) {
@@ -163,7 +163,7 @@
 					}
 				}
 
-				ConfigurationManager.getManager().deleting(project);
+//				ConfigurationManager.getManager().deleting(project);
 			}
 		} catch (InvocationTargetException e) {
 			ValidationPlugin.getPlugin().handleException(e);
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/GlobalConfiguration.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/GlobalConfiguration.java
index 318de6d..20c044f 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/GlobalConfiguration.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/GlobalConfiguration.java
@@ -47,7 +47,7 @@
 	 * without persisting them (i.e., if the user presses Cancel then nothing needs to be done.)
 	 */
 	public GlobalConfiguration(GlobalConfiguration original) throws InvocationTargetException {
-		super();
+		super(original.getResource());
 		original.copyTo(this);
 	}
 
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ProjectConfiguration.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ProjectConfiguration.java
index a797e65..63407bf 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ProjectConfiguration.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ProjectConfiguration.java
@@ -48,22 +48,21 @@
 		// global list.
 		super(project, extractProjectValidators(convertToArray(ValidationRegistryReader.getReader().getAllValidators()), project));
 
-		// Can't put the call to load() and passivate() in the ValidationConfiguration constructor
-		// due
+		// Can't put the call to load() and passivate() in the ValidationConfiguration constructor due
 		// to the order of initialization.
-		//    1. First the ValidationConfiguration constructor is called, and that loads the stored
-		// values.
+		//    1. First the ValidationConfiguration constructor is called, and that loads the stored values.
 		//    2. Then this class's <init> method is called, and that initializes the "override" field
-		// to the default,
-		//       which may be different than the stored value.
+		//       to the default, which may be different than the stored value.
 	}
 
 	/**
 	 * This constructor is provided only for the Properties page, so that the page can store values
 	 * without persisting them (i.e., if the user presses Cancel then nothing needs to be done.)
+	 * 
+	 * @deprecated
 	 */
 	public ProjectConfiguration(ProjectConfiguration original) throws InvocationTargetException {
-		super();
+		super(original.getResource());
 		original.copyTo(this);
 	}
 
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidationConfiguration.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidationConfiguration.java
index 7f82711..74426e0 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidationConfiguration.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/ValidationConfiguration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2008 IBM Corporation and others.
+ * Copyright (c) 2001, 2009 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
@@ -42,7 +42,7 @@
  * property while the resource is open.
  */
 public abstract class ValidationConfiguration implements IPropertyChangeListener {
-	private IResource 	_resource;
+	private final IResource 	_resource;
 	private boolean 	disableAllValidation = getDisableAllValidation();
 	private String 		_version;
 	
@@ -161,8 +161,9 @@
 	public static IWorkspaceRoot getRoot() {
 		return ResourcesPlugin.getWorkspace().getRoot();
 	}
-
-	protected ValidationConfiguration() throws InvocationTargetException {
+	
+	protected ValidationConfiguration(IResource resource){
+		_resource = resource;
 	}
 
 	protected ValidationConfiguration(IResource resource, ValidatorMetaData[] validators) throws InvocationTargetException {
@@ -170,12 +171,8 @@
 			throw new InvocationTargetException(null, ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_NULLCREATE));
 		}
 
-		setResource(resource);
-		setValidators(validators);
-	}
-
-	private void setResource(IResource resource) {
 		_resource = resource;
+		setValidators(validators);
 	}
 	
 	public boolean isDisableAllValidation() throws InvocationTargetException {
@@ -467,6 +464,7 @@
 
 	/**
 	 * This preference has been migrated; change the version to the current version.
+	 * @deprecated dead code.
 	 */
 	public void markVersionCurrent() {
 		// The version should not be marked current until the migration is complete
@@ -817,7 +815,6 @@
 
 	protected void copyTo(ValidationConfiguration up) throws InvocationTargetException {
 		up.setVersion(getVersion());
-		up.setResource(getResource());
 		up.setValidators(getValidators());
 		up.setDisableAllValidation(isDisableAllValidation());
 		up.setEnabledValidators(getEnabledValidators());
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ManualValidatorsOperation.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ManualValidatorsOperation.java
index 4f22ced..03a0bf2 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ManualValidatorsOperation.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ManualValidatorsOperation.java
@@ -20,11 +20,13 @@
  * ValidationOperation, because some initialization of the validator, and handling of error
  * conditions, is done in the operation. The initialization is separated because some of the
  * information needed to initialize the validator (i.e., the project) isn't known until runtime.
- * 
+ * <p>
  * Instances of this operation run every enabled validator (both full and incremental) on the
  * project.
- * 
+ * </p>
+ * <p>
  * This operation is not intended to be subclassed outside of the validation framework.
+ * </p>
  */
 public class ManualValidatorsOperation extends ValidatorSubsetOperation {
 
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationOperation.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationOperation.java
index 75b76eb..176a83c 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationOperation.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationOperation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2008 IBM Corporation and others.
+ * Copyright (c) 2001, 2009 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
@@ -63,11 +63,12 @@
 import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;
 
 /**
- * Implemented Validators methods must not be called directly by anyone other than this class, since
+ * Validators 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.
+ * </p>
  */
 public abstract class ValidationOperation implements IWorkspaceRunnable, IHeadlessRunnableWithProgress {
 	// Since IResourceConstants don't have a "no delta" flag, let this constant be the flag.
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidatorManager.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidatorManager.java
index 86bbbf3..7cf398b 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidatorManager.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidatorManager.java
@@ -121,15 +121,10 @@
 		try {
 			ProjectConfiguration prjp = ConfigurationManager.getManager().getProjectConfiguration(project);
 			prjp.setDoesProjectOverride(true);
-			ValidatorMetaData vmd = ValidationRegistryReader.getReader()
-					.getValidatorMetaData(validatorId);
+			ValidatorMetaData vmd = ValidationRegistryReader.getReader().getValidatorMetaData(validatorId);
 			
-			if(manualValidation){
-				prjp.disableSingleManualValidator(vmd);
-			} 
-			if (buildValidation){
-				prjp.disableSingleBuildValidator(vmd);
-			}
+			if(manualValidation)prjp.disableSingleManualValidator(vmd);
+			if (buildValidation)prjp.disableSingleBuildValidator(vmd);
 			prjp.store();
 			
 		} catch (InvocationTargetException e) {
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationFramework.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationFramework.java
index 9f5fd4c..7687fab 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationFramework.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/ValidationFramework.java
@@ -49,6 +49,7 @@
 import org.eclipse.wst.validation.internal.ValType;
 import org.eclipse.wst.validation.internal.ValidationRunner;
 import org.eclipse.wst.validation.internal.ValidatorMetaData;
+import org.eclipse.wst.validation.internal.ValManager.UseProjectPreferences;
 import org.eclipse.wst.validation.internal.operations.ValidationBuilder;
 import org.eclipse.wst.validation.internal.operations.ValidatorManager;
 import org.eclipse.wst.validation.internal.operations.WorkbenchReporter;
@@ -290,7 +291,7 @@
 	 * @throws ProjectUnavailableError
 	 */
 	public Validator[] getValidatorsConfiguredForProject(IProject project) throws ProjectUnavailableError {
-		Validator[] orig = ValManager.getDefault().getValidatorsConfiguredForProject(project, false);
+		Validator[] orig = ValManager.getDefault().getValidatorsConfiguredForProject(project, UseProjectPreferences.Normal);
 		Validator[] copy = new Validator[orig.length];
 		for (int i=0; i<orig.length; i++)copy[i] = orig[i].copy();
 		return copy;
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java
index 0e9f544..05b6e72 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/Validator.java
@@ -529,16 +529,20 @@
 	 * Set whether this validator should be triggered as part of a manual validation.
 	 * 
 	 * @param manualValidation
+	 * @return true if the setting changed.
 	 */
-	public void setManualValidation(boolean manualValidation) {
-		setManualValidation2(manualValidation);
+	public boolean setManualValidation(boolean manualValidation) {
+		return setManualValidation2(manualValidation);
 	}
 	
-	protected final void setManualValidation2(boolean manualValidation) {
+	protected final boolean setManualValidation2(boolean manualValidation) {
+		boolean changed = false;
 		if (_manualValidation != manualValidation){
 			bumpChangeCountGlobal();
+			changed = true;
 			_manualValidation = manualValidation;
 		}
+		return changed;
 	}
 
 	/**
@@ -567,16 +571,20 @@
 	 * Set whether this validator should be triggered by the build process.
 	 * 
 	 * @param buildValidation
+	 * @return true if the setting changed.
 	 */
-	public void setBuildValidation(boolean buildValidation) {
-		setBuildValidation2(buildValidation);
+	public boolean setBuildValidation(boolean buildValidation) {
+		return setBuildValidation2(buildValidation);
 	}
 	
-	protected final void setBuildValidation2(boolean buildValidation) {
+	protected final boolean setBuildValidation2(boolean buildValidation) {
+		boolean changed = false;
 		if (_buildValidation != buildValidation){
 			bumpChangeCountGlobal();
+			changed = true;
 			_buildValidation = buildValidation;
 		}
+		return changed;
 	}
 
 	/**
@@ -700,15 +708,17 @@
 	}
 	
 	@Override
-	public void setBuildValidation(boolean buildValidation) {
-		super.setBuildValidation(buildValidation);
+	public boolean setBuildValidation(boolean buildValidation) {
+		boolean changed = super.setBuildValidation(buildValidation);
 		_vmd.setBuildValidation(buildValidation);
+		return changed;
 	}
 	
 	@Override
-	public void setManualValidation(boolean manualValidation) {
-		super.setManualValidation(manualValidation);
+	public boolean setManualValidation(boolean manualValidation) {
+		boolean changed = super.setManualValidation(manualValidation);
 		_vmd.setManualValidation(manualValidation);
+		return changed;
 	}
 
 	@Override
@@ -773,13 +783,13 @@
 		}
 		
 		@Override
-		public void setManualValidation(boolean bool) {
-			setManualValidation2(bool);
+		public boolean setManualValidation(boolean bool) {
+			return setManualValidation2(bool);
 		}
 		
 		@Override
-		public void setBuildValidation(boolean bool) {
-			setBuildValidation2(bool);
+		public boolean setBuildValidation(boolean bool) {
+			return setBuildValidation2(bool);
 		}
 		
 		@Override
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ExtensionValidators.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ExtensionValidators.java
index 5b74568..090f4af 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ExtensionValidators.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ExtensionValidators.java
@@ -12,6 +12,8 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.core.resources.IProject;
@@ -23,29 +25,26 @@
  * @author karasiuk
  *
  */
-public class ExtensionValidators {
+public final class ExtensionValidators {
 	private static ExtensionValidators _me;
 	
 	/** All the registered validators. The key is the validator id and the value is the validator. */
-	private Map<String, Validator> _map;
+	private final Map<String, Validator> _map;
 	
 	public synchronized static ExtensionValidators instance(){
 		if (_me == null){
 			_me = new ExtensionValidators();
-			_me.load();
 		}
 		return _me;
 	}
 
-	private ExtensionValidators(){};
-	
-	private void load() {
+	private ExtensionValidators(){
 		_map = new HashMap<String, Validator>(100);
 		for (Validator v : ValidatorExtensionReader.getDefault().process()){
 			_map.put(v.getId(), v);
-		}
+		}		
 	}
-
+	
 	/**
 	 * Answer all the v2 validators that have been defined by the extension point. This is the real
 	 * map (not a copy).
@@ -81,19 +80,31 @@
 		Map<String, Validator> map = new HashMap<String, Validator>();
 		map.putAll(_map);
 		
+		for (Validator v : getV1Validators(project))map.put(v.getId(), v);
+		
+		return map;
+	}
+	
+	/**
+	 * Answer the v1 validators that have been defined just on this project.
+	 * @param project
+	 * @return
+	 */
+	List<Validator> getV1Validators(IProject project){
+		List<Validator> list = new LinkedList<Validator>();
 		try {
 			ProjectConfiguration pc = new ProjectConfiguration(project);
 			pc.resetToDefault();
 			for (ValidatorMetaData vmd : pc.getValidators()){
 				Validator v = Validator.create(vmd, pc, project);
-				map.put(v.getId(), v);
+				list.add(v);
 			}
 		}
 		catch (InvocationTargetException e){
 			ValidationPlugin.getPlugin().handleException(e);
 		}
 
-		return map;
+		return list;
 	}
 
 }
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java
index ecd9317..3998019 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValManager.java
@@ -20,6 +20,8 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -63,32 +65,32 @@
  * @author karasiuk
  *
  */
-public class ValManager implements IValChangedListener, IFacetedProjectListener, IProjectChangeListener {
+public final class ValManager implements IValChangedListener, IFacetedProjectListener, IProjectChangeListener {
 	
 	/**
 	 * Projects may be allowed to override the global validation settings. If that is the case then those
 	 * project specific settings are saved here. If the key exists, but the value is null, then that
 	 * means that the project has been checked and it does not have any specific settings.
 	 */
-	private Map<IProject, ProjectPreferences> _projectPreferences = 
+	private final Map<IProject, ProjectPreferences> _projectPreferences = 
 		Collections.synchronizedMap(new HashMap<IProject, ProjectPreferences>(50));
 	
-	private AtomicReference<GlobalPreferences> _globalPreferences = new AtomicReference<GlobalPreferences>();
+	private final AtomicReference<GlobalPreferences> _globalPreferences = new AtomicReference<GlobalPreferences>();
 		
 	/**
 	 * This number increases each time any of the validation configurations change. It is used to determine
 	 * if information that we have cached in the ValProperty is stale or not. This starts off at zero, each time
 	 * the workbench is started.
 	 */
-	private AtomicInteger _configNumber = new AtomicInteger();
+	private final AtomicInteger _configNumber = new AtomicInteger();
 	
-	private ValidatorIdManager _idManager = new ValidatorIdManager();
-	
-	private ValidatorProjectManager _projectManager = new ValidatorProjectManager();
-	
+	private final ValidatorIdManager _idManager = new ValidatorIdManager();
+	private final ValidatorCache 	_cache = new ValidatorCache();
+		
 	private static final QualifiedName StatusBuild = new QualifiedName(ValidationPlugin.PLUGIN_ID, "sb"); //$NON-NLS-1$
 	private static final QualifiedName StatusManual = new QualifiedName(ValidationPlugin.PLUGIN_ID, "sm"); //$NON-NLS-1$
-			
+
+	
 	public static ValManager getDefault(){
 		return Singleton.valManager;
 	}
@@ -163,13 +165,38 @@
 	 *            project settings are used. Normal validation would set this to true.
 	 *            The properties page would set this to false.
 	 *            
-	 * @deprecated Use {@link #getValidators(IProject)} instead            
+	 * @deprecated Use {@link #getValidatorsNotCached(IProject)} instead            
 	 */
-	public synchronized Validator[] getValidators(IProject project, boolean respectOverrideSettings) throws ProjectUnavailableError {
+	public Validator[] getValidators(IProject project, boolean respectOverrideSettings) throws ProjectUnavailableError {
 		return getValidators(project);
 	}
 	
 	/**
+	 * Answer a cached copy of the the validators for a given project. This is a front end method, 
+	 * for the getValidatorsNotCached() method.
+	 * <p>
+	 * Individual projects may override the global validation preference
+	 * settings. If the project has it's own settings, then those validators are
+	 * returned via this method.
+	 * </p>
+	 * <p>
+	 * The following approach is used. For version 1 validators, the validator
+	 * is only returned if it is defined to operate on this project type. This
+	 * is the way that the previous version of the framework did it. For version
+	 * 2 validators, they are all returned.
+	 * </p>
+	 * 
+	 * @param project
+	 *            This may be null, in which case the global preferences are
+	 *            returned.
+	 * 
+	 * @return The validators in name sorted order.
+	 */
+	public Validator[] getValidators(IProject project) throws ProjectUnavailableError {
+		return _cache.getValidatorsCached(project);
+	}
+	
+	/**
 	 * Answer all the validators for the given project.
 	 * <p>
 	 * Individual projects may override the global validation preference
@@ -189,8 +216,8 @@
 	 * 
 	 * @return The validators in name sorted order.
 	 */
-	public synchronized Validator[] getValidators(IProject project) throws ProjectUnavailableError {
-		Map<String,Validator> v2Vals = getV2Validators(project, false);
+	private Validator[] getValidatorsNotCached(IProject project) throws ProjectUnavailableError {
+		Map<String,Validator> v2Vals = getV2Validators(project, UseProjectPreferences.Normal);
 		TreeSet<Validator> sorted = new TreeSet<Validator>();
 		sorted.addAll(v2Vals.values());
 		
@@ -221,7 +248,6 @@
 		sorted.toArray(vals);
 		return vals;
 	}
-	
 	/**
 	 * Validators can use project level settings (Project natures and facets) to
 	 * determine if they are applicable to the project or not.
@@ -235,22 +261,51 @@
 	 * @return The validators that are configured to run on this project based
 	 *         on the project level settings. These are the "live" validators, they are not copies.
 	 * @throws ProjectUnavailableError
+	 * 
+	 * @deprecated Use getValidatorsConfiguredForProject(IProject project, UseProjectPreferences useProject)
 	 */
 	public Validator[] getValidatorsConfiguredForProject(IProject project, boolean mustUseProjectSettings) throws ProjectUnavailableError {
-		Map<String,Validator> v2Vals = getV2Validators(project, mustUseProjectSettings);
+		UseProjectPreferences useProject = UseProjectPreferences.Normal;
+		return getValidatorsConfiguredForProject(project, useProject);
+	}
+	
+	/**
+	 * Validators can use project level settings (Project natures and facets) to
+	 * determine if they are applicable to the project or not.
+	 * 
+	 * @param project
+	 *            The project that the configuration is based on.
+	 * @param useProject
+	 *            Specifies how to use the project preferences. This can be used
+	 *            to force the project properties to be used. There is a case
+	 *            where the user has toggled the Enable project specific
+	 *            settings checkbox in the dialog, but has not yet committed the
+	 *            changes. This allows that setting to be passed through.
+	 * @return The validators that are configured to run on this project based
+	 *         on the project level settings. These are the "live" validators,
+	 *         they are not copies.
+	 * @throws ProjectUnavailableError
+	 */
+	public Validator[] getValidatorsConfiguredForProject(IProject project, UseProjectPreferences useProject) throws ProjectUnavailableError {
+		Map<String,Validator> v2Vals = getV2Validators(project, useProject);
 		TreeSet<Validator> sorted = new TreeSet<Validator>();
 		sorted.addAll(v2Vals.values());
 		
-		try {
-			ValidationConfiguration vc = ConfigurationManager.getManager().getProjectConfiguration(project);
-			ValidatorMetaData[] vmds = vc.getValidators();
-			for (ValidatorMetaData vmd : vmds) {
-				Validator v = Validator.create(vmd, vc, project);
-				sorted.add(v);
-			}
+		if (useProject == UseProjectPreferences.MustNotUse){
+			sorted.addAll(ExtensionValidators.instance().getV1Validators(project));
 		}
-		catch (InvocationTargetException e){
-			ValidationPlugin.getPlugin().handleException(e);
+		else {
+			try {
+				ValidationConfiguration vc = ConfigurationManager.getManager().getProjectConfiguration(project);
+				ValidatorMetaData[] vmds = vc.getValidators();
+				for (ValidatorMetaData vmd : vmds) {
+					Validator v = Validator.create(vmd, vc, project);
+					sorted.add(v);
+				}
+			}
+			catch (InvocationTargetException e){
+				ValidationPlugin.getPlugin().handleException(e);
+			}
 		}
 				
 		List<Validator> list = new LinkedList<Validator>();
@@ -276,27 +331,31 @@
 	 * @param project
 	 *            This may be null, in which case only the global preferences
 	 *            are used.
-	 * @param mustUseProjectSettings
-	 *            Force the project properties to be used. There is a case where the user has toggled the
-	 *            Enable project specific settings checkbox in the dialog, but has not yet committed the
+	 * @param useProject
+	 *            Specifies how to use the project preferences. This can be used
+	 *            to force the project properties to be used. There is a case
+	 *            where the user has toggled the Enable project specific
+	 *            settings checkbox in the dialog, but has not yet committed the
 	 *            changes. This allows that setting to be passed through.
 	 *            
 	 * @return
 	 */
-	private Map<String,Validator> getV2Validators(IProject project, boolean mustUseProjectSettings){
+	private Map<String,Validator> getV2Validators(IProject project, UseProjectPreferences useProject){
 		Map<String,Validator> extVals = ExtensionValidators.instance().getMapV2Copy();
 		try {
 			List<Validator> vals = ValPrefManagerGlobal.getDefault().getValidators();
 			for (Validator v : vals)extVals.put(v.getId(), v);
 			
-			if (mustUseProjectSettings || !mustUseGlobalValidators(project)){
-				//TODO should probably cache this vpm
-				ValPrefManagerProject vpm = new ValPrefManagerProject(project);
-				vals = vpm.getValidators(extVals);
-				for (Validator v : vals)extVals.put(v.getId(), v);
-				
-				for (Validator v : getProjectPreferences(project).getValidators())extVals.put(v.getId(), v);
-			}		
+			if (useProject != UseProjectPreferences.MustNotUse){
+				if (useProject == UseProjectPreferences.MustUse || !mustUseGlobalValidators(project)){
+					//TODO should probably cache this vpm
+					ValPrefManagerProject vpm = new ValPrefManagerProject(project);
+					vals = vpm.getValidators(extVals);
+					for (Validator v : vals)extVals.put(v.getId(), v);
+					
+					for (Validator v : getProjectPreferences(project).getValidators())extVals.put(v.getId(), v);
+				}	
+			}
 		}
 		catch (BackingStoreException e){
 			ValidationPlugin.getPlugin().handleException(e);
@@ -315,7 +374,7 @@
 	public boolean mustUseGlobalValidators(IProject project){
 		if (project == null)return true;
 		if (!getGlobalPreferences().getOverride())return true;
-		ProjectPreferences pp = getProjectPreferences2(project);
+		ProjectPreferences pp = _projectPreferences.get(project);
 		if (pp != null)return !pp.getOverride();
 		
 		ValPrefManagerProject vpm = new ValPrefManagerProject(project);
@@ -389,7 +448,7 @@
 		GlobalPreferences gp = getGlobalPreferences();
 		if (!gp.getOverride() || project == null)return gp.getDisableAllValidation();
 		
-		ProjectPreferences pp = getProjectPreferences2(project);
+		ProjectPreferences pp = _projectPreferences.get(project);
 		if (pp == null)return gp.getDisableAllValidation();
 		return pp.getSuspend();		
 	}
@@ -481,7 +540,8 @@
 	 */
 	private void configHasChanged(){
 		_configNumber.incrementAndGet();
-		_projectManager.reset();
+		ValidatorProjectManager.reset();
+		_cache.reset();
 	}
 		
 	/**
@@ -513,8 +573,12 @@
 		return changes;
 	}
 		
+	/**
+	 * Answer the project preferences for this project.
+	 * @param project The project, this may be null.
+	 */
 	public ProjectPreferences getProjectPreferences(IProject project) {
-		ProjectPreferences pp = getProjectPreferences2(project);
+		ProjectPreferences pp = _projectPreferences.get(project);
 		if (pp != null)return pp;
 		
 		/* hopefully we rarely get this far */
@@ -532,34 +596,22 @@
 		return pp;
 	}
 
-	
+	/**
+	 * 
+	 * @param project The project, this may be null.
+	 * @param baseValidators
+	 */
 	private ProjectPreferences getProjectPreferences(IProject project, Map<String, Validator> baseValidators) 
 		throws BackingStoreException {
-		if (_projectPreferences.containsKey(project)){
-			return _projectPreferences.get(project);
-		}
+		ProjectPreferences pp = _projectPreferences.get(project);
+		if (pp != null)return pp;
 		
 		ValPrefManagerProject vpm = new ValPrefManagerProject(project);
-		ProjectPreferences pp = new ProjectPreferences(project); 
-		vpm.loadProjectPreferences(pp, baseValidators);
+		pp = vpm.loadProjectPreferences(project, baseValidators);
 		_projectPreferences.put(project, pp);
 		return pp;		
 	}
-	
-	/**
-	 * Answer the project specific validation preferences from the cache
-	 * 
-	 * @param project
-	 * 
-	 * @return null if the project is not in the cache.
-	 */
-	private ProjectPreferences getProjectPreferences2(IProject project){
-		if (_projectPreferences.containsKey(project)){
-			return _projectPreferences.get(project);
-		}
-		return null;
-	}
-	
+		
 	/**
 	 * Restore all the validation defaults, as defined by the individual validators via the
 	 * validation extension point.
@@ -684,7 +736,7 @@
 		
 		for (Validator val : getValidators(project)){
 			if (monitor.isCanceled())return;
-			if (!_projectManager.shouldValidate(val, project, valType))continue;
+			if (!ValidatorProjectManager.get().shouldValidate(val, project, valType))continue;
 			if (operation.isSuspended(val, project))continue;
 			try {
 				visitor.visit(val, project, valType, operation, monitor);
@@ -736,7 +788,7 @@
 		ContentTypeWrapper ctw = new ContentTypeWrapper();
 		for (Validator val : getValidators(project)){
 			if (!monitor.isCanceled()) {
-				if (!_projectManager.shouldValidate(val, project, valType))continue;
+				if (!ValidatorProjectManager.get().shouldValidate(val, project, valType))continue;
 				if (Friend.shouldValidate(val, resource, valType, ctw)){
 					vp.getConfigSet().set(_idManager.getIndex(val.getId()));
 					// we do the suspend check after figuring out if it needs to be validated, because we save
@@ -844,8 +896,9 @@
 	 * @param project The project that has been opened, created, or had it's description change.
 	 */
 	public void projectChanged(IProject project){
-		_projectManager.change(project);
+		ValidatorProjectManager.reset();
 		_projectPreferences.remove(project);
+		_cache.reset(project);
 	}
 	
 	/**
@@ -855,8 +908,9 @@
 	 * 
 	 */
 	public void projectRemoved(IProject project){
-		_projectManager.remove(project);
+		ValidatorProjectManager.reset();
 		_projectPreferences.remove(project);
+		_cache.reset(project);
 	}
 	
 	private void putValProperty(ValProperty vp, IResource resource, ValType valType) {
@@ -914,11 +968,11 @@
 		}
 	}
 	
-	private class HasValidatorVisitor implements IResourceVisitor {
+	private final class HasValidatorVisitor implements IResourceVisitor {
 		
-		private boolean 	_hasValidator;
-		private boolean		_isManual;
-		private boolean		_isBuild;
+		private boolean 			_hasValidator;
+		private final boolean		_isManual;
+		private final boolean		_isBuild;
 		
 		public HasValidatorVisitor(boolean isManual, boolean isBuild){
 			_isManual = isManual;
@@ -951,13 +1005,13 @@
 	 * @author karasiuk
 	 *
 	 */
-	private static class ValidatorIdManager {
+	private final static class ValidatorIdManager {
 		
 		/**
 		 * Map validator id's to Integers. The integers correspond to bits in the ValProperty instances.
 		 */
-		private Map<String, Integer> _map = new HashMap<String, Integer>(100);
-		private Map<Integer, String> _reverseMap = new HashMap<Integer, String>(100);
+		private final Map<String, Integer> _map = new HashMap<String, Integer>(100);
+		private final Map<Integer, String> _reverseMap = new HashMap<Integer, String>(100);
 		
 		/** Next available bit. */
 		private int _next;
@@ -1011,14 +1065,59 @@
 	/**
 	 * This is used to keep track of which validators are enabled with which projects. We want to ensure
 	 * that we don't activate a validator (and it's plug-in) if it has nothing to validate in the workspace.
-	 * The ValManager keeps a single instance of this class. 
+	 * This is an immutable object.
 	 * @author karasiuk
 	 *
 	 */
-	private static class ValidatorProjectManager {
+	private final static class ValidatorProjectManager {
 		
-		private ValProjectMap _manual = new ValProjectMap(ValType.Manual);
-		private ValProjectMap _build = new ValProjectMap(ValType.Build);
+		private final static AtomicReference<ValidatorProjectManager> _me = new AtomicReference<ValidatorProjectManager>();
+		private final static AtomicInteger _counter = new AtomicInteger();
+		
+		private final ValProjectMap _manual = new ValProjectMap(ValType.Manual);
+		private final ValProjectMap _build = new ValProjectMap(ValType.Build);
+		private final int _sequence;
+		
+		/**
+		 * Answer the most current ValidatorProjectManager creating a new one if you have to.
+		 * @return
+		 */
+		public static ValidatorProjectManager get(){
+			ValidatorProjectManager vpm = _me.get();
+			if (vpm != null)return vpm;
+			
+			int next = _counter.incrementAndGet();
+			ValidatorProjectManager newVpm = null;
+			boolean looking = true;
+			while(looking){
+				vpm = _me.get();
+				if (vpm == null || next > vpm.getSequence()){
+					if (newVpm == null)newVpm = new ValidatorProjectManager(next);
+					if (_me.compareAndSet(vpm, newVpm))return newVpm;
+				}
+				else looking = false;
+			}
+			return vpm;
+		}
+		
+		/**
+		 * Reset the ValidatorProjectManager to null, which will force a newer one to be created the next time
+		 * that it is requested.
+		 */
+		public static void reset(){
+			int next = _counter.incrementAndGet();
+			ValidatorProjectManager vpm = _me.get();
+			if ( vpm == null)return;
+			if (next > vpm.getSequence())_me.compareAndSet(vpm, null);
+		}
+		
+		private ValidatorProjectManager(int sequence){
+			_sequence = sequence;
+		}
+		
+		int getSequence(){
+			return _sequence;
+		}
 		
 		/**
 		 * Should this validator attempt to validate any resources in this project?
@@ -1037,26 +1136,8 @@
 			if (type == ValType.Manual)return _manual.shouldValidate(validator, project);
 				
 			return false;
-		}
-		
-		/**
-		 * A project has been created, opened, or had it's description changed.
-		 * @param project
-		 */
-		public void change(IProject project) {
-			reset();
-		}
-		
-		public void remove(IProject project) {
-			reset();
-		}
-		
-		
-		public void reset(){
-			_build.reset();
-			_manual.reset();
-		}
-		
+		}		
+				
 		/**
 		 * This is used to keep track of which validators are enabled for which projects. We want to ensure
 		 * that we don't activate a validator (and it's plug-in) if it has nothing to validate in the workspace.
@@ -1067,9 +1148,9 @@
 		 * @author karasiuk
 		 *
 		 */
-		private static class ValProjectMap {
+		private final static class ValProjectMap {
 			/**
-			 * Map a validator to the projects that it validates. 
+			 * Map a validator to the projects that it validates. This is an immutable object.
 			 * <p>
 			 * I've gone back and forth on whether the key should
 			 * be a Validator or the validator id. I'm back to it being the id because I was
@@ -1078,15 +1159,13 @@
 			 * false matches, it is probably because reset isn't being called when it should be.
 			 * </p>
 			 */
-			private Map<String, Set<IProject>> _map = new HashMap<String, Set<IProject>>(50);
+			private final Map<String, Set<IProject>> _map;
 			
 			private final ValType _type;
-			
-			/** Have we been initialized yet? */
-			private boolean	_initialized;
-			
+						
 			public ValProjectMap(ValType type){
 				_type = type;
+				_map = load();
 			}
 			
 			/**
@@ -1102,20 +1181,11 @@
 			 * @return true if the validator should attempt to validate.
 			 */
 			public boolean shouldValidate(Validator validator, IProject project){
-				if (!_initialized){
-					Map<String, Set<IProject>> map = load();
-					synchronized (this) {
-						_map = map;
-						_initialized = true;
-					}
-				}
-				synchronized(this){
-					String vid = validator.getId();
-					Set<IProject> projects = _map.get(vid);
-					if (projects == null)return false;
-					if (project == null)return projects.size() > 0;
-					return projects.contains(project);
-				}
+				String vid = validator.getId();
+				Set<IProject> projects = _map.get(vid);
+				if (projects == null)return false;
+				if (project == null)return projects.size() > 0;
+				return projects.contains(project);
 			}
 			
 			/**
@@ -1143,10 +1213,6 @@
 				return map;
 			}
 			
-			public synchronized void reset(){
-				_initialized = false;
-				_map.clear();
-			}
 		}
 		
 	}
@@ -1179,5 +1245,41 @@
 	private static class Singleton {
 		static ValManager valManager = new ValManager();
 	}
+	
+	private final class ValidatorCache {
+		private final ConcurrentMap<IProject, Validator[]> _cache = new ConcurrentHashMap<IProject, Validator[]>(50);
+		private final AtomicReference<Validator[]> _global = new AtomicReference<Validator[]>();
+		
+		public Validator[] getValidatorsCached(IProject project) throws ProjectUnavailableError {
+			Validator[] vals = null;
+			if (project == null){
+				vals = _global.get();
+				if (vals == null){				
+					vals = getValidatorsNotCached(project);
+					_global.set(vals);
+				}
+			}
+			else {
+				vals = _cache.get(project);
+				if (vals == null){
+					vals = getValidatorsNotCached(project);
+					_cache.put(project, vals);
+				}
+			}
+			return vals;
+		}
+		
+		public void reset(){
+			_cache.clear();
+			_global.set(null);
+		}
+		
+		public void reset(IProject project){
+			if (project != null)_cache.remove(project);
+		}
+
+	}
+	
+	public enum UseProjectPreferences {Normal, MustUse, MustNotUse}
 
 }
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValPrefManagerProject.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValPrefManagerProject.java
index b3a10fd..9dcf15e 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValPrefManagerProject.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValPrefManagerProject.java
@@ -36,10 +36,10 @@
  * @author karasiuk
  *
  */
-public class ValPrefManagerProject {
+public final class ValPrefManagerProject {
 	
-	private IProject	_project;
-	private static List<IValChangedListener> _listeners = new LinkedList<IValChangedListener>();
+	private final IProject	_project;
+	private final static List<IValChangedListener> _listeners = new LinkedList<IValChangedListener>();
 	
 	/**
 	 * The validators that are in the project preference file, but have
@@ -83,8 +83,10 @@
 	}
 	
 	/**
-	 * Answer the v2 validators that have been overridden by the global
-	 * preferences.
+	 * Answer the v2 validators that have been overridden by the project
+	 * preferences. The validators will not have the preference store's
+	 * customizations applied yet. The purpose of this method, is to identify the subset of validators 
+	 * that may later be configured.
 	 * 
 	 * @param baseValidators
 	 *            V2 validators from the extension points, and customized by any
@@ -100,7 +102,9 @@
 	}
 	
 	/**
-	 * Load the validators from the preference store.
+	 * Load the validators from the preference store. The validators will not have the preference store's
+	 * customizations applied yet. The purpose of this method, is to identify the subset of validators 
+	 * that may later be configured.
 	 * 
 	 * @param baseValidators
 	 *            V2 validators from the extension points, and customized by any
@@ -126,23 +130,7 @@
 		}
 		return list;
 	}
-	
-	/**
-	 * Update the project preferences from the preference store.
-	 * @return false if the project does not have any specific preferences.
-	 * 
-	 * @deprecated
-	 */
-	public boolean loadProjectPreferencesShallow(ProjectPreferences pp) {
-		IEclipsePreferences pref = getPreferences();
 		
-		if (pref == null)return false;
-		
-		pp.setOverride(pref.getBoolean(PrefConstants.override, ProjectPreferences.DefaultOverride));
-		pp.setSuspend(pref.getBoolean(PrefConstants.suspend, ProjectPreferences.DefaultSuspend));
-		return true;
-	}
-	
 	/**
 	 * Answer the setting of the getOverride field.
 	 */
@@ -163,20 +151,19 @@
 		return pref.getBoolean(PrefConstants.override, ProjectPreferences.DefaultOverride);
 	}
 
-	private void migrateFromBeforeWTP30(ProjectPreferences pp, Map<String, Validator> baseValidators) {
+	private ProjectPreferences migrateFromBeforeWTP30(IProject project, Map<String, Validator> baseValidators) {
 		try {
-			ProjectConfiguration pc = ConfigurationManager.getManager().getProjectConfiguration(pp.getProject());
-			pp.setSuspend(pc.isDisableAllValidation());
-			pp.setOverride(pc.getDoesProjectOverride());
+			ProjectConfiguration pc = ConfigurationManager.getManager().getProjectConfiguration(project);
 			
 			List<Validator> list = migrateFromBeforeWTP30(baseValidators, pc);
 			Validator[] vals = new Validator[list.size()];
 			list.toArray(vals);
-			pp.setValidators(vals);			
+			return new ProjectPreferences(project, pc.getDoesProjectOverride(), pc.isDisableAllValidation(), vals);
 		}
 		catch (InvocationTargetException e){
 			// eat it, if it fails we just go with the defaults
 		}
+		return new ProjectPreferences(project);
 	}
 
 	private List<Validator> migrateFromBeforeWTP30(Map<String, Validator> baseValidators, ProjectConfiguration pc)
@@ -206,28 +193,27 @@
 	
 	
 	/**
-	 * Update the project preferences from the preference store.
-	 * @return false if the project does not have any specific preferences.
+	 * Answer the project preferences from the preference store.
+	 * @return null if the project does not have any specific preferences.
 	 */
-	public boolean loadProjectPreferences(ProjectPreferences pp, Map<String, Validator> baseValidators) 
+	public ProjectPreferences loadProjectPreferences(IProject project, Map<String, Validator> baseValidators) 
 		throws BackingStoreException {
 		
 		IEclipsePreferences pref = getPreferences();
 
-		if (pref == null)return false;
+		if (pref == null)return null;
 		int version = pref.getInt(PrefConstants.frameworkVersion, 0);
 		if (version == 0){
 			// This means that we have a project that is before WTP 3.0
-			migrateFromBeforeWTP30(pp, baseValidators);
-			return true;
+			return migrateFromBeforeWTP30(project, baseValidators);
 		}
 		
 		if (version != ValPrefManagerGlobal.frameworkVersion)ValPrefManagerGlobal.migrate(version, pref);
 
-		pp.setOverride(pref.getBoolean(PrefConstants.override, ProjectPreferences.DefaultOverride));
-		pp.setSuspend(pref.getBoolean(PrefConstants.suspend, ProjectPreferences.DefaultSuspend));
-		
-		if (!pref.nodeExists(PrefConstants.vals))return true;
+		if (!pref.nodeExists(PrefConstants.vals)){
+			return new ProjectPreferences(project, pref.getBoolean(PrefConstants.override, ProjectPreferences.DefaultOverride),
+				pref.getBoolean(PrefConstants.suspend, ProjectPreferences.DefaultSuspend), new Validator[0]);
+		}
 		
 		Preferences vp = pref.node(PrefConstants.vals);
 		List<Validator> list = new LinkedList<Validator>();
@@ -242,8 +228,8 @@
 		}
 		Validator[] vals = new Validator[list.size()];
 		list.toArray(vals);
-		pp.setValidators(vals);
-		return true;
+		return new ProjectPreferences(project, pref.getBoolean(PrefConstants.override, ProjectPreferences.DefaultOverride),
+			pref.getBoolean(PrefConstants.suspend, ProjectPreferences.DefaultSuspend), vals);
 	}
 
 	private IEclipsePreferences getPreferences() {
@@ -252,7 +238,8 @@
 		return pref;
 	}
 
-	public void savePreferences(ProjectPreferences projectPreferences, Validator[] validators) {
+	public void savePreferences(ProjectPreferences projectPreferences) {
+		Validator[] validators = projectPreferences.getValidators();
 		IEclipsePreferences pref = getPreferences();
 		pref.putBoolean(PrefConstants.suspend, projectPreferences.getSuspend());
 		pref.putBoolean(PrefConstants.override, projectPreferences.getOverride());
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidatorExtensionReader.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidatorExtensionReader.java
index 7e8a924..108e066 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidatorExtensionReader.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/ValidatorExtensionReader.java
@@ -42,17 +42,16 @@
  */
 public class ValidatorExtensionReader {
 	
-	private static ValidatorExtensionReader _me;
+	private static ValidatorExtensionReader _me = new ValidatorExtensionReader();
 	
-	public synchronized static ValidatorExtensionReader getDefault(){
-		if (_me == null)_me = new ValidatorExtensionReader();
+	public  static ValidatorExtensionReader getDefault(){
 		return _me;
 	}
 	
 	private ValidatorExtensionReader(){}
 	
 	/**
-	 * Read the extensions.
+	 * Process the v2 extensions, returning all the v2 validators.
 	 */
 	Collection<Validator> process() {
 		Map<String,Validator> map = new HashMap<String, Validator>(100);
@@ -201,7 +200,7 @@
 	}
 
 	/**
-	 * Answer the extension point for the validators.
+	 * Answer the extension point for the v2 validators.
 	 * 
 	 * @return null if there is a problem or no extensions.
 	 */
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/FilterGroup.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/FilterGroup.java
index 156a498..6d20dd5 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/FilterGroup.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/FilterGroup.java
@@ -92,14 +92,16 @@
 	private FilterGroup(FilterRule[] rules){
 		_rules = rules;
 	}
-	
+		
 	/**
-	 * The rules in the group. Callers of this method must not change this array in any way.
+	 * The rules in the group.
 	 */
-	public FilterRule[] getRules(){
-		return _rules;
+	public final FilterRule[] getRules(){
+		FilterRule[] rules = new FilterRule[_rules.length];
+		System.arraycopy(_rules, 0, rules, 0, _rules.length);
+		return rules;
 	}
-	
+		
 	/**
 	 * Answer the internal type of group, e.g. "include" or "exclude".
 	 */
@@ -171,11 +173,10 @@
 	 * only the project level checks are performed.
 	 */
 	public boolean shouldValidate(IProject project, IResource resource, ContentTypeWrapper contentTypeWrapper) {
-		FilterRule[] rules = getRules();
 		boolean exclude = isExclude();
 		boolean include = isInclude();
 		int count = 0;
-		for (FilterRule rule : rules){
+		for (FilterRule rule : _rules){
 			if (resource != null){
 				Boolean match = rule.matchesResource(resource, contentTypeWrapper);
 				if (match != null)count++;
@@ -224,7 +225,7 @@
 	 */
 	public static FilterGroup addRule(FilterGroup baseGroup, FilterRule rule) {
 		List<FilterRule> list = new LinkedList<FilterRule>();
-		for (FilterRule r : baseGroup.getRules())list.add(r);
+		for (FilterRule r : baseGroup._rules)list.add(r);
 		list.add(rule);
 		
 		FilterRule[] rules = new FilterRule[list.size()];
@@ -240,7 +241,7 @@
 	 */
 	public static FilterGroup removeRule(FilterGroup baseGroup,	FilterRule rule) {
 		List<FilterRule> list = new LinkedList<FilterRule>();
-		for (FilterRule r : baseGroup.getRules()){
+		for (FilterRule r : baseGroup._rules){
 			if (!r.equals(rule))list.add(r);
 		}
 		
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/GlobalPreferences.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/GlobalPreferences.java
index 9b4c40e..2989c2c 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/GlobalPreferences.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/GlobalPreferences.java
@@ -55,21 +55,12 @@
 	
 	/** The incoming version of the framework. This is used to determine if a migration is needed.*/
 	private final int		_version;
-		
+			
 	/**
 	 * The only valid way to get the global preferences is through the ValManager.
 	 * 
 	 * @see org.eclipse.wst.validation.internal.ValManager#getGlobalPreferences()
 	 */
-	public GlobalPreferences(){
-		_confirmDialog = DefaultConfirm;
-		_disableAllValidation = DefaultSuspend;
-		_override  = DefaultOverride;
-		_saveAutomatically = DefaultAutoSave;
-		_stateTimeStamp = -1;
-		_version = -1;
-	}
-	
 	public GlobalPreferences(GlobalPreferencesValues gp) {
 		_confirmDialog = gp.confirmDialog;
 		_disableAllValidation = gp.disableAllValidation;
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/GlobalPreferencesValues.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/GlobalPreferencesValues.java
index b9ee1b0..cdf8345 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/GlobalPreferencesValues.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/GlobalPreferencesValues.java
@@ -1,3 +1,14 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.model;
 
 /**
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/ProjectPreferences.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/ProjectPreferences.java
index 38705a1..0014306 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/ProjectPreferences.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/ProjectPreferences.java
@@ -19,35 +19,42 @@
  *
  */
 public final class ProjectPreferences {
+	/*
+	 * Before this object can be considered immutable, the mutable validators need to be addressed.
+	 */
 	/** false - Default setting for the "should all the validation be suspended" setting. */ 
 	public static final boolean DefaultSuspend = false;
 	
 	/** false - Default setting for letting projects override the global settings. */
 	public static final boolean DefaultOverride = false;
 	
-	private IProject	_project;
+	private final IProject	_project;
 
-	private boolean 	_override = DefaultOverride;
-	private boolean		_suspend = DefaultSuspend;
+	private final boolean 	_override;
+	private final boolean	_suspend;
 	
-	private Validator[]	_validators = new Validator[0];
+	private final Validator[]	_validators;
 	
 	public ProjectPreferences(IProject project){
 		_project = project;
+		_override = DefaultOverride;
+		_suspend  = DefaultSuspend;
+		_validators = new Validator[0];
+	}
+	
+	public ProjectPreferences(IProject project, boolean override, boolean suspend, Validator[] validtors){
+		_project = project;
+		_override = override;
+		_suspend = suspend;
+		_validators = validtors;
 	}
 	
 	public boolean getOverride() {
 		return _override;
 	}
-	public void setOverride(boolean override) {
-		_override = override;
-	}
 	public boolean getSuspend() {
 		return _suspend;
 	}
-	public void setSuspend(boolean suspend) {
-		_suspend = suspend;
-	}
 	
 	/**
 	 * Answer the validators that have been registered for this project.
@@ -57,10 +64,6 @@
 		return _validators;
 	}
 	
-	public void setValidators(Validator[] validators){
-		_validators = validators;
-	}
-	
 	public IProject getProject() {
 		return _project;
 	}
diff --git a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/ValidatorHelper.java b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/ValidatorHelper.java
index b9d2654..8270b28 100644
--- a/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/ValidatorHelper.java
+++ b/plugins/org.eclipse.wst.validation/vf2/org/eclipse/wst/validation/internal/model/ValidatorHelper.java
@@ -22,16 +22,9 @@
 	
 	/**
 	 * Answer true if this validator already has an exclude filter.
-	 * 
-	 * @param v
-	 * @return
 	 */
 	public static boolean hasExcludeGroup(Validator.V2 v){
-		FilterGroup[] groups = v.getGroups();
-		for (int i=0; i<groups.length; i++){
-			if (groups[i].isExclude())return true;
-		}
-		return false;
-		
+		for (FilterGroup group : v.getGroups())if (group.isExclude())return true;
+		return false;		
 	}
 }