Index: /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/CloudManagerClient.cs
===================================================================
--- /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/CloudManagerClient.cs	(revision 7386)
+++ /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/CloudManagerClient.cs	(revision 7387)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Clients.Hive.CloudManager.Azure;
 using HeuristicLab.Clients.Hive.CloudManager.Model;
@@ -39,4 +40,5 @@
     private CloudManagerClient() {
       subscriptions = new ItemList<Subscription>();
+      hostedServices = new ItemList<HostedService>();
       azureProvider = new AzureProvider();
     }
@@ -50,4 +52,14 @@
           subscriptions = value;
           //fire event OnSubscriptionsChagned
+        }
+      }
+    }
+
+    private IItemList<HostedService> hostedServices;
+    public IItemList<HostedService> HostedServices {
+      get { return hostedServices; }
+      set {
+        if (value != hostedServices) {
+          hostedServices = value;
         }
       }
@@ -86,5 +98,8 @@
         foreach (Subscription subscription in subs) {
           if (subscription.DiscoverServices) {
-            //Discover
+            List<HostedService> servs = AzureProvider.DiscoverSlaveService(subscription);
+            foreach (HostedService s in servs) {
+              Add(s);
+            }
           }
         }
@@ -119,5 +134,13 @@
     }
 
-
+    public void Add(HostedService hostedService) {
+      if (hostedService == null) {
+        throw new ArgumentNullException("subscription", "Subscription must not be null.");
+      }
+      if (HostedServices.Contains(hostedService)) {
+        HostedServices.Remove(hostedService);
+      }
+      HostedServices.Add(hostedService);
+    }
 
 
Index: /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/AddAzureServiceDialog.cs
===================================================================
--- /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/AddAzureServiceDialog.cs	(revision 7386)
+++ /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/AddAzureServiceDialog.cs	(revision 7387)
@@ -108,4 +108,11 @@
           }
       }
+    }
+
+    private bool ValidateInput() {
+      bool valid = true;
+      // TODO: input validation
+      // see http://stackoverflow.com/questions/769184/winform-ui-validation
+      return valid;
     }
 
@@ -159,30 +166,33 @@
       if (cmbChooseSubscription.SelectedItem != null) {
         Subscription sub = (Subscription)cmbChooseSubscription.SelectedItem;
-        bool newHostedServiceChecked = cbNewHostedService.Checked;
-        bool regionChecked = rbRegion.Checked;
-        string certFile = certificateFile;
-        string certPw = certificatePassword;
-        int instanceCount = Convert.ToInt32(tbInstanceCount.Text);
-        HostedService hostedService = new HostedService();
-        hostedService.ServiceName = tbServiceName.Text;
-        HostedServiceProperties properties = new HostedServiceProperties();
-        if (regionChecked) {
-          properties.AffinityGroup = string.Empty;
+        if (ValidateInput()) {
+          bool newHostedServiceChecked = cbNewHostedService.Checked;
+          bool regionChecked = rbRegion.Checked;
+          string certFile = certificateFile;
+          string certPw = certificatePassword;
+          int instanceCount = Convert.ToInt32(tbInstanceCount.Text);
+          HostedService hostedService = new HostedService();
+          hostedService.ServiceName = tbServiceName.Text;
+          HostedServiceProperties properties = new HostedServiceProperties();
+          if (regionChecked) {
+            properties.AffinityGroup = string.Empty;
+            properties.Location = (string)cmbLocation.SelectedItem;
+          } else {
+            properties.AffinityGroup = ((AffinityGroup)cmbAffinityGroup.SelectedItem).Name;
+            properties.Location = string.Empty;
+          }
+
+          properties.AffinityGroup = ((AffinityGroup)cmbAffinityGroup.SelectedItem).Name;
+          properties.Label = tbLabel.Text;
           properties.Location = (string)cmbLocation.SelectedItem;
-        } else {
-          properties.AffinityGroup = ((AffinityGroup)cmbAffinityGroup.SelectedItem).Name;
-          properties.Location = string.Empty;
-        }
-        properties.AffinityGroup = ((AffinityGroup)cmbAffinityGroup.SelectedItem).Name;
-        properties.Label = tbLabel.Text;
-        properties.Location = (string)cmbLocation.SelectedItem;
-        hostedService.HostedServiceProperties = properties;
-
-        var parameters = Tuple.Create<Subscription, bool, bool, string, string, HostedService, int>(sub, newHostedServiceChecked, regionChecked, certificateFile, certificatePassword, hostedService, instanceCount);
-
-        bwCompleted = false;
-        progressBar.Visible = true;
-        SetAllControlsEnabled(this, false);
-        workerCreate.RunWorkerAsync(parameters);
+          hostedService.HostedServiceProperties = properties;
+
+          var parameters = Tuple.Create<Subscription, bool, bool, string, string, HostedService, int>(sub, newHostedServiceChecked, regionChecked, certificateFile, certificatePassword, hostedService, instanceCount);
+
+          bwCompleted = false;
+          progressBar.Visible = true;
+          SetAllControlsEnabled(this, false);
+          workerCreate.RunWorkerAsync(parameters);
+        }
       }
     }
