### Eclipse Workspace Patch 1.0
#P org.jboss.tools.deltacloud.ui
Index: src/org/jboss/tools/internal/deltacloud/ui/wizards/CloudConnectionPageModel.java
===================================================================
--- src/org/jboss/tools/internal/deltacloud/ui/wizards/CloudConnectionPageModel.java	(revision 29980)
+++ src/org/jboss/tools/internal/deltacloud/ui/wizards/CloudConnectionPageModel.java	(working copy)
@@ -11,14 +11,21 @@
 package org.jboss.tools.internal.deltacloud.ui.wizards;
 
 import java.net.MalformedURLException;
+import java.text.MessageFormat;
 
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.jboss.tools.deltacloud.core.DeltaCloud;
+import org.jboss.tools.deltacloud.core.DeltaCloudException;
 import org.jboss.tools.deltacloud.core.Driver;
-import org.jboss.tools.internal.deltacloud.core.observable.ObservablePojo;
+import org.jboss.tools.internal.deltacloud.ui.common.databinding.validator.ObservableUIPojo;
 
 /**
  * @author Andre Dietisheim
  */
-public class CloudConnectionPageModel extends ObservablePojo {
+public class CloudConnectionPageModel extends ObservableUIPojo {
 
 	public static final String PROPERTY_URL = "url"; //$NON-NLS-1$
 	public static final String PROPERTY_NAME = "name"; //$NON-NLS-1$
@@ -49,10 +56,11 @@
 	public CloudConnectionPageModel(String name, String url, String username, String password, Driver driver) {
 		this.name = name;
 		this.initialName = name;
-			this.url = url;
+		this.url = url;
 		this.username = username;
 		this.password = password;
-		this.driver = driver;
+		// this.driver = driver;
+		setDriverByUrl(url);
 	}
 
 	public String getUsername() {
@@ -98,4 +106,41 @@
 	public void setDriver(Driver driver) {
 		firePropertyChange(PROPERTY_DRIVER, this.driver, this.driver = driver);
 	}
+
+	/**
+	 * Sets the driver for a given cloud url. Queries the cloud at the given url
+	 * and determine its driver.
+	 * 
+	 * @param cloudUrl
+	 *            the url of the cloud to query
+	 */
+	public void setDriverByUrl(final String url) {
+		setDriver(Driver.UNKNOWN);
+		new Job(MessageFormat.format("Determining driver for cloud at url {0}", url)) {
+
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				Driver driver = getDriverFor(url);
+				setDriver(driver);
+				return Status.OK_STATUS;
+			}
+
+		}.schedule();
+	}
+
+	private Driver getDriverFor(String url) {
+		try {
+			return DeltaCloud.getServerDriver(url);
+		} catch (DeltaCloudException e) {
+			return Driver.UNKNOWN;
+		}
+	}
+
+	public boolean isKnownCloud(Object value) {
+		if (value instanceof Driver) {
+			Driver driver = (Driver) value;
+			return driver != Driver.UNKNOWN;
+		}
+		return false;
+	}
 }
Index: src/org/jboss/tools/internal/deltacloud/ui/common/swt/JFaceUtils.java
===================================================================
--- src/org/jboss/tools/internal/deltacloud/ui/common/swt/JFaceUtils.java	(revision 29564)
+++ src/org/jboss/tools/internal/deltacloud/ui/common/swt/JFaceUtils.java	(working copy)
@@ -19,10 +19,14 @@
 public class JFaceUtils {
 
 	public static ControlDecoration createDecoration(Control control, String message) {
+		return createDecoration(control, message, FieldDecorationRegistry.DEC_ERROR);
+	}
+
+	public static ControlDecoration createDecoration(Control control, String message, String decorationId) {
 		ControlDecoration controlDecoration = new ControlDecoration(control, SWT.LEFT | SWT.TOP);
 		controlDecoration.setDescriptionText(message);
 		FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault()
-				.getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+				.getFieldDecoration(decorationId);
 		controlDecoration.setImage(fieldDecoration.getImage());
 		return controlDecoration;
 	}
Index: src/org/jboss/tools/internal/deltacloud/ui/wizards/CloudConnectionPage.java
===================================================================
--- src/org/jboss/tools/internal/deltacloud/ui/wizards/CloudConnectionPage.java	(revision 29980)
+++ src/org/jboss/tools/internal/deltacloud/ui/wizards/CloudConnectionPage.java	(working copy)
@@ -35,6 +35,7 @@
 import org.eclipse.jface.databinding.wizard.WizardPageSupport;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.wizard.WizardPage;
 import org.eclipse.swt.SWT;
@@ -59,7 +60,6 @@
 import org.jboss.tools.deltacloud.core.DeltaCloudException;
 import org.jboss.tools.deltacloud.core.DeltaCloudManager;
 import org.jboss.tools.deltacloud.core.Driver;
-import org.jboss.tools.deltacloud.core.client.DeltaCloudClientImpl.DeltaCloudServerType;
 import org.jboss.tools.deltacloud.ui.Activator;
 import org.jboss.tools.deltacloud.ui.SWTImagesFactory;
 import org.jboss.tools.internal.deltacloud.ui.common.databinding.validator.CompositeValidator;
@@ -67,6 +67,8 @@
 import org.jboss.tools.internal.deltacloud.ui.common.swt.JFaceUtils;
 import org.jboss.tools.internal.deltacloud.ui.preferences.IPreferenceKeys;
 import org.jboss.tools.internal.deltacloud.ui.preferences.StringPreferenceValue;
+import org.jboss.tools.internal.deltacloud.ui.utils.ControlDecorationAdapter;
+import org.jboss.tools.internal.deltacloud.ui.utils.DataBindingUtils;
 
 /**
  * @author Jeff Jonhston
@@ -113,40 +115,23 @@
 	};
 
 	/**
-	 * Displays the cloud type in the given label. Listens to ValueChangeEvents
-	 * and sets the given label accordingly.
-	 * 
-	 * @param typeLabel
-	 *            the label that shall display the delta cloud type
+	 * jface databinding converter that converts Driver values to displayable
+	 * text
 	 * 
-	 * @see IValueChangeListener
-	 * @see DeltaCloudServerType
+	 * @see Driver
 	 */
-	private class DeltaCloudTypeLabelAdapter implements IValueChangeListener {
-
-		private Label typeLabel;
-
-		public DeltaCloudTypeLabelAdapter(Driver cloudType, Label typeLabel) {
-			this.typeLabel = typeLabel;
-			init(cloudType);
-		}
+	private static class Driver2Label extends Converter {
 
-		private void init(Driver cloudType) {
-			setLabelText(cloudType);
+		private Driver2Label() {
+			super(Driver.class, String.class);
 		}
 
 		@Override
-		public void handleValueChange(ValueChangeEvent event) {
-			Object newValue = event.diff.getNewValue();
-			setLabelText(newValue);
-		}
-
-		private void setLabelText(Object cloudType) {
-			if (cloudType != null && !Driver.UNKNOWN.equals(cloudType)) {
-				typeLabel.setText(cloudType.toString());
-			} else {
-				typeLabel.setText("?"); // $NON-NLS-1$
+		public Object convert(Object fromObject) {
+			if (fromObject instanceof Driver) {
+				return ((Driver) fromObject).name();
 			}
+			return null;
 		}
 	}
 
@@ -351,7 +336,16 @@
 		Label typeLabel = new Label(container, SWT.NULL);
 		typeLabel.setText(WizardMessages.getString(CLOUDTYPE_LABEL));
 		Label computedTypeLabel = new Label(container, SWT.NULL);
-		Binding urlTypeBinding = bindCloudType(dbc, urlText, computedTypeLabel);
+		Binding typeLabelBinding = bindCloudType(dbc, urlText, computedTypeLabel);
+
+		// bind url text decoration to type
+		ControlDecoration decoration = JFaceUtils.createDecoration(
+				urlText, WizardMessages.getString("IllegalCloudUrl.msg"), FieldDecorationRegistry.DEC_WARNING);
+		IObservableValue validationStatusProvider = typeLabelBinding.getValidationStatus();
+		DataBindingUtils.addValueChangeListener(
+				new ControlDecorationAdapter(decoration, (IStatus) validationStatusProvider.getValue()),
+				typeLabelBinding.getValidationStatus(), urlText);
+
 
 		// set url from preferences
 		String url =
@@ -380,16 +374,16 @@
 		// test button
 		final Button testButton = new Button(container, SWT.NULL);
 		testButton.setText(WizardMessages.getString(TESTBUTTON_LABEL));
-		boolean isUrlValid = ((IStatus) urlTypeBinding.getValidationStatus().getValue()).getSeverity() == IStatus.OK;
-		urlTypeBinding.getValidationStatus().addValueChangeListener(
-				enableButtonOnUrlValidityChanges(testButton, isUrlValid));
+		bindTestButtonEnablement(testButton, dbc);
 
 		CredentialsTestAdapter credentialsTestAdapter = new CredentialsTestAdapter(
 				usernameText,
 				passwordText);
 		testButton.addSelectionListener(credentialsTestAdapter);
-		usernameObservable.addValueChangeListener(credentialsTestAdapter);
-		passwordTextObservable.addValueChangeListener(credentialsTestAdapter);
+		DataBindingUtils.addValueChangeListener(
+				credentialsTestAdapter, usernameObservable, usernameText);
+		DataBindingUtils.addValueChangeListener(
+				credentialsTestAdapter, passwordTextObservable, passwordText);
 
 		// ec2 user link
 		Link ec2userLink = new Link(container, SWT.NULL);
@@ -482,24 +476,25 @@
 	}
 
 	/**
-	 * Enables/Disables (credentials) test button on url validity changes.
+	 * Enables/Disables (credentials) test button on changes in the driver
+	 * property of the model.
 	 * 
 	 * @param testButton
-	 *            the test button
-	 * @param isUrlValid
-	 * @return the i value change listener
+	 *            the test button to bind
+	 * @param dbc
+	 *            the databinding context to use
 	 */
-	private IValueChangeListener enableButtonOnUrlValidityChanges(final Button testButton, boolean isUrlValid) {
-
-		testButton.setEnabled(isUrlValid);
-		return new IValueChangeListener() {
-
-			@Override
-			public void handleValueChange(ValueChangeEvent event) {
-				IStatus status = (IStatus) event.diff.getNewValue();
-				testButton.setEnabled(status.isOK());
-			}
-		};
+	private void bindTestButtonEnablement(final Button testButton, DataBindingContext dbc) {
+		dbc.bindValue(
+				WidgetProperties.enabled().observe(testButton),
+				BeanProperties.value(CloudConnectionPageModel.PROPERTY_DRIVER).observe(connectionModel),
+				new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
+				new UpdateValueStrategy().setConverter(new Converter(Driver.class, Boolean.class) {
+					@Override
+					public Object convert(Object fromObject) {
+						return connectionModel.isKnownCloud(fromObject);
+					}
+				}));
 	}
 
 	/**
@@ -516,36 +511,43 @@
 	 * @param typeLabel
 	 *            the cloud type label to display the cloud type in
 	 * @return
+	 * @return
 	 * @return the binding that was created
 	 */
 	private Binding bindCloudType(DataBindingContext dbc, Text urlText, final Label typeLabel) {
-		UpdateValueStrategy updateStrategy = new UpdateValueStrategy();
-		Url2DriverConverter urlToCloudTypeConverter = new Url2DriverConverter();
-		updateStrategy.setConverter(urlToCloudTypeConverter);
-		updateStrategy.setBeforeSetValidator(new CloudDriverValidator());
 
-		// bind url to cloud type in model
-		Binding urlTypeBinding = dbc.bindValue(
-				WidgetProperties.text(SWT.Modify).observeDelayed(CLOUDTYPE_CHECK_DELAY, urlText),
+		// bind driver value to driver label
+		Binding typeLabelBinding = dbc.bindValue(
+				WidgetProperties.text().observe(typeLabel),
 				BeanProperties.value(CloudConnectionPageModel.PROPERTY_DRIVER).observe(connectionModel),
-				updateStrategy,
-				new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER));
-		/*
-		 * bind converter to delta cloud label.
-		 * 
-		 * Cloud type cannot be fetched from the model since invalid url's don't
-		 * get propagated to the model and no type update happens in this case.
-		 * We could not show invalid urls in the label if we would get the type
-		 * in the model.
-		 */
-		IObservableValue cloudTypeObservable = urlToCloudTypeConverter.getCloudTypeObservable();
-		Object value = cloudTypeObservable.getValue();
-		Assert.isTrue(value == null || value instanceof Driver);
-		DeltaCloudTypeLabelAdapter cloudTypeAdapter = new DeltaCloudTypeLabelAdapter((Driver) value, typeLabel);
-		cloudTypeObservable.addValueChangeListener(cloudTypeAdapter);
-		ControlDecorationSupport.create(urlTypeBinding, SWT.LEFT | SWT.TOP);
+				new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
+				new UpdateValueStrategy()
+						.setConverter(new Driver2Label())
+						.setAfterGetValidator(new IValidator() {
+							@Override
+							public IStatus validate(Object value) {
+								if (connectionModel.isKnownCloud(value)) {
+									return ValidationStatus.ok();
+								} else {
+									return ValidationStatus.warning(WizardMessages.getString("IllegalCloudUrl.msg"));
+								}
+							}
+						})
+				);
 
-		return urlTypeBinding;
+		// set driver value when user stops typing or moves focus away
+		DataBindingUtils.addValueChangeListener(
+				new IValueChangeListener() {
+
+					@Override
+					public void handleValueChange(ValueChangeEvent event) {
+						String url = (String) event.diff.getNewValue();
+						connectionModel.setDriverByUrl(url);
+					}
+				},
+				WidgetProperties.text(SWT.Modify).observeDelayed(CLOUDTYPE_CHECK_DELAY, urlText),
+				urlText);
+		return typeLabelBinding;
 	}
 
 	/**
Index: src/org/jboss/tools/internal/deltacloud/ui/utils/ControlDecorationAdapter.java
===================================================================
--- src/org/jboss/tools/internal/deltacloud/ui/utils/ControlDecorationAdapter.java	(revision 0)
+++ src/org/jboss/tools/internal/deltacloud/ui/utils/ControlDecorationAdapter.java	(revision 0)
@@ -0,0 +1,37 @@
+package org.jboss.tools.internal.deltacloud.ui.utils;
+
+import org.eclipse.core.databinding.observable.value.IValueChangeListener;
+import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+
+/**
+ * A listener that shows/hides given control decorations on changes in the
+ * validation status it listens to.
+ * 
+ * @author André Dietisheim
+ */
+public class ControlDecorationAdapter implements IValueChangeListener {
+	private ControlDecoration decoration;
+
+	public ControlDecorationAdapter(ControlDecoration decoration, IStatus initialStatus) {
+		this.decoration = decoration;
+		setDecorationVisible(initialStatus);
+	}
+
+	@Override
+	public void handleValueChange(ValueChangeEvent event) {
+		if (event.diff.getNewValue() instanceof IStatus) {
+			IStatus status = (IStatus) event.diff.getNewValue();
+			setDecorationVisible(status);
+		}
+	}
+
+	private void setDecorationVisible(IStatus status) {
+		if (!status.isOK()) {
+			decoration.show();
+		} else {
+			decoration.hide();
+		}
+	}
+}
