[390105]  Publish before start servers synchronization problem
[390692]  Finish button not disabled when no entries selected
[390695]  New Server wizard doesn't block user from creating server
with existing name
[390697]  Runtime search function results in duplicate entries on
Server Runtime Environments preferences page
[390700]  ServerToolTip too aggressive at opening tooltips
[390704]  ServerToolTip escape on focussed tooltip not working
perfectly
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 2766708..dc12a39 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
@@ -19,6 +19,5 @@
 <p>Bug <a href='https://bugs.eclipse.org/370992'>370992</a>. Extensible Server Start Jobs</p>
 <p>Bug <a href='https://bugs.eclipse.org/377566'>377566</a>. The server timeout timer begins at the incorrect time</p>
 <p>Bug <a href='https://bugs.eclipse.org/377835'>377835</a>. The JavaDoc and implementation isn't consistent for utility method ServerUtil.setRuntimeDefaultName() - Port to WTP 3.2.5 patches</p>
-
-
+<p>Bug <a href='https://bugs.eclipse.org/390105'>390105</a>. Publish before start servers synchronization problem</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 3282694..9cc374f 100644
--- a/features/org.eclipse.wst.server_core.feature.patch/feature.properties
+++ b/features/org.eclipse.wst.server_core.feature.patch/feature.properties
@@ -32,6 +32,7 @@
 Bug https://bugs.eclipse.org/370992 Extensible Server Start Jobs\n\
 Bug https://bugs.eclipse.org/377566 The server timeout timer begins at the incorrect time\n\
 Bug https://bugs.eclipse.org/377835 The JavaDoc and implementation isn't consistent for utility method ServerUtil.setRuntimeDefaultName() - Port to WTP 3.2.5 patches\n\
+Bug https://bugs.eclipse.org/390105 Publish before start servers synchronization problem\n\
 \n\
 # "copyright" property - text of the "Feature Update Copyright"
 copyright=\
diff --git a/features/org.eclipse.wst.server_ui.feature.patch/buildnotes_org.eclipse.wst.server_ui.feature.patch.html b/features/org.eclipse.wst.server_ui.feature.patch/buildnotes_org.eclipse.wst.server_ui.feature.patch.html
index 2eea2cc..f01c18c 100644
--- a/features/org.eclipse.wst.server_ui.feature.patch/buildnotes_org.eclipse.wst.server_ui.feature.patch.html
+++ b/features/org.eclipse.wst.server_ui.feature.patch/buildnotes_org.eclipse.wst.server_ui.feature.patch.html
@@ -24,5 +24,10 @@
 <p>Bug <a href='https://bugs.eclipse.org/376996'>376996</a>. deleting a server with a dirty server editor</p>
 <p>Bug <a href='https://bugs.eclipse.org/377095'>377095</a>. FileNotFound and ResourceExceptions when Deleting Servers Configuration</p>
 <p>Bug <a href='https://bugs.eclipse.org/377533'>377533</a>. Server view tooltip not colour accessible</p>
+<p>Bug <a href='https://bugs.eclipse.org/390692'>390692</a>. Finish button not disabled when no entries selected</p>
+<p>Bug <a href='https://bugs.eclipse.org/390695'>390695</a>. New Server wizard doesn't block user from creating server with existing name</p>
+<p>Bug <a href='https://bugs.eclipse.org/390697'>390697</a>. Runtime search function results in duplicate entries on Server Runtime Environments preferences page</p>
+<p>Bug <a href='https://bugs.eclipse.org/390700'>390700</a>. ServerToolTip too aggressive at opening tooltips</p>
+<p>Bug <a href='https://bugs.eclipse.org/390704'>390704</a>. ServerToolTip escape on focussed tooltip not working perfectly</p>
 
 </body></html>
\ No newline at end of file
diff --git a/features/org.eclipse.wst.server_ui.feature.patch/feature.properties b/features/org.eclipse.wst.server_ui.feature.patch/feature.properties
index 7b0281a..45bcaa2 100644
--- a/features/org.eclipse.wst.server_ui.feature.patch/feature.properties
+++ b/features/org.eclipse.wst.server_ui.feature.patch/feature.properties
@@ -38,6 +38,11 @@
 Bug https://bugs.eclipse.org/376996 deleting a server with a dirty server editor\n\
 Bug https://bugs.eclipse.org/377095 FileNotFound and ResourceExceptions when Deleting Servers Configuration\n\
 Bug https://bugs.eclipse.org/377533 Server view tooltip not colour accessible\n\