@@ -218,4 +228,5 @@
 
     private void CreateDoploymentTask(object sender, DoWorkEventArgs e) {
+      bool errorOccured = false;
       Tuple<Subscription, bool, bool, string, string, HostedService, int> parameters = (Tuple<Subscription, bool, bool, string, string, HostedService, int>)e.Argument;
 
@@ -229,20 +240,48 @@
 
       // STEP 1 - Create Hosted Service
-      if (newHostedServiceChecked) {
-        if (regionChecked) {
-          CloudManagerClient.Instance.AzureProvider.CreateHostedService(sub, hostedService.ServiceName, hostedService.HostedServiceProperties.Label, hostedService.HostedServiceProperties.Description, hostedService.HostedServiceProperties.Location);
-        } else {
-          CloudManagerClient.Instance.AzureProvider.CreateHostedService(sub, hostedService.ServiceName, hostedService.HostedServiceProperties.Label, hostedService.HostedServiceProperties.Description, new AffinityGroup() { Name = hostedService.HostedServiceProperties.AffinityGroup });
-        }
+      try {
+        if (newHostedServiceChecked) {
+          if (regionChecked) {
+            CloudManagerClient.Instance.AzureProvider.CreateHostedService(sub, hostedService.ServiceName, hostedService.HostedServiceProperties.Label, hostedService.HostedServiceProperties.Description, hostedService.HostedServiceProperties.Location);
+          } else {
+            CloudManagerClient.Instance.AzureProvider.CreateHostedService(sub, hostedService.ServiceName, hostedService.HostedServiceProperties.Label, hostedService.HostedServiceProperties.Description, new AffinityGroup() { Name = hostedService.HostedServiceProperties.AffinityGroup });
+          }
+        }
+      }
+      catch (Exception ex) {
+        errorOccured = true;
+        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
       }
 
       // STEP 2 - Add Certificate
-      if (certFile != string.Empty) {
-        CloudManagerClient.Instance.AzureProvider.AddCertificate(sub, hostedService, certFile, certPw);
+      try {
+        if ((!errorOccured) && (certFile != string.Empty)) {
+          CloudManagerClient.Instance.AzureProvider.AddCertificate(sub, hostedService, certFile, certPw);
+        }
+      }
+      catch (Exception ex) {
+        errorOccured = true;
+        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+        if (newHostedServiceChecked) {
+          CloudManagerClient.Instance.AzureProvider.DeleteHostedService(sub, hostedService.ServiceName);
+        }
+
       }
 
       // STEP 3 - Create Deployment
-      CloudManagerClient.Instance.AzureProvider.CreateDeployment(sub, hostedService.ServiceName, Guid.NewGuid().ToString(), Constants.DeploymentSlotStaging, Constants.DeploymentPackageUrl, Constants.DeploymentConfigurationUrl, Constants.DeploymentLabel, instanceCount);
-
+      try {
+        if (!errorOccured) {
+          CloudManagerClient.Instance.AzureProvider.CreateDeployment(sub, hostedService.ServiceName, Guid.NewGuid().ToString(), Constants.DeploymentSlotStaging, Constants.DeploymentPackageUrl, Constants.DeploymentConfigurationUrl, Constants.DeploymentLabel, instanceCount);
+        }
+      }
+      catch (Exception ex) {
+        errorOccured = true;
+        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+        if (newHostedServiceChecked) {
+          CloudManagerClient.Instance.AzureProvider.DeleteHostedService(sub, hostedService.ServiceName);
+        }
+      }
+
+      e.Result = errorOccured;
     }
 
@@ -251,6 +290,11 @@
       progressBar.Visible = false;
       bwCompleted = true;
+      bool errorOccured = (bool)e.Result;
       if (closePending) {
         this.Close();
+      } else if (!errorOccured) {
+        this.Close();
+      } else {
+        this.Show();
       }
     }
Index: /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/AddSubscriptionDialog.cs
===================================================================
--- /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/AddSubscriptionDialog.cs	(revision 7386)
+++ /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/AddSubscriptionDialog.cs	(revision 7387)
@@ -24,6 +24,15 @@
     }
 
