[252217] Deadlock during validation and rebuild
diff --git a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationBuilder.java b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationBuilder.java
index 9e6051c..aae7122 100644
--- a/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationBuilder.java
+++ b/plugins/org.eclipse.wst.validation/validate/org/eclipse/wst/validation/internal/operations/ValidationBuilder.java
@@ -51,6 +51,13 @@
  * </p>
  */
 public class ValidationBuilder extends IncrementalProjectBuilder {
+	/*
+	 * GRK - This class serves as a main entry point into the framework. There is one instance of this class for every
+	 * project that has a validation builder configured for it. Typically if you had ten projects in your workspace you would have
+	 * ten of these objects. They created early in the life cycle of the workbench, and then are reused. 
+	 * 
+	 * My observation was that they are run serially by the same thread.
+	 */
 	public static final int NO_DELTA_CHANGE = -1;
 	protected List<IProject> referencedProjects;
 	protected IWorkbenchContext workbenchContext = null;
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 cec6825..4fc849f 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,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
@@ -76,7 +77,8 @@
 	 * 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 int _configNumber;
+	private AtomicInteger _configNumber = new AtomicInteger();
+	
 	private ValidatorIdManager _idManager = new ValidatorIdManager();
 	
 	private ValidatorProjectManager _projectManager = new ValidatorProjectManager();
@@ -476,24 +478,41 @@
 	 * This method needs to be called whenever the validation configuration has changed.
 	 */
 	private void configHasChanged(){
-		_configNumber++;
+		_configNumber.incrementAndGet();
 		_projectManager.reset();
 	}
 		
 	/**
 	 * Answer the global validation preferences.
 	 */
-	public synchronized GlobalPreferences getGlobalPreferences(){
+	public GlobalPreferences getGlobalPreferences(){
 		GlobalPreferences gp = _globalPreferences;
 		if (gp == null){
 			ValPrefManagerGlobal vpm = ValPrefManagerGlobal.getDefault();
 			gp = new GlobalPreferences();
 			vpm.loadGlobalPreferences(gp);
-			_globalPreferences = gp;
+			gp = setIfNotNullGlobalPreferences(gp);
 		}
 		return gp;		
 	}
 	
+	/**
+	 * If the global preferences have not been set yet, set them now.
+	 * 
+	 * @param gp
+	 *            The global preferences to use if they have not already been
+	 *            set.
+	 * @return The current global preferences. If they were set before the
+	 *         original ones are returned. Otherwise the passed in ones are both
+	 *         saved and returned.
+	 */
+	private synchronized GlobalPreferences setIfNotNullGlobalPreferences(GlobalPreferences gp){
+		if (_globalPreferences == null){
+			_globalPreferences = gp;
+		}
+		return _globalPreferences;
+	}
+	
 	public ProjectPreferences getProjectPreferences(IProject project) {
 		ProjectPreferences pp = getProjectPreferences2(project);
 		if (pp != null)return pp;
@@ -689,7 +708,7 @@
 		
 		Map<String,IValidatorGroupListener[]> groupListeners = new HashMap<String,IValidatorGroupListener[]>();
 		
-		ValProperty vp = getValProperty(resource, valType, _configNumber);
+		ValProperty vp = getValProperty(resource, valType, _configNumber.get());
 		if (vp != null){
 			BitSet bs = vp.getConfigSet();
 			for (Validator val : getValidators(project)){
@@ -713,7 +732,7 @@
 		}
 		
 		vp = new ValProperty();
-		vp.setConfigNumber(_configNumber);
+		vp.setConfigNumber(_configNumber.get());
 		ContentTypeWrapper ctw = new ContentTypeWrapper();
 		for (Validator val : getValidators(project)){
 			if (!monitor.isCanceled()) {
@@ -815,7 +834,7 @@
 			// don't care about this one
 		}
 		if (vp == null)return null;
-		if (vp.getConfigNumber() != _configNumber)return null;
+		if (vp.getConfigNumber() != _configNumber.get())return null;
 		return vp;
 	}
 	
@@ -935,8 +954,8 @@
 		/**
 		 * Map validator id's to Integers. The integers correspond to bits in the ValProperty instances.
 		 */
-		private HashMap<String, Integer> _map = new HashMap<String, Integer>(100);
-		private HashMap<Integer, String> _reverseMap = new HashMap<Integer, String>(100);
+		private Map<String, Integer> _map = new HashMap<String, Integer>(100);
+		private Map<Integer, String> _reverseMap = new HashMap<Integer, String>(100);
 		
 		/** Next available bit. */
 		private int _next;
@@ -946,7 +965,7 @@
 		 * @param id validator id.
 		 * @return index into the validator bit mask.
 		 */
-		public int getIndex(String id){
+		public synchronized int getIndex(String id){
 			Integer i = _map.get(id);
 			if (i != null)return i;
 			
@@ -962,11 +981,11 @@
 		 * @param index
 		 * @return null if the index number has not been set.
 		 */
-		public String getId(Integer index){
+		public synchronized String getId(Integer index){
 			return _reverseMap.get(index);
 		}
 		
-		public void reset(){
+		public synchronized void reset(){
 			_map.clear();
 			_reverseMap.clear();
 			_next = 0;
@@ -976,7 +995,7 @@
 		 * Answer the ids for the bit in the bitset. This is used for debugging. 
 		 * @param bs
 		 */
-		public String[] getIds(BitSet bs){
+		public synchronized String[] getIds(BitSet bs){
 			List<String> list = new LinkedList<String>();
 			for(int i=bs.nextSetBit(0); i>=0; i=bs.nextSetBit(i+1)) {
 				String id = getId(i);
@@ -1011,7 +1030,7 @@
 		 *            The type of validation operation.
 		 * @return true if the validator should attempt to validate.
 		 */
-		public synchronized boolean shouldValidate(Validator validator, IProject project, ValType type){
+		public boolean shouldValidate(Validator validator, IProject project, ValType type){
 			if (type == ValType.Build)return _build.shouldValidate(validator, project);
 			if (type == ValType.Manual)return _manual.shouldValidate(validator, project);
 				
@@ -1031,7 +1050,7 @@
 		}
 		
 		
-		public synchronized void reset(){
+		public void reset(){
 			_build.reset();
 			_manual.reset();
 		}
@@ -1053,7 +1072,7 @@
 			 */
 			private Map<String, Set<IProject>> _map = new HashMap<String, Set<IProject>>(50);
 			
-			private ValType _type;
+			private final ValType _type;
 			
 			/** Have we been initialized yet? */
 			private boolean	_initialized;
@@ -1074,16 +1093,25 @@
 			 *            
 			 * @return true if the validator should attempt to validate.
 			 */
-			public synchronized boolean shouldValidate(Validator validator, IProject project){
-				if (!_initialized)load();
-				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);
+			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);
+				}
 			}
 			
-			private void load() {
+			private Map<String, Set<IProject>> load() {
+				Map<String, Set<IProject>> map = new HashMap<String, Set<IProject>>(50);
 				ValManager vm = ValManager.getDefault();
 				IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
 				Tracing.log("ValManager-02: loading " + projects.length + " projects");  //$NON-NLS-1$//$NON-NLS-2$
@@ -1092,16 +1120,16 @@
 					Validator[] vals = vm.getValidators(project);
 					for (Validator v : vals){
 						String vid = v.getId();
-						Set<IProject> set = _map.get(vid);
+						Set<IProject> set = map.get(vid);
 						if (set == null){
 							set = new HashSet<IProject>(50);
-							_map.put(vid, set);
+							map.put(vid, set);
 						}
 						
 						if (v.shouldValidateProject(project, _type))set.add(project);
 					}					
 				}
-				_initialized = true;
+				return map;
 			}
 			
 			public synchronized void reset(){