+Bug https://bugs.eclipse.org/390692 Finish button not disabled when no entries selected\n\
+Bug https://bugs.eclipse.org/390695 New Server wizard doesn't block user from creating server with existing name\n\
+Bug https://bugs.eclipse.org/390697 Runtime search function results in duplicate entries on Server Runtime Environments preferences page\n\
+Bug https://bugs.eclipse.org/390700 ServerToolTip too aggressive at opening tooltips\n\
+Bug https://bugs.eclipse.org/390704 ServerToolTip escape on focussed tooltip not working perfectly\n\
 \n\
 # "copyright" property - text of the "Feature Update Copyright"
 copyright=\
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 0350d2b..eef4029 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.209.qualifier
+Bundle-Version: 1.1.210.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 1bdaf42..13fdda4 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
@@ -375,11 +375,18 @@
 		public RestartJob(String launchMode) {
 			super(NLS.bind(Messages.jobRestarting, Server.this.getName()));
 			this.launchMode = launchMode;
-			setRule(Server.this);
 		}
 
 		protected IStatus run(IProgressMonitor monitor) {
-			return restartImpl(launchMode, monitor);
+			try{
+				// Do begin rule in here instead of setRule on constructor to prevent deadlock
+				// on the default restart operation during the join() in the StartJob.
+				Job.getJobManager().beginRule(Server.this, monitor);
+				return restartImpl(launchMode, monitor);
+			}
+			finally{
+				Job.getJobManager().endRule(Server.this);
+			}
 		}
 	}
 
@@ -1108,10 +1115,7 @@
 				srl[i].publishStarted(this);
 			} catch (Exception e) {
 				if (Trace.SEVERE) {
-					Trace.trace(
-							Trace.STRING_SEVERE,
-							"  Error firing publish started event to " + srl[i],
-							e);
+					Trace.trace(Trace.STRING_SEVERE, "  Error firing publish started event to " + srl[i], e);
 				}
 			}
 		}
@@ -1146,9 +1150,7 @@
 				srl[i].publishFinished(this, status);
 			} catch (Exception e) {
 				if (Trace.SEVERE) {
-					Trace.trace(Trace.STRING_SEVERE,
-							"  Error firing publishing finished event to "
-									+ srl[i], e);
+					Trace.trace(Trace.STRING_SEVERE, "  Error firing publishing finished event to " + srl[i], e);
 				}
 			}
 		}
@@ -1656,9 +1658,7 @@
 			getBehaviourDelegate(monitor).setupLaunchConfiguration(workingCopy, monitor);
 		} catch (Exception e) {
 			if (Trace.SEVERE) {
-				Trace.trace(Trace.STRING_SEVERE,
-						"Error calling delegate setupLaunchConfiguration() "
-								+ toString(), e);
+				Trace.trace(Trace.STRING_SEVERE, "Error calling delegate setupLaunchConfiguration() " + toString(), e);
 			}
 		}
 	}
@@ -1709,9 +1709,7 @@
 										lc[0] = wc.doSave();
 									} catch (CoreException ce) {
 										if (Trace.SEVERE) {
-											Trace.trace(Trace.STRING_SEVERE,
-													"Error configuring launch",
-													ce);
+											Trace.trace(Trace.STRING_SEVERE, "Error configuring launch", ce);
 										}
 									}
 									return Status.OK_STATUS;
@@ -1723,8 +1721,7 @@
 								job.join();
 							} catch (Exception e) {
 								if (Trace.SEVERE) {
-									Trace.trace(Trace.STRING_SEVERE,
-											"Error configuring launch", e);
+									Trace.trace(Trace.STRING_SEVERE, "Error configuring launch", e);
 								}
 							}
 							if (job.getState() != Job.NONE) {
@@ -1738,8 +1735,7 @@
 					}
 				} catch (CoreException e) {
 					if (Trace.SEVERE) {
-						Trace.trace(Trace.STRING_SEVERE,
-								"Error configuring launch", e);
+						Trace.trace(Trace.STRING_SEVERE, "Error configuring launch", e);
 					}
 				}
 			}
@@ -1902,7 +1898,7 @@
 		job.schedule();
 	}
 