+    private void SetAllControlsEnabled(Form frm, bool isEnabled) {
+      foreach (Control ctrl in frm.Controls) {
+        if (!(ctrl is ProgressBar)) {
+          ctrl.Enabled = isEnabled;
+        }
+      }
+    }
+
     private void btnOk_Click(object sender, System.EventArgs e) {
       this.progressBar.Visible = true;
+      SetAllControlsEnabled(this, false);
       worker.RunWorkerAsync();
     }
@@ -38,4 +47,5 @@
 
     private void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
+      SetAllControlsEnabled(this, true);
       progressBar.Visible = false;
       if (e.Error == null) {
Index: /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/CloudResourcesView.Designer.cs
===================================================================
--- /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/CloudResourcesView.Designer.cs	(revision 7386)
+++ /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/CloudResourcesView.Designer.cs	(revision 7387)
@@ -5,15 +5,4 @@
     /// </summary>
     private System.ComponentModel.IContainer components = null;
-
-    /// <summary> 
-    /// Clean up any resources being used.
-    /// </summary>
-    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-    protected override void Dispose(bool disposing) {
-      if (disposing && (components != null)) {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
 
     #region Component Designer generated code
@@ -106,6 +95,6 @@
       // treeCloudResources
       // 
-      this.treeCloudResources.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
-            | System.Windows.Forms.AnchorStyles.Left) 
+      this.treeCloudResources.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
             | System.Windows.Forms.AnchorStyles.Right)));
       this.treeCloudResources.ImageIndex = 0;
Index: /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/CloudResourcesView.cs
===================================================================
--- /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/CloudResourcesView.cs	(revision 7386)
+++ /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/CloudResourcesView.cs	(revision 7387)
@@ -1,5 +1,4 @@
 ﻿using System;
 using System.Diagnostics;
-using System.Threading;
 using System.Timers;
 using System.Windows.Forms;
@@ -16,6 +15,8 @@
     private int updateInterval = 15000;
     private DateTime dueTime;
+
     private const int subscriptionImageIndex = 0;
     private const int serviceImageIndex = 1;
+    private const int deploymentImageIndex = 2;
 
     public new IItemList<Subscription> Content {
@@ -24,11 +25,21 @@
     }
 
+    private IItemList<HostedService> hostedServices;
+    public IItemList<HostedService> HostedServices {
+      get { return hostedServices; }
+      set { hostedServices = value; }
+    }
+
     public CloudResourcesView() {
       InitializeComponent();
 
+      treeCloudResources.ImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.NewFolder);
       treeCloudResources.ImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.NetworkCenterLarge);
       treeCloudResources.ImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.MonitorLarge);
 
+      HostedServices = CloudManagerClient.Instance.HostedServices;
       Content = CloudManagerClient.Instance.Subscriptions;
+
+
       CloudManagerClient.Instance.Refreshing += new EventHandler(Instance_Refreshing);
       CloudManagerClient.Instance.Refreshed += new EventHandler(Instance_Refreshed);
@@ -41,11 +52,4 @@
     }
 
