[364482] A race condition could occur in Server code
diff --git a/features/org.eclipse.wst.server_core.feature.patch/buildnotes_org.eclipse.wst.server_core.feature.patch.html b/features/org.eclipse.wst.server_core.feature.patch/buildnotes_org.eclipse.wst.server_core.feature.patch.html
index 0226ed5..bbe43e8 100644
--- a/features/org.eclipse.wst.server_core.feature.patch/buildnotes_org.eclipse.wst.server_core.feature.patch.html
+++ b/features/org.eclipse.wst.server_core.feature.patch/buildnotes_org.eclipse.wst.server_core.feature.patch.html
@@ -4,17 +4,17 @@
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="Build" content="Build">
-   <title>WTP 3.2.2 Patches</title>
+   <title>WTP 3.2.5 Patches</title>
 </head>
 
 <body>
 
-<h1>WTP 3.2.2 Patches</h1>
+<h1>WTP 3.2.5 Patches</h1>
 
 <h2>Feature Patched: org.eclipse.wst.server_core.feature</h2>
 <h3>Plugin(s) replaced:</h3>
 <ul><li>org.eclipse.wst.server.core</li></ul>
-<p>Bug <a href='https://bugs.eclipse.org/327247'>327247</a>. Deadlock during debugging</p>
+<p>Bug <a href='https://bugs.eclipse.org/364482'>364482</a>. A race condition could occur in Server code</p>
 
 
 </body></html>
\ No newline at end of file
diff --git a/features/org.eclipse.wst.server_core.feature.patch/feature.properties b/features/org.eclipse.wst.server_core.feature.patch/feature.properties
index 40eb625..c44afc3 100644
--- a/features/org.eclipse.wst.server_core.feature.patch/feature.properties
+++ b/features/org.eclipse.wst.server_core.feature.patch/feature.properties
@@ -27,7 +27,7 @@
 description=\
 Contains fixes described in the following bugzilla(s):\n\
 \n\
-Bug https://bugs.eclipse.org/327247 Deadlock during debugging\n\
+Bug https://bugs.eclipse.org/364482 A race condition could occur in Server code\n\
 \n\
 # "copyright" property - text of the "Feature Update Copyright"
 copyright=\
diff --git a/features/org.eclipse.wst.server_core.feature.patch/feature.xml b/features/org.eclipse.wst.server_core.feature.patch/feature.xml
index 46c2bad..e148ee8 100644
--- a/features/org.eclipse.wst.server_core.feature.patch/feature.xml
+++ b/features/org.eclipse.wst.server_core.feature.patch/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.wst.server_core.feature.patch"
     label="%featureName"
-    version="3.2.2.qualifier"
+    version="3.2.5.qualifier"
     provider-name="%providerName">
 
     <description>%description</description>
@@ -12,7 +12,7 @@
     <license url="%licenseURL">%license</license>
 
    <requires>
-      <import feature="org.eclipse.wst.server_core.feature" version="3.2.2.v20100908-30F8V8s734C3I3K" patch="true"/>
+      <import feature="org.eclipse.wst.server_core.feature" version="3.2.5.v20110729_1202-30F8_8s7355463Ha2845" patch="true"/>
    </requires>
 
    <plugin
diff --git a/plugins/org.eclipse.wst.server.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.server.core/META-INF/MANIFEST.MF
index a2d43e2..0350d2b 100644
--- a/plugins/org.eclipse.wst.server.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.wst.server.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.wst.server.core; singleton:=true
-Bundle-Version: 1.1.208.qualifier
+Bundle-Version: 1.1.209.qualifier
 Bundle-Activator: org.eclipse.wst.server.core.internal.ServerPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
index 11670be..cdedc84 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * Copyright (c) 2003, 2012 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
@@ -83,6 +83,9 @@
 
 	// the list of modules that are to be published to the server
 	protected List<IModule> modules;
+	
+	/** A lock that is used to synchronize access to modules. */
+	protected final Object modulesLock = new Object();
 
 	// the list of external modules
 	protected List<IModule> externalModules;
@@ -923,22 +926,28 @@
 		if (getModules().length < 0)
 			return false;
 		
-		// shallow search: check for root modules first
-		boolean deployed = modules.contains(requestedModule);
+		boolean deployed = false;
 		