-	protected IStatus publishBeforeStart(IProgressMonitor monitor, boolean synchronous){
+	protected IStatus publishBeforeStart(IProgressMonitor monitor, final StartJob startJob, final boolean synchronous){
 
 		// check if we need to publish
 		byte pub = StartJob.PUBLISH_NONE;
@@ -1921,22 +1917,53 @@
 			pubJob.addJobChangeListener(new JobChangeAdapter(){
 				public void done(IJobChangeEvent event) {
 					IStatus status = event.getResult();
-					if (status != null && status.getSeverity() == IStatus.ERROR)
-						pubStatus[0] = status; 
+					if (status != null && status.getSeverity() == IStatus.ERROR) {
+						pubStatus[0] = status;
+						if (Trace.INFO) {
+							Trace.trace(Trace.STRING_INFO,
+									"Skipping server start job schedule since the server publish failed on a publish before start server.");
+						}
+					} else {
+						if (Trace.INFO) {
+							Trace.trace(Trace.STRING_INFO,
+									"Scheduling server start job after successful publish.");
+						}
+						// Schedule the server start job since the publish operation is completed successfully.
+						startJob.schedule();
+						
+						try {
+							if (synchronous)
+								startJob.join();
+						} catch (InterruptedException e) {
+							if (Trace.WARNING) {
+								Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+							}
+						}
+					}
 				}
 				
 			});
-			
 			pubJob.schedule();
 			
-			try{
+			try {
 				if (synchronous)
 					pubJob.join();
-					
-			}
-			catch (InterruptedException ie){
+			} catch (InterruptedException ie) {
 				return Status.CANCEL_STATUS;
 			}
+		} else {
+			// Schedule the server start since a publish is not needed so 
+			// Schedule the server start job since the publish operation is completed successfully.
+			startJob.schedule();
+			
+			try {
+				if (synchronous)
+					startJob.join();
+			} catch (InterruptedException e) {
+				if (Trace.WARNING) {
+					Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+				}
+			}
 		}
 		return pubStatus[0];
 	}
@@ -2000,20 +2027,10 @@
 		// make sure that the delegate is loaded and the server state is correct
 		loadAdapter(ServerBehaviourDelegate.class, null);
 		
-		boolean synchronous = ((ServerType)getServerType()).synchronousStart();
-		IStatus status = publishBeforeStart(monitor,synchronous);
-		
-		if (status != null && status.getSeverity() == IStatus.ERROR){
-			if (Trace.FINEST) {
-				Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
-			}
-			return;
-		}
-		
 		StartJob startJob = new StartJob(mode2);
 		// 287442 - only do publish after start if the server start is successful.
 		final IProgressMonitor monitor2 = monitor; 
-		final boolean synchronous2 = synchronous;
+		final boolean synchronous = ((ServerType)getServerType()).synchronousStart();
 		startJob.addJobChangeListener(new JobChangeAdapter() {
 			public void done(IJobChangeEvent event) {
 				IStatus resultStatus = event.getResult();
@@ -2023,17 +2040,29 @@
 								"Skipping auto publish after server start since the server start failed.");
 					}
 				} else {
-					publishAfterStart(monitor2,synchronous2,null);
+					publishAfterStart(monitor2,synchronous,null);
 				}
 			}
 		});
-		startJob.schedule();
-		try {
-			if(synchronous)
-				startJob.join();
-		} catch (InterruptedException e) {
-			if (Trace.WARNING) {
-				Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+		// Forces synchronous start since this method is supposed to wait until the publish operation is completed.
+		IStatus status = publishBeforeStart(monitor, startJob, true);
+		
+		if (status != null && status.getSeverity() == IStatus.ERROR){
+			if (Trace.FINEST) {
+				Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
+			}
+			return;
+		}
+		
+		if (((ServerType)getServerType()).startBeforePublish()) {
+			startJob.schedule();
+			try {
+				if(synchronous)
+					startJob.join();
+			} catch (InterruptedException e) {
+				if (Trace.WARNING) {
+					Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+				}
 			}
 		}
 	}
@@ -2051,18 +2080,6 @@
 		// make sure that the delegate is loaded and the server state is correct
 		loadAdapter(ServerBehaviourDelegate.class, null);
 		
-		boolean synchronous = ((ServerType)getServerType()).synchronousStart();
-		IStatus status = publishBeforeStart(null,synchronous);
-		
-		if (status != null && status.getSeverity() == IStatus.ERROR){
-			if (Trace.FINEST) {
-				Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
-			}
-			if (opListener != null)
-				opListener.done(Status.OK_STATUS);
-			return;
-		}
-
 		// check the publish flag (again) to determine when to call opListener.done 
 		byte pub = StartJob.PUBLISH_NONE;
 		if (ServerCore.isAutoPublishing() && shouldPublish()) {
@@ -2084,13 +2101,28 @@
 				}
 			});
 		}
+		
+		final boolean synchronous = ((ServerType)getServerType()).synchronousStart();
+		// For publish before start servers, the start job will only be kicked off if the publishing
+		// operation is completed successfully.
+		IStatus status = publishBeforeStart(null, startJob, synchronous);
+		
+		if (status != null && status.getSeverity() == IStatus.ERROR){
+			if (Trace.FINEST) {
+				Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
+			}
+			if (opListener != null)
+				opListener.done(Status.OK_STATUS);
+			return;
+		}
+
 		// 287442 - only do publish after start if the server start is successful.