-    public new void Dispose() {
-      CloudManagerClient.Instance.Refreshing -= new EventHandler(Instance_Refreshing);
-      CloudManagerClient.Instance.Refreshed -= new EventHandler(Instance_Refreshed);
-      timer.Dispose();
-      Debug.WriteLine("Dispose");
-    }
-
     #region Register Content Events
     protected override void DeregisterContentEvents() {
@@ -60,4 +64,20 @@
     }
     #endregion
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+        CloudManagerClient.Instance.Refreshing -= new EventHandler(Instance_Refreshing);
+        CloudManagerClient.Instance.Refreshed -= new EventHandler(Instance_Refreshed);
+        timer.Stop();
+        timer.Dispose();
+        timer = null;
+      }
+      base.Dispose(disposing);
+    }
 
     protected override void SetEnabledStateOfControls() {
@@ -81,13 +101,35 @@
         treeCloudResources.Nodes.Clear();
       } else {
+        treeCloudResources.BeginUpdate();
         treeCloudResources.Nodes.Clear();
         foreach (Subscription sub in Content) {
-          TreeNode tn = new TreeNode();
-          tn.Tag = sub;
-          tn.Text = sub.SubscriptionName;
-          tn.ImageIndex = subscriptionImageIndex;
-          tn.SelectedImageIndex = tn.ImageIndex;
-          treeCloudResources.Nodes.Add(tn);
+          TreeNode nodeSub = new TreeNode();
+          nodeSub.Tag = sub;
+          nodeSub.Text = sub.SubscriptionName;
+          nodeSub.ImageIndex = subscriptionImageIndex;
+          nodeSub.SelectedImageIndex = nodeSub.ImageIndex;
+
+          foreach (HostedService s in HostedServices) {
+            if (s.SubscriptionId == sub.SubscriptionID) {
+              TreeNode nodeServ = new TreeNode();
+              nodeServ.Tag = s;
+              nodeServ.Text = s.HostedServiceProperties.Label;
+              nodeServ.ImageIndex = serviceImageIndex;
+              nodeServ.SelectedImageIndex = nodeServ.ImageIndex;
+
+              foreach (Deployment d in s.Deployments) {
+                TreeNode nodeDepl = new TreeNode();
+                nodeDepl.Tag = d;
+                nodeDepl.Text = d.Label + " (" + d.DeploymentSlot + ")";
+                nodeDepl.ImageIndex = deploymentImageIndex;
+                nodeDepl.SelectedImageIndex = nodeDepl.ImageIndex;
+                nodeServ.Nodes.Add(nodeDepl);
+              }
+              nodeSub.Nodes.Add(nodeServ);
+            }
+          }
+          treeCloudResources.Nodes.Add(nodeSub);
         }
+        treeCloudResources.EndUpdate();
       }
     }
@@ -95,8 +137,18 @@
     private void Instance_Refreshing(object sender, EventArgs e) {
       Debug.WriteLine("Instance_Refreshing");
+      //if (treeCloudResources.InvokeRequired) {
+      //  treeCloudResources.Invoke((MethodInvoker)delegate { OnContentChanged(); });
+      //} else {
+      //  OnContentChanged();
+      //}
     }
 
     private void Instance_Refreshed(object sender, EventArgs e) {
       Debug.WriteLine("Instance_Refreshed");
+      if (treeCloudResources.InvokeRequired) {
+        treeCloudResources.Invoke((MethodInvoker)delegate { OnContentChanged(); });
+      } else {
+        OnContentChanged();
+      }
     }
 
@@ -120,8 +172,10 @@
         // statistics
         Debug.WriteLine("perform update");
-        Thread.Sleep(1000);
+        CloudManagerClient.Instance.Refresh();
 
         dueTime = DateTime.Now.AddMilliseconds(updateInterval);
-        timer.Start();
+        if (timer != null) {
+          timer.Start();
+        }
       }
     }
Index: /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/HiveCloudManagerView.cs
===================================================================
--- /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/HiveCloudManagerView.cs	(revision 7386)
+++ /branches/HeuristicLab.Hive.Azure/HeuristicLab.Clients.Hive.CloudManager/3.3/Views/HiveCloudManagerView.cs	(revision 7387)
@@ -39,4 +39,5 @@
       InitializeComponent();
       cloudResourcesView.Content = CloudManagerClient.Instance.Subscriptions;
+      cloudResourcesView.HostedServices = CloudManagerClient.Instance.HostedServices;
     }
 