-		if(!deployed){
-			// deep search: look into all the child modules
-			Iterator<IModule> itr = modules.iterator();
-			while(itr.hasNext() && !deployed){
-				IModule[] m = new IModule[] {itr.next()};
-				deployed = !visitModule(m, new IModuleVisitor(){
-					public boolean visit(IModule[] modules2) {
-						for (int i =0;i<=modules2.length-1;i++){
-							if (modules2[i].equals(requestedModule))
-								return false;
-						}
-						return true;
-				}}, null);
+		synchronized (modulesLock){
+			// shallow search: check for root modules first
+			if (modules != null){
+				deployed = modules.contains(requestedModule);
+			
+				if(!deployed){
+					// deep search: look into all the child modules
+					Iterator<IModule> itr = modules.iterator();
+					while(itr.hasNext() && !deployed){
+						IModule[] m = new IModule[] {itr.next()};
+						deployed = !visitModule(m, new IModuleVisitor(){
+							public boolean visit(IModule[] modules2) {
+								for (int i =0;i<=modules2.length-1;i++){
+									if (modules2[i].equals(requestedModule))
+										return false;
+								}
+								return true;
+						}}, null);
+					}
+				}
 			}
 		}
 		
@@ -2361,7 +2370,9 @@
 		serverSyncState = wc.serverSyncState;
 		//restartNeeded = wc.restartNeeded;
 		serverType = wc.serverType;
-		modules = wc.modules;
+		synchronized(modulesLock){
+			modules = wc.modules;
+		}
 		
 		// can never modify the following properties via the working copy
 		//serverState = wc.serverState;
@@ -2427,13 +2438,26 @@
 	}
 	
 	public void clearModuleCache() {
-		modules = null;
+		synchronized (modulesLock){
+			modules = null;
+		}
 	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.wst.server.core.IServer#getModules()
 	 */
 	public IModule[] getModules() {
+		synchronized (modulesLock){
+			return getModulesWithoutLock();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * The implementation for getModules but this one does not lock the modules object. Caller is responsible for locking the modulesLock
+	 * object when calling this method for thread safe implementation.
+	 * @see org.eclipse.wst.server.core.IServer#getModules()
+	 */
+	protected IModule[] getModulesWithoutLock() {
 		if (modules == null) {
 			// convert from attribute
 			List<String> list = getAttribute(MODULE_LIST, (List<String>) null);
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java
index cb88a6a..671b1a0 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * Copyright (c) 2003, 2012 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
@@ -553,51 +553,53 @@
 			wch.setDirty(true);
 			
 			// trigger load of modules list
-			getModules();
-			
-			if (add != null) {
-				int size = add.length;
-				for (int i = 0; i < size; i++) {
-					if (!modules.contains(add[i])) {
-						modules.add(add[i]);
-						resetState(new IModule[] { add[i] }, monitor);
+			synchronized (modulesLock){
+				getModulesWithoutLock();
+				if (add != null) {
+					int size = add.length;
+					for (int i = 0; i < size; i++) {
+						if (!modules.contains(add[i])) {
+							modules.add(add[i]);
+							resetState(new IModule[] { add[i] }, monitor);
+						}
 					}
 				}
-			}
-			
-			if (remove != null) {
-				int size = remove.length;
-				externalModules = getExternalModules();
-				for (int i = 0; i < size; i++) {
-					if (modules.contains(remove[i])) {
-						modules.remove(remove[i]);
-						resetState(new IModule[] { remove[i] }, monitor);
-					}
-					if (externalModules != null && externalModules.contains(remove[i])) {
-						externalModules.remove(remove[i]);
-						resetState(new IModule[] { remove[i] }, monitor);
+				
+				if (remove != null) {
+					int size = remove.length;
+					externalModules = getExternalModules();
+					for (int i = 0; i < size; i++) {
+						if (modules.contains(remove[i])) {
+							modules.remove(remove[i]);
+							resetState(new IModule[] { remove[i] }, monitor);
+						}
+						if (externalModules != null && externalModules.contains(remove[i])) {
+							externalModules.remove(remove[i]);
+							resetState(new IModule[] { remove[i] }, monitor);
+						}
 					}
 				}
-			}
-			
-			// convert to attribute
-			List<String> list = new ArrayList<String>();
-			Iterator iterator = modules.iterator();
-			while (iterator.hasNext()) {
-				IModule module = (IModule) iterator.next();
-				StringBuffer sb = new StringBuffer(module.getName());
-				sb.append("::");
-				sb.append(module.getId());
-				IModuleType mt = module.getModuleType();
-				if (mt != null) {
+				
+				// convert to attribute
+				List<String> list = new ArrayList<String>();
+				Iterator iterator = modules.iterator();
+				while (iterator.hasNext()) {
+					IModule module = (IModule) iterator.next();
+					StringBuffer sb = new StringBuffer(module.getName());
 					sb.append("::");
-					sb.append(mt.getId());
-					sb.append("::");
-					sb.append(mt.getVersion());
+					sb.append(module.getId());
+					IModuleType mt = module.getModuleType();
+					if (mt != null) {
+						sb.append("::");
+						sb.append(mt.getId());
+						sb.append("::");
+						sb.append(mt.getVersion());
+					}
+					list.add(sb.toString());
 				}
-				list.add(sb.toString());
+				setAttribute(MODULE_LIST, list);
 			}
-			setAttribute(MODULE_LIST, list);
+
 			resetOptionalPublishOperations();
 			resetPreferredPublishOperations();
 		} catch (CoreException ce) {