-		final boolean synchronous2 = synchronous;
 		if (pub == StartJob.PUBLISH_AFTER) {
 			startJob.addJobChangeListener(new JobChangeAdapter() {
 				public void done(IJobChangeEvent event) {
 					IStatus resultStatus = event.getResult();
 					if (resultStatus != null && resultStatus.getSeverity() == IStatus.ERROR) { 
+						// Do not launch the publish.
 						if (Trace.INFO) {
 							Trace.trace(Trace.STRING_INFO,
 									"Skipping auto publish after server start since the server start failed.");
@@ -2099,19 +2131,19 @@
 							opListener.done(Status.OK_STATUS);
 					}
 					else {
-						publishAfterStart(null,synchronous2,opListener);
+						publishAfterStart(null,synchronous,opListener);
 					}
 				}
 			});
-		}
-		startJob.schedule();
-		
-		try {
-			if(synchronous)
-				startJob.join();
-		} catch (InterruptedException e) {
-			if (Trace.WARNING) {
-				Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+			startJob.schedule();
+			
+			try {
+				if(synchronous)
+					startJob.join();
+			} catch (InterruptedException e) {
+				if (Trace.WARNING) {
+					Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+				}
 			}
 		}
 	}
@@ -2123,15 +2155,6 @@
 		// make sure that the delegate is loaded and the server state is correct
 		loadAdapter(ServerBehaviourDelegate.class, monitor);
 		
-		IStatus status = publishBeforeStart(monitor,true);
-		
-		if (status != null && status.getSeverity() == IStatus.ERROR){
-			if (Trace.FINEST) {
-				Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
-			}
-			return;
-		}
-		
 		StartJob startJob = new StartJob(mode2);
 		// 287442 - only do publish after start if the server start is successful.
 		final IProgressMonitor monitor2 = monitor; 
@@ -2148,13 +2171,25 @@
 				}
 			}
 		});
-		startJob.schedule();
 		
-		try {
-			startJob.join();
-		} catch (InterruptedException e) {
-			if (Trace.WARNING) {
-				Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+		IStatus status = publishBeforeStart(monitor, startJob, true);
+		
+		if (status != null && status.getSeverity() == IStatus.ERROR){
+			if (Trace.FINEST) {
+				Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
+			}
+			return;
+		}
+		
+		if (((ServerType)getServerType()).startBeforePublish()) {
+			startJob.schedule();
+			
+			try {
+				startJob.join();
+			} catch (InterruptedException e) {
+				if (Trace.WARNING) {
+					Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+				}
 			}
 		}
 	}
@@ -2712,8 +2747,7 @@
 									notified.notifyAll();
 								} catch (Exception e) {
 									if (Trace.SEVERE) {
-										Trace.trace(Trace.STRING_SEVERE,
-												"Error notifying runAndWait", e);
+										Trace.trace(Trace.STRING_SEVERE, "Error notifying runAndWait", e);
 									}
 								}
 							}
@@ -2772,8 +2806,7 @@
 					}
 				} catch (Exception e) {
 					if (Trace.SEVERE) {
-						Trace.trace(Trace.STRING_SEVERE,
-								"Error notifying runAndWait timeout", e);
+						Trace.trace(Trace.STRING_SEVERE, "Error notifying runAndWait timeout", e);
 					}
 				}
 			}
@@ -2812,8 +2845,7 @@
 				}
 			} catch (Exception e) {
 				if (Trace.SEVERE) {
-					Trace.trace(Trace.STRING_SEVERE,
-							"Error waiting for operation", e);
+					Trace.trace(Trace.STRING_SEVERE, "Error waiting for operation", e);
 				}
 			}
 			timer.alreadyDone = true;
@@ -2853,9 +2885,8 @@
 							getBehaviourDelegate(monitor2).startModule(module, monitor2);
 						} catch (Exception e) {
 							if (Trace.SEVERE) {
-								Trace.trace(Trace.STRING_SEVERE,
-										"Error calling delegate startModule() "
-												+ toString(), e);
+								Trace.trace(Trace.STRING_SEVERE, "Error calling delegate startModule() " + toString(),
+										e);
 							}
 							throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, e.getMessage()));
 						}
@@ -2896,9 +2927,7 @@
 							getBehaviourDelegate(monitor2).stopModule(module, monitor2);
 						} catch (Exception e) {
 							if (Trace.SEVERE) {
-								Trace.trace(Trace.STRING_SEVERE,
-										"Error calling delegate stopModule() "
-												+ toString(), e);
+								Trace.trace(Trace.STRING_SEVERE, "Error calling delegate stopModule() " + toString(), e);
 							}
 							throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, e.getMessage()));
 						}
