[126764] Download latest version of server adapter
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/InstallableRuntime.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/InstallableRuntime.java
index 741a77a..66431ec 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/InstallableRuntime.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/InstallableRuntime.java
@@ -18,18 +18,10 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.*;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.update.core.ISite;
-import org.eclipse.update.core.ISiteWithMirrors;
-import org.eclipse.update.core.IURLEntry;
-import org.eclipse.update.core.SiteManager;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
 import org.eclipse.update.standalone.InstallCommand;
 import org.osgi.framework.Bundle;
 /**
@@ -123,28 +115,43 @@
 		installRuntimeJob.schedule();
 	}
 
-	public static String getMirror(String fromSite, IProgressMonitor monitor) {
-		//	 if the site is a site containing mirrors, set the fromSite to the first
-		// mirror site since many mirror list generators will sort the mirrors to closest
-		// geographic location
-		String mirrorSite = null;
+	public static ISite getSite(String fromSite, IProgressMonitor monitor) {
 		try {
 			URL siteURL = new URL(fromSite);
-			ISite site = SiteManager.getSite(siteURL, monitor);
-			if (site != null && site instanceof ISiteWithMirrors) {
+			return SiteManager.getSite(siteURL, monitor);
+		} catch (MalformedURLException e) {
+			Trace.trace(Trace.WARNING, "Could not parse site", e);
+		} catch (CoreException e) {
+			Trace.trace(Trace.WARNING, "Could not parse site", e);
+		} catch (Exception e) {
+			Trace.trace(Trace.WARNING, "Could not parse site", e);
+		}
+		return null;
+	}
+
+	public static String getMirror(String fromSite, ISite site) {
+		if (site != null) {
+			String mirrorSite = getMirror(site);
+			if (mirrorSite != null) 
+				return mirrorSite;
+		}
+		return fromSite;
+	}
+
+	public static String getMirror(ISite site) {
+		// if the site is a site containing mirrors, set the fromSite to the
+		// first mirror site since many mirror list generators will sort the mirrors
+		// to closest geographic location
+		if (site != null && site instanceof ISiteWithMirrors) {
+			try {
 				IURLEntry[] urlEntries = ((ISiteWithMirrors) site).getMirrorSiteEntries();
 				if (urlEntries.length > 0)
-					mirrorSite = urlEntries[0].getURL().toExternalForm();
+					return urlEntries[0].getURL().toExternalForm();
+			} catch (CoreException e) {
+				Trace.trace(Trace.WARNING, "Could not find mirror site", e);
 			}
-		} catch (MalformedURLException e) {
-			Trace.trace(Trace.WARNING, "Could not find mirror site", e);
-		} catch (CoreException e) {
-			Trace.trace(Trace.WARNING, "Could not find mirror site", e);
 		}
-		
-		if (mirrorSite != null) 
-			return mirrorSite;
-		return fromSite;
+		return null;
 	}
 
 	/*
@@ -158,7 +165,8 @@
 		if (featureId == null || featureVersion == null || fromSite == null)
 			return;
 		
-		fromSite = getMirror(fromSite, monitor);
+		ISite site = getSite(fromSite, monitor);
+		fromSite = getMirror(fromSite, site);
 		
 		// download and install plugins
 		Bundle bundle = Platform.getBundle(getBundleId());
@@ -166,11 +174,15 @@
 			try {
 				monitor.setTaskName("Installing feature");
 				InstallCommand command = new InstallCommand(featureId, featureVersion, fromSite, null, "false");
-				command.run(monitor);
+				boolean b = command.run(monitor);
+				if (!b)
+					throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
+							Messages.errorInstallingServerFeature, null));
 				command.applyChangesNow();
 			} catch (Exception e) {
 				Trace.trace(Trace.SEVERE, "Error installing feature", e);
-				return;
+				throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
+						NLS.bind(Messages.errorInstallingServer, e.getLocalizedMessage()), e));
 			}
 		}
 		
@@ -203,7 +215,9 @@
 			}
 			zin.close();
 		} catch (Exception e) {
-			Trace.trace(Trace.SEVERE, "Error installing feature", e);
+			Trace.trace(Trace.SEVERE, "Error unzipping runtime", e);
+			throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
+					NLS.bind(Messages.errorInstallingServer, e.getLocalizedMessage()), e));
 		} 
 	}
 
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/InstallableServer.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/InstallableServer.java
index d716f6d..09637da 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/InstallableServer.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/InstallableServer.java
@@ -13,6 +13,13 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.PluginVersionIdentifier;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.core.VersionedIdentifier;
 import org.eclipse.update.standalone.InstallCommand;
 /**
  * 
@@ -121,14 +128,21 @@
 		if (featureId == null || featureVersion == null || fromSite == null)
 			return;
 		
-		fromSite = InstallableRuntime.getMirror(fromSite, monitor);
+		ISite site = InstallableRuntime.getSite(fromSite, monitor);
+		fromSite = InstallableRuntime.getMirror(fromSite, site);
+		featureVersion = getLatestVersion(site, featureVersion, featureId);
 		
 		try {
 			InstallCommand command = new InstallCommand(featureId, featureVersion, fromSite, null, "false");
-			command.run(monitor);
+			boolean b = command.run(monitor);
+			if (!b)
+				throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
+						Messages.errorInstallingServerFeature, null));
 			//command.applyChangesNow();
 		} catch (Exception e) {
 			Trace.trace(Trace.SEVERE, "Error installing feature", e);
+			throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0,
+					NLS.bind(Messages.errorInstallingServer, e.getLocalizedMessage()), e));
 		}
 		
 		try {
@@ -138,6 +152,31 @@
 		}
 	}
 
+	public static String getLatestVersion(ISite site, String version, String featureId) {
+		String latestVersion = null;
+		
+		try {
+			PluginVersionIdentifier pvi = new PluginVersionIdentifier(version);
+			ISiteFeatureReference[] features = site.getFeatureReferences();
+			
+			for (int i = 0; i < features.length; i++) {
+				if (features[i].getName().equals(featureId)) {
+					VersionedIdentifier vi = features[i].getVersionedIdentifier();
+					if (vi.getVersion().isGreaterThan(pvi)) {
+						latestVersion = vi.getIdentifier();
+						pvi = new PluginVersionIdentifier(latestVersion);
+					}
+				}
+			}
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error searching for latest feature version", e);
+		}
+		
+		if (latestVersion == null)
+			return version;
+		return latestVersion;
+	}
+
 	public String toString() {
 		return "InstallableServer[" + getId() + ", " + getName() + "]";
 	}
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Messages.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Messages.java
index 13e7b33..3152345 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Messages.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Messages.java
@@ -51,6 +51,8 @@
 	public static String errorStartTimeout;
 	public static String errorStartFailed;
 	public static String errorModuleRestartFailed;
+	public static String errorInstallingServer;
+	public static String errorInstallingServerFeature;
 	public static String canRestartModuleOk;
 	public static String errorRestartModule;
 	public static String canStartErrorState;
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Messages.properties b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Messages.properties
index 425bb01..5d9730a 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Messages.properties
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Messages.properties
@@ -45,6 +45,8 @@
 errorStartTimeout=Timeout waiting for {0} to start. Server did not start after {1}s. 
 errorStartFailed=Server {0} failed to start.
 errorCannotAddModule=The server does not support version {1} of the {0} specification.
+errorInstallingServer=Error occurred installing server: {0}
+errorInstallingServerFeature=Could not download and install update feature.
 
 # Default server creation names
 # {0} will be replaced by a number if the given name is already being used
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 fd9e3a0..10cebe0 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
@@ -1055,7 +1055,7 @@
 		try {
 			getBehaviourDelegate(monitor).setupLaunchConfiguration(workingCopy, monitor);
 		} catch (Exception e) {
-			Trace.trace(Trace.SEVERE, "Error calling delegate setLaunchDefaults() " + toString(), e);
+			Trace.trace(Trace.SEVERE, "Error calling delegate setupLaunchConfiguration() " + toString(), e);
 		}
 	}