@@ -2940,8 +2969,7 @@
 						} catch (Exception e) {
 							if (Trace.SEVERE) {
 								Trace.trace(Trace.STRING_SEVERE,
-										"Error calling delegate restartModule() "
-												+ toString(), e);
+										"Error calling delegate restartModule() " + toString(), e);
 							}
 							throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, e.getMessage()));
 						}
@@ -3125,8 +3153,7 @@
 				getBehaviourDelegate(monitor).publish(kind, modules4, monitor, info);
 			} catch (CoreException ce) {
 				if (Trace.WARNING) {
-					Trace.trace(Trace.STRING_WARNING,
-							"Error during publishing", ce);
+					Trace.trace(Trace.STRING_WARNING, "Error during publishing", ce);
 				}
 				status = ce.getStatus();
 			}
@@ -3154,10 +3181,7 @@
 			return status;
 		} catch (Exception e) {
 			if (Trace.SEVERE) {
-				Trace.trace(
-						Trace.STRING_SEVERE,
-						"Error calling delegate publish() "
-								+ Server.this.toString(), e);
+				Trace.trace(Trace.STRING_SEVERE, "Error calling delegate publish() " + Server.this.toString(), e);
 			}
 			return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorPublishing, e);
 		}
@@ -3168,6 +3192,7 @@
 			Trace.trace(Trace.STRING_FINEST, "Restarting server: " + getName());
 		}
 		
+		ISchedulingRule curRule = null;
 		try {
 			try {
 				// synchronous restart
@@ -3184,14 +3209,21 @@
 			}
 			// if restart is not implemented by the server adopter
 			// lets provide a default implementation
+			// Ending the current rule setup by the RestartJob to prevent deadlock since the StopJob triggered
+			// by the stop(false) also setup the Server as the scheduling rule.
+			curRule = Job.getJobManager().currentRule();
+			Job.getJobManager().endRule(curRule);
 			stop(false);
 			start(launchMode, monitor);
-
 		} catch (Exception e) {
 			if (Trace.SEVERE) {
 				Trace.trace(Trace.STRING_SEVERE, "Error restarting server", e);
 			}
 			return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorStartFailed, getName()), e);
+		} finally {
+			if (curRule != null) {
+				Job.getJobManager().beginRule(curRule, monitor);
+			}
 		}
 		return Status.OK_STATUS;
 	}
@@ -3224,8 +3256,7 @@
 								notified.notifyAll();
 							} catch (Exception e) {
 								if (Trace.SEVERE) {
-									Trace.trace(Trace.STRING_SEVERE,
-											"Error notifying server restart", e);
+									Trace.trace(Trace.STRING_SEVERE, "Error notifying server restart", e);
 								}
 							}
 						}
@@ -3284,8 +3315,7 @@
 					}
 				} catch (Exception e) {
 					if (Trace.SEVERE) {
-						Trace.trace(Trace.STRING_SEVERE,
-								"Error notifying server restart timeout", e);
+						Trace.trace(Trace.STRING_SEVERE, "Error notifying server restart timeout", e);
 					}
 				}
 			}
@@ -3325,8 +3355,7 @@
 				}
 			} catch (Exception e) {
 				if (Trace.SEVERE) {
-					Trace.trace(Trace.STRING_SEVERE,
-							"Error waiting for server restart", e);
+					Trace.trace(Trace.STRING_SEVERE, "Error waiting for server restart", e);
 				}
 			}
 			timer.alreadyDone = true;
@@ -3370,8 +3399,7 @@
 								notified.notifyAll();
 							} catch (Exception e) {
 								if (Trace.SEVERE) {
-									Trace.trace(Trace.STRING_SEVERE,
-											"Error notifying server start", e);
+									Trace.trace(Trace.STRING_SEVERE, "Error notifying server start", e);
 								}
 							}
 						}
@@ -3430,8 +3458,7 @@
 					}
 				} catch (Exception e) {
 					if (Trace.SEVERE) {
-						Trace.trace(Trace.STRING_SEVERE,
-								"Error notifying server start timeout", e);
+						Trace.trace(Trace.STRING_SEVERE, "Error notifying server start timeout", e);
 					}
 				}
 			}
@@ -3470,8 +3497,7 @@
 				}
 			} catch (Exception e) {
 				if (Trace.SEVERE) {
-					Trace.trace(Trace.STRING_SEVERE,
-							"Error waiting for server start", e);
+					Trace.trace(Trace.STRING_SEVERE, "Error waiting for server start", e);
 				}
 			}
 			timer.alreadyDone = true;
@@ -3520,8 +3546,7 @@
 			}
 		} catch (CoreException e) {
 			if (Trace.SEVERE) {
-				Trace.trace(Trace.STRING_SEVERE, "Error starting server "
-						+ Server.this.toString(), e);
+				Trace.trace(Trace.STRING_SEVERE, "Error starting server " + Server.this.toString(), e);
 			}
 			throw e;
 		}
@@ -3544,8 +3569,7 @@
 								mutex.notifyAll();
 							} catch (Exception e) {
 								if (Trace.SEVERE) {
-									Trace.trace(Trace.STRING_SEVERE,
-											"Error notifying server stop", e);
+									Trace.trace(Trace.STRING_SEVERE, "Error notifying server stop", e);
 								}
 							}
 						}
@@ -3566,7 +3590,7 @@
 		if (serverTimeout > 0) {
 			thread = new Thread("Server Stop Timeout") {
 				public void run() {
-					try {					
+					try {
 						int totalTimeout = serverTimeout;
 						if (totalTimeout < 0)
 							totalTimeout = 1;
@@ -3591,8 +3615,7 @@
 						}
 					} catch (Exception e) {
 						if (Trace.SEVERE) {
-							Trace.trace(Trace.STRING_SEVERE,
-									"Error notifying server stop timeout", e);
+							Trace.trace(Trace.STRING_SEVERE, "Error notifying server stop timeout", e);
 						}
 					}
 				}
@@ -3615,8 +3638,7 @@
 					mutex.wait();
 			} catch (Exception e) {
 				if (Trace.SEVERE) {
-					Trace.trace(Trace.STRING_SEVERE,
-							"Error waiting for server stop", e);
+					Trace.trace(Trace.STRING_SEVERE, "Error waiting for server stop", e);
 				}
 			}
 			timer.alreadyDone = true;
@@ -3647,18 +3669,12 @@
 			getBehaviourDelegate(null).stop(force);
 		} catch (RuntimeException e) {
 			if (Trace.SEVERE) {
-				Trace.trace(
-						Trace.STRING_SEVERE,
-						"Error calling delegate stop() "
-								+ Server.this.toString(), e);
+				Trace.trace(Trace.STRING_SEVERE, "Error calling delegate stop() " + Server.this.toString(), e);
 			}
 			throw e;
 		} catch (Throwable t) {
 			if (Trace.SEVERE) {
-				Trace.trace(
-						Trace.STRING_SEVERE,
-						"Error calling delegate stop() "
-								+ Server.this.toString(), t);
+				Trace.trace(Trace.STRING_SEVERE, "Error calling delegate stop() " + Server.this.toString(), t);
 			}
 			throw new RuntimeException(t);
 		}
diff --git a/plugins/org.eclipse.wst.server.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.server.ui/META-INF/MANIFEST.MF
index 58d7488..5e9f90b 100644
--- a/plugins/org.eclipse.wst.server.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.wst.server.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.wst.server.ui; singleton:=true
-Bundle-Version: 1.1.211.qualifier
+Bundle-Version: 1.1.212.qualifier
 Bundle-Activator: org.eclipse.wst.server.ui.internal.ServerUIPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Messages.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Messages.java
index f29fe0f..8c9e3eb 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Messages.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Messages.java
@@ -1,5 +1,5 @@
 /**********************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * Copyright (c) 2005, 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
@@ -267,6 +267,7 @@
 	public static String editorRenameFiles;
 	public static String errorEditorCantSave;
 	public static String errorDuplicateName;
+	public static String errorDuplicateServerName;
 	public static String editorReadOnly;
 	public static String editorWritable;
 	public static String editorResourceModifiedTitle;
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Messages.properties b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Messages.properties
index d4148fe..b6b0e02 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Messages.properties
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/Messages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2004, 2011 IBM Corporation and others.
+# Copyright (c) 2004, 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
@@ -400,6 +400,7 @@
 errorConfigurationNotAccessible=The server configuration is not accessible. The {0} project is closed.
 errorRootModule=Could not find a valid parent module to add to the server.
 errorDuplicateName=The name is already in use. Specify a different name.
+errorDuplicateServerName=The server name is already in use. Specify a different name.
 
 # Info messages
 infoNoRuntimesFound=No new server runtime environments were found.
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/RuntimePreferencePage.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/RuntimePreferencePage.java
index 16b86f3..1283443 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/RuntimePreferencePage.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/RuntimePreferencePage.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
@@ -281,7 +281,7 @@
 						Trace.trace(Trace.STRING_SEVERE, "Error finding runtimes", ex);
 					}
 				}
-				runtimeComp.refresh();
+				runtimeComp2.refresh();
 			}
 		});
 		
@@ -434,7 +434,7 @@
 		final RuntimeComposite runtimeComp2 = this.runtimeComp;
 		Display.getDefault().asyncExec(new Runnable(){
 			public void run(){
-				runtimeComp2.add(runtime);
+				runtimeComp2.refresh();
 			}
 		});
 	}
@@ -442,7 +442,7 @@
 		final RuntimeComposite runtimeComp2 = this.runtimeComp;
 		Display.getDefault().asyncExec(new Runnable(){
 			public void run(){
-				runtimeComp2.remove(runtime);
+				runtimeComp2.refresh();
 			}
 		});
 	}
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/ServerToolTip.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/ServerToolTip.java
index 1ff11a6..e84746f 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/ServerToolTip.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/ServerToolTip.java
@@ -86,7 +86,16 @@
 				| SWT.NO_FOCUS);
 		stickyTooltip.setLayout(new FillLayout());
 		stickyTooltip.setBackground(stickyTooltip.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-		
+		stickyTooltip.addShellListener(new ShellAdapter() {
+			public void shellClosed(ShellEvent e) {
+				if (CURRENT_TOOLTIP != null) {
+					CURRENT_TOOLTIP.dispose();
+					CURRENT_TOOLTIP = null;
+				}
+				activate();
+			}
+		});
+
 		control.getDisplay().asyncExec(new Runnable() {
 			public void run() {
 				Event event = new Event();
@@ -130,8 +139,25 @@
 	}
 
 	protected final boolean shouldCreateToolTip(Event event) {
-		if (tree.getItem(new Point(event.x, event.y)) == null)
+		Object o = tree.getItem(new Point(event.x, event.y));
+		if (o == null) {
 			return false;
+		}
+		IServer server = null;
+		IServerModule module = null;
+		if (o instanceof TreeItem) {
+			Object obj = ((TreeItem)o).getData();
+			if (obj instanceof IServer) {
+				server = (IServer) obj;
+			}
+			if (obj instanceof IServerModule) {
+				module = (IServerModule) obj;
+			}
+		}
+		// Only enable for supported objects.
+		if (server == null && module == null) {
+			return false;
+		}
 		return super.shouldCreateToolTip(event);
 	}
 
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewRuntimeWizardFragment.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewRuntimeWizardFragment.java
index 273d1ed..2aaa32f 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewRuntimeWizardFragment.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewRuntimeWizardFragment.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2007 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
@@ -40,6 +40,10 @@
 
 	protected Map<String, WizardFragment> fragmentMap = new HashMap<String, WizardFragment>();
 
+	// Storing the NewRuntimeComposite is required to determine if the selected item
+	// by the user is a valid server runtime
+	protected NewRuntimeComposite comp;
+	
 	public NewRuntimeWizardFragment() {
 		// do nothing
 	}
@@ -58,7 +62,8 @@
 	 * @see org.eclipse.wst.server.ui.internal.task.WizardTask#getWizardPage()
 	 */
 	public Composite createComposite(Composite parent, IWizardHandle wizard) {
-		return new NewRuntimeComposite(parent, wizard, getTaskModel(), type, version, runtimeTypeId);
+		comp = new NewRuntimeComposite(parent, wizard, getTaskModel(), type, version, runtimeTypeId);
+		return comp;
 	}
 
 	public List getChildFragments() {
@@ -121,4 +126,13 @@
 			fragmentMap.put(typeId, fragment);
 		return fragment;
 	}
+	
+	public boolean isComplete(){
+		// If the selected runtime is invalid, the wizard 
+		// should not allow the user to press Finish
+		if (comp.hasValidSelectedRuntime()){
+			return true;
+		}
+		return false;
+	}	
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewServerWizardFragment.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewServerWizardFragment.java
index 5747e58..ba6c982 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewServerWizardFragment.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/fragment/NewServerWizardFragment.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
@@ -149,10 +149,15 @@
 		if(getServer().getServerType() == null)
 			return false;
 		
-		return checkHostAndServerType();
+		return checkValidInput();
 	}
 	
-	private boolean checkHostAndServerType(){
+	/*
+	 * Checks for valid host name, server type, and server name
+	 * 
+	 * @return true if input is valid, false otherwise
+	 */
+	private boolean checkValidInput(){
 		boolean isComplete = false;
 
 		boolean supportsRemote = getServer().getServerType().supportsRemoteHosts();
@@ -165,6 +170,10 @@
 					return false;
 				}
 				
+				if (manualComp.isServerNameInUse()){
+					return false;
+				}
+				
 				if (manualComp.getCurrentHostname().trim().length() == 0){
 					isComplete = false;
 				} else if(!supportsRemote && !SocketUtil.isLocalhost(manualComp.getCurrentHostname())){
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewManualServerComposite.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewManualServerComposite.java
index f54a7de..2e5be30 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewManualServerComposite.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewManualServerComposite.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
@@ -40,6 +40,7 @@
 import org.eclipse.ui.dialogs.PreferencesUtil;
 import org.eclipse.ui.help.IWorkbenchHelpSystem;
 import org.eclipse.wst.server.core.*;
+import org.eclipse.wst.server.core.internal.ServerPlugin;
 import org.eclipse.wst.server.core.internal.ServerWorkingCopy;
 import org.eclipse.wst.server.core.util.SocketUtil;
 import org.eclipse.wst.server.ui.AbstractUIControl;
@@ -110,6 +111,10 @@
 	
 	private boolean canSupportModule=true;
 
+	// These variables deal with caching server name checks
+	private boolean isServerNameInUse=false;
+	private String cacheServerNameCheck="";
+	
 	/**
 	 * Creates a new server and server configuration.  If the initial
 	 * resource selection contains exactly one container resource then it will be
@@ -236,6 +241,13 @@
 					return;
 				
 				String name = serverName.getText();
+								
+				IServerType selectedServerType = serverTypeComposite.getSelectedServerType();
+				if (!validate(selectedServerType)) {
+					// Do not set the server name if it is invalid
+					return;			
+				}
+				
 				if (server != null) {
 					server.setName(name);
 					IRuntime runtime2 = server.getRuntime();
@@ -392,7 +404,7 @@
 	protected void handleHostnameChange(IServerType serverType) {
 
 		wizard.setMessage(null, IMessageProvider.NONE);
-		if (!checkHostAndServerType(serverType)) {
+		if (!validate(serverType)) {
 			return;// Host name validation failed, so there is no need to continue handling hostname change event			
 		}
 		loadServerImpl(serverType);
@@ -438,10 +450,23 @@
 			wizard.setMessage(NLS.bind(Messages.wizCheckRemoteSupport, new Object[0]), IMessageProvider.ERROR);
 			return false;
 		}
-		
+
 		return true;
 	}
 	
+	protected boolean checkServerName(){		
+		if (isServerNameInUse()){
+			wizard.setMessage(Messages.errorDuplicateServerName, IMessageProvider.ERROR);
+			return false;			
+		}
+		return true;
+	}
+	
+	protected boolean validate(IServerType selectedServerType){
+		wizard.setMessage(null, IMessageProvider.NONE);
+		return (checkHostAndServerType(selectedServerType) & checkServerName());
+	}
+	
 	/**
 	 * Load a server of the given type.
 	 */
@@ -723,7 +748,7 @@
 		// Update the old server type value.
 		oldServerType = serverType;
 
-		checkHostAndServerType(serverType);
+		validate(serverType);
 		wizard.update();
 	}
 
@@ -883,4 +908,28 @@
 			hostName = host;
 		}
 	}
+	
+	/**
+	 * Determines if the server name is in use. The server name that is checked
+	 * is cached to increase performance on multiple calls. 
+	 * 
+	 * @return true if name is in use, false otherwise
+	 */
+	public boolean isServerNameInUse(){
+		String myServerName="";
+		if (serverName != null){
+			myServerName = serverName.getText().trim();
+			// If the server name is equal to the cached server name, then return the
+			// previously cached value. If the server name is not equal to the cached
+			// server name, check to see if the name is in use
+			if (!cacheServerNameCheck.equals(myServerName)){
+				cacheServerNameCheck = myServerName;
+				isServerNameInUse = ServerPlugin.isNameInUse(server, serverName.getText().trim());				
+			}
+			return isServerNameInUse;			
+		}
+
+		// If the widget is null, return false
+		return false;
+	}	
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewRuntimeComposite.java b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewRuntimeComposite.java
index 5962e97..c8d69d0 100644
--- a/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewRuntimeComposite.java
+++ b/plugins/org.eclipse.wst.server.ui/serverui/org/eclipse/wst/server/ui/internal/wizard/page/NewRuntimeComposite.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
@@ -202,4 +202,17 @@
 					c[i].setVisible(visible);
 		}
 	}
+	
+	/**
+	 * 
+	 * Determines if the selected runtime is a
+	 * valid. 
+	 * 
+	 */
+	public boolean hasValidSelectedRuntime(){
+		if (runtime == null){
+			return false;
+		}
+		return true;
+	}
 }
\ No newline at end of file