Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave.Tests/Mocks/MockHiveService.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave.Tests/Mocks/MockHiveService.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave.Tests/Mocks/MockHiveService.cs	(revision 6006)
@@ -68,5 +68,5 @@
     }
 
-    public void updateJobs(List<Job> js, MockJob m) {
+    public void UpdateJobs(List<Job> js, MockJob m) {
       jobs = js;
       byte[] data = PersistenceUtil.Serialize(m);
@@ -80,5 +80,5 @@
 
       hiveExperiments = new List<HiveExperiment>();
-      hiveExperiments.Add(new HiveExperiment() { Id = Guid.NewGuid(), Name = "Hive Exp 1", Description = "", RootJobId = jobs[0].Id });
+      hiveExperiments.Add(new HiveExperiment() { Id = Guid.NewGuid(), Name = "Hive Exp 1", Description = "" });
 
       ResultJobDatas = new List<JobData>();
@@ -143,4 +143,8 @@
     public List<LightweightJob> GetLightweightChildJobs(Guid? parentJobId, bool recursive, bool includeParent) {
       return jobs.Where(j => j.ParentJobId.HasValue).Select(j => new LightweightJob(j)).ToList();
+    }
+
+    public List<LightweightJob> GetLightweightExperimentJobs(Guid experimentId) {
+      throw new NotImplementedException();
     }
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave.Tests/SlaveTest.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave.Tests/SlaveTest.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave.Tests/SlaveTest.cs	(revision 6006)
@@ -81,5 +81,5 @@
         MockHiveService ms = (MockHiveService)service;
         ((MockHiveService)service).Messages = CreateMsgsForSingleJob();
-        ((MockHiveService)service).updateJobs(jobList, job);
+        ((MockHiveService)service).UpdateJobs(jobList, job);
 
         HeuristicLab.Clients.Hive.SlaveCore.Core core = new SlaveCore.Core();
@@ -119,5 +119,5 @@
         MockHiveService ms = (MockHiveService)service;
         ((MockHiveService)service).Messages = CreateMsgsForShutdownSlaveWhileJobRunning();
-        ((MockHiveService)service).updateJobs(jobList, job);
+        ((MockHiveService)service).UpdateJobs(jobList, job);
 
 
@@ -183,5 +183,5 @@
         MockHiveService ms = (MockHiveService)service;
         ((MockHiveService)service).Messages = CreateMsgsForTwoJobs();
-        ((MockHiveService)service).updateJobs(jobList, job);
+        ((MockHiveService)service).UpdateJobs(jobList, job);
 
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/HiveExperimentView.Designer.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/HiveExperimentView.Designer.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/HiveExperimentView.Designer.cs	(revision 6006)
@@ -54,5 +54,5 @@
       this.viewExperimentButton = new System.Windows.Forms.Button();
       this.jobsTabPage = new System.Windows.Forms.TabPage();
-      this.jobsTreeView = new HeuristicLab.Clients.Hive.Views.ItemTreeView();
+      this.jobsTreeView = new HeuristicLab.Clients.Hive.Views.ItemTreeView<HiveJob>();
       this.logTabPage = new System.Windows.Forms.TabPage();
       this.logView = new HeuristicLab.Core.Views.LogView();
@@ -465,5 +465,5 @@
     private System.Windows.Forms.CheckBox useLocalPluginsCheckBox;
     private System.Windows.Forms.TabPage jobsTabPage;
-    private ItemTreeView jobsTreeView;
+    private ItemTreeView<HiveJob> jobsTreeView;
     private System.Windows.Forms.Label nameLabel;
     private System.Windows.Forms.TextBox nameTextBox;
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/HiveExperimentView.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/HiveExperimentView.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/HiveExperimentView.cs	(revision 6006)
@@ -22,6 +22,8 @@
 using System;
 using System.ComponentModel;
+using System.Linq;
 using System.Threading;
 using System.Windows.Forms;
+using HeuristicLab.Collections;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -34,5 +36,5 @@
   /// The base class for visual representations of items.
   /// </summary>
-  [View("Experiment View")]
+  [View("Hive Experiment View")]
   [Content(typeof(HiveExperiment), true)]
   public sealed partial class HiveExperimentView : ItemView {
@@ -52,13 +54,8 @@
 
     protected override void DeregisterContentEvents() {
-      //Content.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred);
       Content.ExecutionStateChanged -= new EventHandler(Content_ExecutionStateChanged);
       Content.ExecutionTimeChanged -= new EventHandler(Content_ExecutionTimeChanged);
-      //Content.Prepared -= new EventHandler(Content_Prepared);
-      //Content.Started -= new EventHandler(Content_Started);
-      //Content.Paused -= new EventHandler(Content_Paused);
-      //Content.Stopped -= new EventHandler(Content_Stopped);
       Content.RefreshAutomaticallyChanged -= new EventHandler(Content_RefreshAutomaticallyChanged);
-      Content.HiveJobChanged -= new EventHandler(Content_HiveJobChanged);
+      Content.HiveJobsChanged -= new EventHandler(Content_HiveJobChanged);
       Content.IsProgressingChanged -= new EventHandler(Content_IsProgressingChanged);
       Content.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(Content_PropertyChanged);
@@ -68,13 +65,8 @@
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
-      //Content.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred);
       Content.ExecutionStateChanged += new EventHandler(Content_ExecutionStateChanged);
       Content.ExecutionTimeChanged += new EventHandler(Content_ExecutionTimeChanged);
-      //Content.Prepared += new EventHandler(Content_Prepared);
-      //Content.Started += new EventHandler(Content_Started);
-      //Content.Paused += new EventHandler(Content_Paused);
-      //Content.Stopped += new EventHandler(Content_Stopped);
       Content.RefreshAutomaticallyChanged += new EventHandler(Content_RefreshAutomaticallyChanged);
-      Content.HiveJobChanged += new EventHandler(Content_HiveJobChanged);
+      Content.HiveJobsChanged += new EventHandler(Content_HiveJobChanged);
       Content.IsProgressingChanged += new EventHandler(Content_IsProgressingChanged);
       Content.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Content_PropertyChanged);
@@ -119,6 +111,6 @@
 
       if (Content != null) {
-        bool alreadyUploaded = Content.RootJobId != null && Content.Id != Guid.Empty;
-        bool jobsLoaded = Content.HiveJob != null && Content.HiveJob.Job.Id != Guid.Empty;
+        bool alreadyUploaded = Content.Id != Guid.Empty;
+        bool jobsLoaded = Content.HiveJobs != null && Content.HiveJobs.All(x => x.Job.Id != Guid.Empty);
 
         this.nameTextBox.ReadOnly = Content.ExecutionState != ExecutionState.Prepared || alreadyUploaded;
@@ -127,5 +119,5 @@
         this.useLocalPluginsCheckBox.Enabled = !(Content.ExecutionState != ExecutionState.Prepared || alreadyUploaded);
         this.refreshAutomaticallyCheckBox.Enabled = alreadyUploaded && jobsLoaded && Content.ExecutionState == ExecutionState.Started;
-        this.viewExperimentButton.Enabled = Content.GetExperiment() != null;
+        this.viewExperimentButton.Enabled = Content.GetExperiment(0) != null;
         this.openExperimentButton.Enabled = !alreadyUploaded && Content.ExecutionState == ExecutionState.Prepared;
         this.newExperimentButton.Enabled = !alreadyUploaded && Content.ExecutionState == ExecutionState.Prepared;
@@ -146,4 +138,11 @@
 
     #region Content Events
+    private void HiveJobs_ItemsAdded_Removed_Reset(object sender, CollectionItemsChangedEventArgs<HiveJob> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<HiveJob>(HiveJobs_ItemsAdded_Removed_Reset), sender, e);
+      else {
+        SetEnabledStateOfControls();
+      }
+    }
     private void Content_ExecutionStateChanged(object sender, EventArgs e) {
       if (InvokeRequired)
@@ -192,10 +191,4 @@
         executionTimeTextBox.Text = Content.ExecutionTime.ToString();
     }
-    private void Content_ExceptionOccurred(object sender, EventArgs<Exception> e) {
-      if (InvokeRequired)
-        Invoke(new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred), sender, e);
-      else
-        ErrorHandling.ShowErrorDialog(this, e.Value);
-    }
     private void Content_RefreshAutomaticallyChanged(object sender, EventArgs e) {
       if (InvokeRequired)
@@ -210,7 +203,8 @@
         Invoke(new EventHandler(Content_HiveJobChanged), sender, e);
       else {
-        if (Content != null) {
-          jobsTreeView.Content = Content.HiveJob;
-          experimentNamedItemView.Content = Content.GetExperiment();
+        if (Content != null && Content.HiveJobs != null) {
+          jobsTreeView.Content = Content.HiveJobs;
+          experimentNamedItemView.Content = Content.GetExperiment(0);
+          RegisterHiveJobEvents();
         } else {
           jobsTreeView.Content = null;
@@ -220,4 +214,16 @@
       }
     }
+
+    private void RegisterHiveJobEvents() {
+      Content.HiveJobs.ItemsAdded += new Collections.CollectionItemsChangedEventHandler<HiveJob>(HiveJobs_ItemsAdded_Removed_Reset);
+      Content.HiveJobs.ItemsRemoved += new Collections.CollectionItemsChangedEventHandler<HiveJob>(HiveJobs_ItemsAdded_Removed_Reset);
+      Content.HiveJobs.CollectionReset += new Collections.CollectionItemsChangedEventHandler<HiveJob>(HiveJobs_ItemsAdded_Removed_Reset);
+    }
+    private void DeregisterHiveJobEvents() {
+      Content.HiveJobs.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler<HiveJob>(HiveJobs_ItemsAdded_Removed_Reset);
+      Content.HiveJobs.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler<HiveJob>(HiveJobs_ItemsAdded_Removed_Reset);
+      Content.HiveJobs.CollectionReset -= new Collections.CollectionItemsChangedEventHandler<HiveJob>(HiveJobs_ItemsAdded_Removed_Reset);
+    }
+
     private void Content_PropertyChanged(object sender, PropertyChangedEventArgs e) {
       if (InvokeRequired)
@@ -241,5 +247,5 @@
       ExperimentManagerClient.StopExperiment(Content);
     }
-    private void resetButton_Click(object sender, EventArgs e) {  }
+    private void resetButton_Click(object sender, EventArgs e) { }
 
     private void nameTextBox_Validated(object sender, EventArgs e) {
@@ -271,9 +277,9 @@
 
     private void showExperimentButton_Click(object sender, EventArgs e) {
-      MainFormManager.MainForm.ShowContent(Content.GetExperiment());
+      MainFormManager.MainForm.ShowContent(Content.GetExperiment(0));
     }
 
     private void viewExperimentButton_Click(object sender, EventArgs e) {
-      MainFormManager.MainForm.ShowContent(Content.GetExperiment());
+      MainFormManager.MainForm.ShowContent(Content.GetExperiment(0));
     }
 
@@ -310,5 +316,5 @@
         startButton.Enabled = pauseButton.Enabled = stopButton.Enabled = resetButton.Enabled = false;
       } else {
-        startButton.Enabled = Content.GetExperiment() != null && Content.ExecutionState == ExecutionState.Prepared;
+        startButton.Enabled = Content.GetExperiment(0) != null && Content.ExecutionState == ExecutionState.Prepared;
         pauseButton.Enabled = Content.ExecutionState == ExecutionState.Started;
         stopButton.Enabled = Content.ExecutionState == ExecutionState.Started;
@@ -346,5 +352,5 @@
     }
     #endregion
- 
+
   }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/ItemTreeView.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/ItemTreeView.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/ItemTreeView.cs	(revision 6006)
@@ -24,4 +24,5 @@
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
+using HeuristicLab.Core;
 using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
@@ -30,9 +31,18 @@
 namespace HeuristicLab.Clients.Hive.Views {
   [View("ItemTree View")]
-  [Content(typeof(IItemTree), IsDefaultView = false)]
-  public sealed partial class ItemTreeView : ItemView {
-    public new IItemTree Content {
-      get { return (IItemTree)base.Content; }
+  [Content(typeof(ItemCollection<>), IsDefaultView = false)]
+  [Content(typeof(ItemCollection<IItemTree>), IsDefaultView = true)]
+  public sealed partial class ItemTreeView<T> : ItemView where T : class, IItemTree {
+    public new ItemCollection<T> Content {
+      get { return (ItemCollection<T>)base.Content; }
       set { base.Content = value; }
+    }
+
+    public T SelectedItem {
+      get {
+        if (treeView.SelectedNode != null)
+          return (T)treeView.SelectedNode.Tag;
+        return null;
+      }
     }
 
@@ -42,11 +52,14 @@
 
     protected override void DeregisterContentEvents() {
+      Content.ItemsAdded -= new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded);
+      Content.ItemsRemoved -= new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved);
+      Content.CollectionReset -= new CollectionItemsChangedEventHandler<T>(Content_CollectionReset);
       foreach (TreeNode node in treeView.Nodes) {
-        DeregisterContentEvents((IItemTree)node.Tag, node);
+        DeregisterContentEvents((T)node.Tag, node);
       }
       base.DeregisterContentEvents();
     }
 
-    private void DeregisterContentEvents(IItemTree item, TreeNode node) {
+    private void DeregisterContentEvents(T item, TreeNode node) {
       item.ItemsAdded -= new CollectionItemsChangedEventHandler<IItemTree>(item_ItemsAdded);
       item.ItemsRemoved -= new CollectionItemsChangedEventHandler<IItemTree>(item_ItemsRemoved);
@@ -55,5 +68,5 @@
       item.ItemImageChanged -= new EventHandler(item_ItemImageChanged);
       foreach (TreeNode childNode in node.Nodes) {
-        DeregisterContentEvents((IItemTree)childNode.Tag, childNode);
+        DeregisterContentEvents((T)childNode.Tag, childNode);
       }
     }
@@ -61,10 +74,13 @@
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
+      Content.ItemsAdded += new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded);
+      Content.ItemsRemoved += new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved);
+      Content.CollectionReset += new CollectionItemsChangedEventHandler<T>(Content_CollectionReset);
       foreach (TreeNode node in treeView.Nodes) {
-        RegisterContentEvents((IItemTree)node.Tag, node);
-      }
-    }
-
-    private void RegisterContentEvents(IItemTree item, TreeNode node) {
+        RegisterContentEvents((T)node.Tag, node);
+      }
+    }
+
+    private void RegisterContentEvents(T item, TreeNode node) {
       item.ItemsAdded += new CollectionItemsChangedEventHandler<IItemTree>(item_ItemsAdded);
       item.ItemsRemoved += new CollectionItemsChangedEventHandler<IItemTree>(item_ItemsRemoved);
@@ -73,16 +89,50 @@
       item.ItemImageChanged += new EventHandler(item_ItemImageChanged);
       foreach (TreeNode childNode in node.Nodes) {
-        RegisterContentEvents((IItemTree)childNode.Tag, childNode);
+        RegisterContentEvents((T)childNode.Tag, childNode);
       }
     }
 
     #region Event Handlers (Content)
+    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<T> e) {
+      if (InvokeRequired) {
+        Invoke(new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded), sender, e);
+      } else {
+        foreach (T item in e.Items) {
+          var node = AddChildNodes(item, treeView.Nodes, true);
+          UpdateNodeItemImage(node);
+        }
+      }
+    }
+    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<T> e) {
+      if (InvokeRequired) {
+        Invoke(new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved), sender, e);
+      } else {
+        foreach (T item in e.Items) {
+          RemoveChildNodes(item, treeView.Nodes);
+        }
+        RebuildImageList();
+      }
+    }
+    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<T> e) {
+      if (InvokeRequired) {
+        Invoke(new CollectionItemsChangedEventHandler<T>(Content_CollectionReset), sender, e);
+      } else {
+        foreach (T item in e.OldItems) {
+          RemoveChildNodes(item, treeView.Nodes);
+        }
+        RebuildImageList();
+        foreach (T item in e.Items) {
+          AddChildNodes(item, treeView.Nodes, true);
+        }
+      }
+    }
+
     private void item_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IItemTree> e) {
       if (InvokeRequired) {
         Invoke(new CollectionItemsChangedEventHandler<IItemTree>(item_ItemsAdded), sender, e);
       } else {
-        TreeNode node = GetNodeByItem(sender as IItemTree);
+        TreeNode node = GetNodeByItem(sender as T);
         if (node != null) {
-          foreach (IItemTree item in e.Items) {
+          foreach (T item in e.Items) {
             AddChildNodes(item, node.Nodes, true);
             node.ExpandAll();
@@ -97,7 +147,7 @@
         Invoke(new CollectionItemsChangedEventHandler<IItemTree>(item_ItemsRemoved), sender, e);
       } else {
-        TreeNode node = GetNodeByItem(sender as IItemTree);
+        TreeNode node = GetNodeByItem(sender as T);
         if (node != null) {
-          foreach (IItemTree item in e.Items) {
+          foreach (T item in e.Items) {
             RemoveChildNodes(item, node.Nodes);
           }
@@ -111,11 +161,11 @@
         Invoke(new CollectionItemsChangedEventHandler<IItemTree>(item_CollectionReset), sender, e);
       } else {
-        TreeNode node = GetNodeByItem(sender as IItemTree);
+        TreeNode node = GetNodeByItem(sender as T);
         if (node != null) {
-          foreach (IItemTree item in e.OldItems) {
+          foreach (T item in e.OldItems) {
             RemoveChildNodes(item, node.Nodes);
           }
           RebuildImageList();
-          foreach (IItemTree item in e.Items) {
+          foreach (T item in e.Items) {
             AddChildNodes(item, node.Nodes, true);
           }
@@ -128,5 +178,5 @@
         Invoke(new EventHandler(item_ToStringChanged), sender, e);
       } else {
-        var item = sender as IItemTree;
+        var item = sender as T;
         TreeNode node = GetNodeByItem(item);
         if(node != null)
@@ -139,5 +189,5 @@
         Invoke(new EventHandler(item_ItemImageChanged), sender, e);
       } else {
-        var item = sender as IItemTree;
+        var item = sender as T;
         TreeNode node = GetNodeByItem(item);
         if(node != null)
@@ -151,5 +201,5 @@
       } else {
         if (treeView.SelectedNode != null) {
-          var item = treeView.SelectedNode.Tag as IItemTree;
+          var item = treeView.SelectedNode.Tag as T;
           if (item != null) {
             IContentView view = MainFormManager.MainForm.ShowContent(item);
@@ -167,14 +217,15 @@
       base.OnContentChanged();
       if (Content == null) {
-        // Add code when content has been changed and is null
         ClearNodes();
         detailsViewHost.Content = null;
       } else {
-        // Add code when content has been changed and is not null
         ClearNodes();
-        AddChildNodes(Content, treeView.Nodes, false);
+        foreach (T itemTree in Content) {
+          AddChildNodes(itemTree, treeView.Nodes, false);
+        }
         foreach (TreeNode node in treeView.Nodes) {
           UpdateNodeItemImage(node);
         }
+        detailsViewHost.Content = null;
       }
     }
@@ -184,5 +235,5 @@
     }
 
-    private void AddChildNodes(IItemTree item, TreeNodeCollection nodes, bool registerEvents) {
+    private TreeNode AddChildNodes(T item, TreeNodeCollection nodes, bool registerEvents) {
       TreeNode node = CreateTreeViewNode(item);
       nodes.Add(node);
@@ -190,11 +241,12 @@
       RegisterContentEvents(item, node); 
       var childItems = item.GetChildItems();
-      foreach (var childItem in childItems) {
+      foreach (T childItem in childItems) {
         AddChildNodes(childItem, node.Nodes, registerEvents);
       }
       node.ExpandAll();
-    }
-
-    private void RemoveChildNodes(IItemTree item, TreeNodeCollection treeNodeCollection) {
+      return node;
+    }
+
+    private void RemoveChildNodes(T item, TreeNodeCollection treeNodeCollection) {
       int idx = -1;
       for (int i = 0; i < treeNodeCollection.Count; i++) {
@@ -207,5 +259,5 @@
     }
     
-    private TreeNode GetNodeByItem(IItemTree item) {
+    private TreeNode GetNodeByItem(T item) {
       TreeNode found = null;
       foreach (TreeNode node in treeView.Nodes) {
@@ -217,5 +269,5 @@
     }
 
-    private TreeNode GetNodeByItem(TreeNode node, IItemTree item) {
+    private TreeNode GetNodeByItem(TreeNode node, T item) {
       if (node.Tag == item)
         return node;
@@ -229,5 +281,5 @@
     }
 
-    private TreeNode CreateTreeViewNode(IItemTree item) {
+    private TreeNode CreateTreeViewNode(T item) {
       var node = new TreeNode(item.ToString());
       node.Tag = item;
@@ -237,5 +289,5 @@
     private void UpdateNodeItemImage(TreeNode node) {
       if (node == null) throw new ArgumentNullException();
-      var item = node.Tag as IItemTree;
+      var item = node.Tag as T;
       int i = node.ImageIndex;
       this.imageList.Images[i] = item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage;
@@ -268,5 +320,5 @@
 
     private void RebuildImageList(TreeNode node) {
-      var item = node.Tag as IItemTree;
+      var item = node.Tag as T;
       treeView.ImageList.Images.Add(item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage);
       node.ImageIndex = treeView.ImageList.Images.Count - 1;
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/ItemTreeView.designer.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/ItemTreeView.designer.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/ItemTreeView.designer.cs	(revision 6006)
@@ -1,4 +1,4 @@
 ﻿namespace HeuristicLab.Clients.Hive.Views {
-  partial class ItemTreeView {
+  partial class ItemTreeView<T> {
     /// <summary> 
     /// Required designer variable.
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/HeuristicLab.Clients.Hive.Views-3.4.csproj
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/HeuristicLab.Clients.Hive.Views-3.4.csproj	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/HeuristicLab.Clients.Hive.Views-3.4.csproj	(revision 6006)
@@ -74,4 +74,5 @@
       <HintPath>C:\Program Files\HeuristicLab 3.3\Calendar.DayView.dll</HintPath>
     </Reference>
+    <Reference Include="HeuristicLab.Clients.Hive.Views-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Collections-3.3">
       <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Collections-3.3.dll</HintPath>
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/ExperimentManagerClient.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/ExperimentManagerClient.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/ExperimentManagerClient.cs	(revision 6006)
@@ -145,5 +145,9 @@
 
     public static void StartExperiment(Action<Exception> exceptionCallback, HiveExperiment hiveExperiment) {
-      ExperimentManagerClient.StoreAsync(exceptionCallback, hiveExperiment);
+      ExperimentManagerClient.StoreAsync(
+        new Action<Exception>((Exception ex) => {
+          hiveExperiment.ExecutionState = ExecutionState.Prepared;
+          exceptionCallback(ex);
+        }), hiveExperiment);
       hiveExperiment.ExecutionState = ExecutionState.Started;
     }
@@ -151,5 +155,5 @@
     public static void PauseExperiment(HiveExperiment hiveExperiment) {
       ServiceLocator.Instance.CallHiveService(service => {
-        foreach (HiveJob job in hiveExperiment.HiveJob.GetAllHiveJobs()) {
+        foreach (HiveJob job in hiveExperiment.GetAllHiveJobs()) {
           if (job.Job.State != JobState.Finished && job.Job.State != JobState.Aborted && job.Job.State != JobState.Failed)
             service.PauseJob(job.Job.Id);
@@ -161,5 +165,5 @@
     public static void StopExperiment(HiveExperiment hiveExperiment) {
       ServiceLocator.Instance.CallHiveService(service => {
-        foreach (HiveJob job in hiveExperiment.HiveJob.GetAllHiveJobs()) {
+        foreach (HiveJob job in hiveExperiment.GetAllHiveJobs()) {
           if (job.Job.State != JobState.Finished && job.Job.State != JobState.Aborted && job.Job.State != JobState.Failed)
             service.StopJob(job.Job.Id);
@@ -185,9 +189,16 @@
           }
 
-          hiveExperiment.HiveJob.SetIndexInParentOptimizerList(null);
-
-          int totalJobCount = hiveExperiment.HiveJob.GetAllHiveJobs().Count();
+          foreach (HiveJob hiveJob in hiveExperiment.HiveJobs) {
+            hiveJob.SetIndexInParentOptimizerList(null);
+          }
+
+          // upload HiveExperiment
+          hiveExperiment.Progress.Status = "Uploading HiveExperiment...";
+          hiveExperiment.Id = service.AddHiveExperiment(hiveExperiment);
+
+          int totalJobCount = hiveExperiment.GetAllHiveJobs().Count();
           int jobCount = 0;
 
+          // upload plugins
           hiveExperiment.Progress.Status = "Uploading plugins...";
           this.OnlinePlugins = service.GetPlugins();
@@ -196,11 +207,11 @@
           this.alreadyUploadedPlugins.Add(configFilePlugin);
 
+          // upload jobs
           hiveExperiment.Progress.Status = "Uploading jobs...";
-          UploadJobWithChildren(hiveExperiment.Progress, service, hiveExperiment.HiveJob, null, resourceIds, ref jobCount, totalJobCount, configFilePlugin.Id, hiveExperiment.UseLocalPlugins);
-          hiveExperiment.RootJobId = hiveExperiment.HiveJob.Job.Id;
-
-          // insert or update HiveExperiment
-          hiveExperiment.Progress.Status = "Uploading HiveExperiment...";
-          hiveExperiment.Id = service.AddHiveExperiment(hiveExperiment);
+
+          foreach (HiveJob hiveJob in hiveExperiment.HiveJobs) {
+            UploadJobWithChildren(hiveExperiment.Progress, service, hiveJob, null, resourceIds, ref jobCount, totalJobCount, configFilePlugin.Id, hiveExperiment.UseLocalPlugins, hiveExperiment.Id);
+          }
+
           if (hiveExperiment.RefreshAutomatically) hiveExperiment.StartResultPolling();
         });
@@ -239,5 +250,5 @@
     /// <param name="parentHiveJob">shall be null if its the root job</param>
     /// <param name="groups"></param>
-    private void UploadJobWithChildren(IProgress progress, IHiveService service, HiveJob hiveJob, HiveJob parentHiveJob, IEnumerable<Guid> groups, ref int jobCount, int totalJobCount, Guid configPluginId, bool useLocalPlugins) {
+    private void UploadJobWithChildren(IProgress progress, IHiveService service, HiveJob hiveJob, HiveJob parentHiveJob, IEnumerable<Guid> groups, ref int jobCount, int totalJobCount, Guid configPluginId, bool useLocalPlugins, Guid hiveExperimentId) {
       jobCount++;
       progress.Status = string.Format("Serializing job {0} of {1}", jobCount, totalJobCount);
@@ -259,4 +270,5 @@
       hiveJob.Job.PluginsNeededIds = PluginUtil.GetPluginDependencies(service, this.onlinePlugins, this.alreadyUploadedPlugins, plugins, useLocalPlugins);
       hiveJob.Job.PluginsNeededIds.Add(configPluginId);
+      hiveJob.Job.HiveExperimentId = hiveExperimentId;
 
       progress.Status = string.Format("Uploading job {0} of {1} ({2} kb)", jobCount, totalJobCount, jobData.Data.Count() / 1024);
@@ -270,5 +282,5 @@
 
       foreach (HiveJob child in hiveJob.ChildHiveJobs) {
-        UploadJobWithChildren(progress, service, child, hiveJob, groups, ref jobCount, totalJobCount, configPluginId, useLocalPlugins);
+        UploadJobWithChildren(progress, service, child, hiveJob, groups, ref jobCount, totalJobCount, configPluginId, useLocalPlugins, hiveExperimentId);
       }
     }
@@ -276,5 +288,5 @@
 
     #region Download Experiment
-    public static void LoadExperiment (HiveExperiment hiveExperiment) {
+    public static void LoadExperiment(HiveExperiment hiveExperiment) {
       hiveExperiment.Progress = new Progress();
       try {
@@ -286,5 +298,5 @@
         // fetch all Job objects to create the full tree of tree of HiveJob objects
         hiveExperiment.Progress.Status = "Downloading list of jobs...";
-        allJobs = ServiceLocator.Instance.CallHiveService(s => s.GetLightweightChildJobs(hiveExperiment.RootJobId, true, true));
+        allJobs = ServiceLocator.Instance.CallHiveService(s => s.GetLightweightExperimentJobs(hiveExperiment.Id));
         totalJobCount = allJobs.Count();
 
@@ -299,25 +311,29 @@
         IDictionary<Guid, HiveJob> allHiveJobs = downloader.Results;
 
-        hiveExperiment.HiveJob = allHiveJobs[hiveExperiment.RootJobId];
-
-        if (hiveExperiment.HiveJob.Job.DateFinished.HasValue && hiveExperiment.HiveJob.Job.DateCreated.HasValue) {
-          hiveExperiment.ExecutionTime = hiveExperiment.HiveJob.Job.DateFinished.Value - hiveExperiment.HiveJob.Job.DateCreated.Value;
+        hiveExperiment.HiveJobs = new ItemCollection<HiveJob>(allHiveJobs.Values.Where(x => !x.Job.ParentJobId.HasValue));
+        //hiveExperiment.HiveJobs = allHiveJobs[hiveExperiment.RootJobId];
+
+        if (hiveExperiment.IsFinished()) {
+          //hiveExperiment.ExecutionTime = hiveExperiment.HiveJobs.Max(.Job.DateFinished.Value - hiveExperiment.HiveJobs.Job.DateCreated.Value;
           //hiveExperiment.lastUpdateTime = hiveExperiment.HiveJob.Job.DateFinished.Value;
           hiveExperiment.ExecutionState = Core.ExecutionState.Stopped;
           //OnStopped(); // todo: stop timer
         } else {
-          hiveExperiment.ExecutionTime = hiveExperiment.HiveJob.Job.DateCreated.HasValue ? DateTime.Now - hiveExperiment.HiveJob.Job.DateCreated.Value : TimeSpan.Zero;
+          //hiveExperiment.ExecutionTime = hiveExperiment.HiveJobs.Job.DateCreated.HasValue ? DateTime.Now - hiveExperiment.HiveJobs.Job.DateCreated.Value : TimeSpan.Zero;
           //hiveExperiment.lastUpdateTime = DateTime.Now;
           hiveExperiment.ExecutionState = Core.ExecutionState.Started;
           //OnStarted(); // todo: start timer
         }
+        hiveExperiment.UpdateTotalExecutionTime();
 
         // build child-job tree
-        BuildHiveJobTree(hiveExperiment.HiveJob, allJobs, allHiveJobs);
+        foreach (HiveJob hiveJob in hiveExperiment.HiveJobs) {
+          BuildHiveJobTree(hiveJob, allJobs, allHiveJobs);
+        }
         hiveExperiment.UpdateTotalExecutionTime();
 
         if (hiveExperiment.ExecutionState != ExecutionState.Stopped) {
           hiveExperiment.RefreshAutomatically = true;
-        }        
+        }
       }
       finally {
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJob.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJob.cs	(revision 6006)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJob.cs	(revision 6006)
@@ -0,0 +1,644 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using HeuristicLab.Clients.Hive.Jobs;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Clients.Hive {
+
+  [Item("Hive Job", "Represents a hive job.")]
+  [StorableClass]
+  public class HiveJob : NamedItem, IItemTree {
+    private static object locker = new object();
+
+    public override Image ItemImage {
+      get {
+        if (job.Id == Guid.Empty) { // not yet uploaded
+          return HeuristicLab.Common.Resources.VSImageLibrary.Event;
+        } else {
+          if (job.State == JobState.Waiting) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
+          else if (job.State == JobState.Calculating) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
+          else if (job.State == JobState.Transferring) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
+          else if (job.State == JobState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePaused;
+          else if (job.State == JobState.Aborted) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
+          else if (job.State == JobState.Failed) return HeuristicLab.Common.Resources.VSImageLibrary.Error;
+          else if (job.State == JobState.Finished) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
+          else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
+        }
+      }
+    }
+
+    private Job job;
+    public Job Job {
+      get { return job; }
+      set {
+        if (job != value) {
+          job = value;
+          OnJobChanged();
+          OnToStringChanged();
+          OnItemImageChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private OptimizerJob optimizerJob;
+    public OptimizerJob OptimizerJob {
+      get { return optimizerJob; }
+      internal set {
+        if (optimizerJob != null && syncJobsWithOptimizers) {
+          this.childHiveJobs.Clear();
+        }
+        if (optimizerJob != value) {
+          DergisterOptimizerEvents();
+          optimizerJob = value;
+          RegisterOptimizerEvents();
+          OnOptimizerJobChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private ItemList<HiveJob> childHiveJobs;
+    public ReadOnlyItemList<HiveJob> ChildHiveJobs {
+      get { return childHiveJobs.AsReadOnly(); }
+    }
+
+    [Storable]
+    private bool syncJobsWithOptimizers = true;
+
+    public HiveJob() {
+      this.Job = new Job() {
+        CoresNeeded = 1,
+        MemoryNeeded = 0
+      };
+      job.State = JobState.Offline;
+      this.childHiveJobs = new ItemList<HiveJob>();
+      syncJobsWithOptimizers = true;
+      RegisterChildHiveJobEvents();
+    }
+
+    public HiveJob(OptimizerJob optimizerJob, bool autoCreateChildHiveJobs)
+      : this() {
+      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
+      this.OptimizerJob = optimizerJob;
+      this.syncJobsWithOptimizers = true;
+    }
+
+    public HiveJob(IOptimizer optimizer)
+      : this() {
+      this.OptimizerJob = new OptimizerJob(optimizer);
+    }
+
+    public HiveJob(Job job, JobData jobData, bool autoCreateChildHiveJobs) {
+      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
+      this.Job = job;
+      try {
+        this.OptimizerJob = PersistenceUtil.Deserialize<OptimizerJob>(jobData.Data);
+      }
+      catch {
+        this.OptimizerJob = null;
+      }
+      this.childHiveJobs = new ItemList<HiveJob>();
+      this.syncJobsWithOptimizers = true;
+      RegisterChildHiveJobEvents();
+    }
+
+    protected HiveJob(HiveJob original, Cloner cloner)
+      : base(original, cloner) {
+      this.Job = cloner.Clone(original.job);
+      this.OptimizerJob = cloner.Clone(original.OptimizerJob);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HiveJob(this, cloner);
+    }
+
+    /// <summary>
+    /// if this.Optimizer is an experiment
+    ///   Uses the child-optimizers of this.HiveJob and creates HiveJob-childs
+    /// if this.Optimizer is a batchrun
+    ///   Creates a number of child-jobs according to repetitions
+    /// </summary>
+    private void UpdateChildHiveJobs() {
+      if (Job != null && syncJobsWithOptimizers) {
+        if (!OptimizerJob.ComputeInParallel) {
+          this.childHiveJobs.Clear();
+        } else {
+          if (OptimizerJob.Optimizer is Optimization.Experiment) {
+            Optimization.Experiment experiment = (Optimization.Experiment)OptimizerJob.Optimizer;
+            foreach (IOptimizer childOpt in experiment.Optimizers) {
+              this.childHiveJobs.Add(new HiveJob(childOpt));
+            }
+          } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
+            Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
+            if (batchRun.Optimizer != null) {
+              while (this.childHiveJobs.Count < batchRun.Repetitions) {
+                this.childHiveJobs.Add(new HiveJob(batchRun.Optimizer));
+              }
+              while (this.childHiveJobs.Count > batchRun.Repetitions) {
+                this.childHiveJobs.Remove(this.childHiveJobs.Last());
+              }
+            }
+          }
+        }
+      }
+    }
+
+    private void RegisterOptimizerEvents() {
+      if (OptimizerJob != null) {
+        if (OptimizerJob.Optimizer is Optimization.Experiment) {
+          Optimization.Experiment experiment = OptimizerJob.OptimizerAsExperiment;
+          experiment.Optimizers.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+          experiment.Optimizers.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+          experiment.Optimizers.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
+          experiment.Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
+        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
+          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
+          batchRun.RepetitionsChanged += new EventHandler(batchRun_RepetitionsChanged);
+          batchRun.OptimizerChanged += new EventHandler(batchRun_OptimizerChanged);
+        }
+        OptimizerJob.ComputeInParallelChanged += new EventHandler(OptimizerJob_ComputeInParallelChanged);
+        OptimizerJob.ToStringChanged += new EventHandler(OptimizerJob_ToStringChanged);
+      }
+    }
+    private void DergisterOptimizerEvents() {
+      if (OptimizerJob != null) {
+        if (OptimizerJob.Optimizer is Optimization.Experiment) {
+          Optimization.Experiment experiment = OptimizerJob.OptimizerAsExperiment;
+          experiment.Optimizers.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+          experiment.Optimizers.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+          experiment.Optimizers.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
+          experiment.Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
+        } else if (OptimizerJob.Optimizer is Optimization.BatchRun) {
+          Optimization.BatchRun batchRun = OptimizerJob.OptimizerAsBatchRun;
+          batchRun.RepetitionsChanged -= new EventHandler(batchRun_RepetitionsChanged);
+          batchRun.OptimizerChanged -= new EventHandler(batchRun_OptimizerChanged);
+        }
+        OptimizerJob.ComputeInParallelChanged -= new EventHandler(OptimizerJob_ComputeInParallelChanged);
+        OptimizerJob.ToStringChanged -= new EventHandler(OptimizerJob_ToStringChanged);
+      }
+    }
+
+    private void RegisterChildHiveJobEvents() {
+      this.childHiveJobs.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
+      this.childHiveJobs.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
+      this.childHiveJobs.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
+    }
+    private void DeregisterChildHiveJobEvents() {
+      this.childHiveJobs.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsAdded);
+      this.childHiveJobs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnItemsRemoved);
+      this.childHiveJobs.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<HiveJob>>(OnCollectionReset);
+    }
+
+    private void batchRun_OptimizerChanged(object sender, EventArgs e) {
+      if (syncJobsWithOptimizers) {
+        UpdateChildHiveJobs();
+      }
+    }
+
+    private void batchRun_RepetitionsChanged(object sender, EventArgs e) {
+      if (syncJobsWithOptimizers) {
+        UpdateChildHiveJobs();
+      }
+    }
+
+    private void OptimizerJob_ToStringChanged(object sender, EventArgs e) {
+      this.OnToStringChanged();
+    }
+
+    private void Optimizers_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
+        foreach (var item in e.Items) {
+          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
+            this.childHiveJobs.Add(new HiveJob(item.Value));
+          }
+        }
+      }
+    }
+    private void Optimizers_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
+        foreach (var item in e.OldItems) {
+          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
+        }
+        foreach (var item in e.Items) {
+          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
+            this.childHiveJobs.Add(new HiveJob(item.Value));
+          }
+        }
+      }
+    }
+    private void Optimizers_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
+        foreach (var item in e.Items) {
+          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
+        }
+      }
+    }
+    private void Optimizers_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      if (syncJobsWithOptimizers && this.OptimizerJob.ComputeInParallel) {
+        foreach (var item in e.Items) {
+          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
+        }
+      }
+    }
+
+    private void OptimizerJob_ComputeInParallelChanged(object sender, EventArgs e) {
+      if (OptimizerJob != null && syncJobsWithOptimizers) {
+        this.UpdateChildHiveJobs();
+      }
+    }
+
+    public void AddChildHiveJob(HiveJob hiveJob) {
+      this.childHiveJobs.Add(hiveJob);
+      syncJobsWithOptimizers = false;
+      if (this.OptimizerJob != null && hiveJob.OptimizerJob != null) {
+        // if job is in state Paused, it has to preserve its ResultCollection, which is cleared when a optimizer is added to an experiment
+        OptimizerJob optimizerJobClone = null;
+        if (hiveJob.Job.State == JobState.Paused) {
+          optimizerJobClone = (OptimizerJob)hiveJob.OptimizerJob.Clone();
+        }
+
+        if (this.OptimizerJob.Optimizer is Optimization.Experiment) {
+          if (!this.OptimizerJob.OptimizerAsExperiment.Optimizers.Contains(hiveJob.OptimizerJob.Optimizer)) {
+            UpdateOptimizerInExperiment(this.OptimizerJob.OptimizerAsExperiment, hiveJob.OptimizerJob);
+          }
+        } else if (this.OptimizerJob.Optimizer is Optimization.BatchRun) {
+          UpdateOptimizerInBatchRun(this.OptimizerJob.OptimizerAsBatchRun, hiveJob.OptimizerJob);
+        }
+
+        if (hiveJob.Job.State == JobState.Paused) {
+          hiveJob.OptimizerJob = optimizerJobClone;
+        }
+      }
+      syncJobsWithOptimizers = true;
+    }
+
+    /// <summary>
+    /// if this.Optimizer is Experiment
+    ///   replace the child-optimizer in the experiment
+    /// if this.Optimizer is BatchRun
+    ///   add the runs from the optimizerJob to the batchrun and replace the Optimizer
+    /// </summary>
+    public void UpdateChildOptimizer(OptimizerJob optimizerJob, Guid childJobId) {
+      syncJobsWithOptimizers = false; // don't sync with optimizers during this method
+      bool childIsFinishedOptimizerDownloaded = false;
+
+      if (this.OptimizerJob != null && this.OptimizerJob.Optimizer != null) {
+        if (this.OptimizerJob.Optimizer is Optimization.Experiment) {
+          UpdateOptimizerInExperiment(this.OptimizerJob.OptimizerAsExperiment, optimizerJob);
+          childIsFinishedOptimizerDownloaded = true;
+        } else if (this.OptimizerJob.Optimizer is Optimization.BatchRun) {
+          UpdateOptimizerInBatchRun(this.OptimizerJob.OptimizerAsBatchRun, optimizerJob);
+          if (this.OptimizerJob.OptimizerAsBatchRun.Repetitions == this.OptimizerJob.Optimizer.Runs.Count) {
+            childIsFinishedOptimizerDownloaded = true;
+          }
+        } else {
+          childIsFinishedOptimizerDownloaded = optimizerJob.Optimizer.ExecutionState == ExecutionState.Stopped;
+        }
+      }
+
+      HiveJob child = this.ChildHiveJobs.Single(j => j.Job.Id == childJobId);
+      if (!optimizerJob.ComputeInParallel) {
+        child.syncJobsWithOptimizers = false;
+        child.OptimizerJob = optimizerJob;
+        child.syncJobsWithOptimizers = true;
+      }
+      if (childIsFinishedOptimizerDownloaded) {
+        //child.IsFinishedOptimizerDownloaded = true; // todo: clean up with childIsFinishedOptimizerDownloaded
+      }
+      syncJobsWithOptimizers = true;
+    }
+
+    /// <summary>
+    /// Adds the runs from the optimizerJob to the batchrun and replaces the Optimizer 
+    /// Sideeffect: the optimizerJob.Optimizer will be prepared (scopes are deleted and executionstate will be reset)
+    /// </summary>
+    private void UpdateOptimizerInBatchRun(BatchRun batchRun, OptimizerJob optimizerJob) {
+      if (batchRun.Optimizer == null) {
+        batchRun.Optimizer = (IOptimizer)optimizerJob.Optimizer; // only set the first optimizer as Optimizer. if every time the Optimizer would be set, the runs would be cleared each time
+      }
+      foreach (IRun run in optimizerJob.Optimizer.Runs) {
+        if (!batchRun.Runs.Contains(run)) {
+          run.Name = GetNewRunName(run, batchRun.Runs);
+          batchRun.Runs.Add(run);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Parses the run numbers out of runs and renames the run to the next number
+    /// </summary>
+    private static string GetNewRunName(IRun run, RunCollection runs) {
+      int idx = run.Name.IndexOf("Run ") + 4;
+
+      if (idx == -1 || runs.Count == 0)
+        return run.Name;
+
+      int maxRunNumber = int.MinValue;
+      foreach (IRun r in runs) {
+        int number = GetRunNumber(r.Name);
+        maxRunNumber = Math.Max(maxRunNumber, number);
+      }
+
+      return run.Name.Substring(0, idx) + (maxRunNumber + 1).ToString();
+    }
+
+    /// <summary>
+    /// Parses the number of a Run out of its name. Example "Genetic Algorithm Run 3" -> 3
+    /// </summary>
+    private static int GetRunNumber(string runName) {
+      int idx = runName.IndexOf("Run ") + 4;
+      if (idx == -1) {
+        return 0;
+      } else {
+        return int.Parse(runName.Substring(idx, runName.Length - idx));
+      }
+    }
+
+    /// <summary>
+    /// replace the child-optimizer in the experiment
+    /// Sideeffect: the optimizerJob.Optimizer will be prepared (scopes are deleted and executionstate will be reset)
+    /// </summary>
+    private void UpdateOptimizerInExperiment(Optimization.Experiment experiment, OptimizerJob optimizerJob) {
+      if (optimizerJob.IndexInParentOptimizerList < 0)
+        throw new IndexOutOfRangeException("IndexInParentOptimizerList must be equal or greater than zero! The Job is invalid and the optimizer-tree cannot be reassembled.");
+
+      while (experiment.Optimizers.Count < optimizerJob.IndexInParentOptimizerList) {
+        experiment.Optimizers.Add(new UserDefinedAlgorithm("Placeholder")); // add dummy-entries to Optimizers so that its possible to insert the optimizerJob at the correct position
+      }
+      if (experiment.Optimizers.Count < optimizerJob.IndexInParentOptimizerList + 1) {
+        experiment.Optimizers.Add(optimizerJob.Optimizer);
+      } else {
+        // if ComputeInParallel==true, don't replace the optimizer (except it is still a Placeholder)
+        // this is because Jobs with ComputeInParallel get submitted to hive with their child-optimizers deleted
+        if (!optimizerJob.ComputeInParallel || experiment.Optimizers[optimizerJob.IndexInParentOptimizerList].Name == "Placeholder") {
+          experiment.Optimizers[optimizerJob.IndexInParentOptimizerList] = optimizerJob.Optimizer;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Sets the IndexInParentOptimizerList property of the OptimizerJob
+    /// according to the position in the OptimizerList of the parentHiveJob.Job
+    /// Recursively updates all the child-jobs as well
+    /// </summary>
+    internal void SetIndexInParentOptimizerList(HiveJob parentHiveJob) {
+      if (parentHiveJob != null) {
+        if (parentHiveJob.OptimizerJob.Optimizer is Optimization.Experiment) {
+          this.OptimizerJob.IndexInParentOptimizerList = parentHiveJob.OptimizerJob.OptimizerAsExperiment.Optimizers.IndexOf(this.OptimizerJob.Optimizer);
+        } else if (parentHiveJob.OptimizerJob.Optimizer is Optimization.BatchRun) {
+          this.OptimizerJob.IndexInParentOptimizerList = 0;
+        } else {
+          throw new NotSupportedException("Only Experiment and BatchRuns are supported");
+        }
+      }
+      foreach (HiveJob child in childHiveJobs) {
+        child.SetIndexInParentOptimizerList(this);
+      }
+    }
+
+    public override string ToString() {
+      if (optimizerJob != null) {
+        return optimizerJob.ToString();
+      } else {
+        return base.ToString();
+      }
+    }
+
+    public void UpdateFromLightweightJob(LightweightJob lightweightJob) {
+      if (lightweightJob != null) {
+        job.Id = lightweightJob.Id;
+        job.ParentJobId = lightweightJob.ParentJobId;
+        job.ExecutionTime = lightweightJob.ExecutionTime;
+        job.State = lightweightJob.State;
+        job.StateLog = new List<StateLog>(lightweightJob.StateLog);
+        job.Command = lightweightJob.Command;
+        job.LastJobDataUpdate = lightweightJob.LastJobDataUpdate;
+        
+        OnJobStateChanged();
+        OnToStringChanged();
+        OnItemImageChanged();
+      }
+    }
+
+    /// <summary>
+    /// Creates a JobData object containing the Job and the IJob-Object as byte[]
+    /// </summary>
+    /// <param name="withoutChildOptimizers">
+    ///   if true the Child-Optimizers will not be serialized (if the job contains an Experiment)
+    /// </param>
+    public JobData GetAsJobData(bool withoutChildOptimizers, out List<IPluginDescription> plugins) {
+      plugins = new List<IPluginDescription>();
+      if (this.optimizerJob == null || this.optimizerJob.Optimizer == null)
+        return null;
+
+      IEnumerable<Type> usedTypes;
+      byte[] jobByteArray;
+      if (withoutChildOptimizers && this.OptimizerJob.Optimizer is Optimization.Experiment) {
+        OptimizerJob clonedJob = (OptimizerJob)this.OptimizerJob.Clone(); // use a cloned job, so that the childHiveJob don't get confused
+        clonedJob.OptimizerAsExperiment.Optimizers.Clear();
+        jobByteArray = PersistenceUtil.Serialize(clonedJob, out usedTypes);
+      } else if (withoutChildOptimizers && this.OptimizerJob.Optimizer is Optimization.BatchRun) {
+        OptimizerJob clonedJob = (OptimizerJob)this.OptimizerJob.Clone();
+        clonedJob.OptimizerAsBatchRun.Optimizer = null;
+        jobByteArray = PersistenceUtil.Serialize(clonedJob, out usedTypes);
+      } else if (this.OptimizerJob.Optimizer is IAlgorithm) {
+        ((IAlgorithm)this.OptimizerJob.Optimizer).StoreAlgorithmInEachRun = false; // avoid storing the algorithm in runs to reduce size
+        jobByteArray = PersistenceUtil.Serialize(this.OptimizerJob, out usedTypes);
+      } else {
+        jobByteArray = PersistenceUtil.Serialize(this.OptimizerJob, out usedTypes);
+      }
+
+      JobData jobData = new JobData() {
+        JobId = job.Id,
+        Data = jobByteArray
+      };
+
+      PluginUtil.CollectDeclaringPlugins(plugins, usedTypes);
+
+      return jobData;
+    }
+
+
+    #region Events
+    public event EventHandler JobChanged;
+    private void OnJobChanged() {
+      LogMessage("JobChanged");
+      EventHandler handler = JobChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler JobStateChanged;
+    private void OnJobStateChanged() {
+      LogMessage("JobStateChanged (State: " + this.Job.State + ", ExecutionTime: " + this.Job.ExecutionTime.ToString() + ")");
+      EventHandler handler = JobStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler OptimizerJobChanged;
+    private void OnOptimizerJobChanged() {
+      OptimizerJob_ComputeInParallelChanged(this, EventArgs.Empty);
+      var handler = OptimizerJobChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler IsFinishedOptimizerDownloadedChanged;
+    private void OnIsFinishedOptimizerDownloadedChanged() {
+      var handler = IsFinishedOptimizerDownloadedChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    public void LogMessage(string message) {
+      lock (locker) {
+        if (optimizerJob != null) {
+          optimizerJob.Log.LogMessage(message);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Returns a list of HiveJobs including this and all its child-jobs recursively
+    /// </summary>
+    public IEnumerable<HiveJob> GetAllHiveJobs() {
+      List<HiveJob> jobs = new List<HiveJob>();
+      jobs.Add(this);
+      foreach (HiveJob child in this.ChildHiveJobs) {
+        jobs.AddRange(child.GetAllHiveJobs());
+      }
+      return jobs;
+    }
+
+    public HiveJob GetParentByJobId(Guid jobId) {
+      if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
+        return this;
+      foreach (HiveJob child in this.childHiveJobs) {
+        HiveJob result = child.GetParentByJobId(jobId);
+        if (result != null)
+          return result;
+      }
+      return null;
+    }
+
+
+    public HiveJob GetChildByOptimizerJob(OptimizerJob optimizerJob) {
+      foreach (var child in ChildHiveJobs) {
+        if (child.OptimizerJob == optimizerJob)
+          return child;
+      }
+      return null;
+    }
+
+
+    public HiveJob GetChildByOptimizer(IOptimizer optimizer) {
+      foreach (var child in ChildHiveJobs) {
+        if (child.OptimizerJob.Optimizer == optimizer)
+          return child;
+      }
+      return null;
+    }
+
+    /// <summary>
+    /// Searches for an HiveJob object with the correct jobId recursively
+    /// </summary>
+    public HiveJob GetHiveJobByJobId(Guid jobId) {
+      if (this.Job.Id == jobId) {
+        return this;
+      } else {
+        foreach (HiveJob child in this.ChildHiveJobs) {
+          HiveJob result = child.GetHiveJobByJobId(jobId);
+          if (result != null)
+            return result;
+        }
+      }
+      return null;
+    }
+
+
+    public void RemoveByJobId(Guid jobId) {
+      IEnumerable<HiveJob> jobs = ChildHiveJobs.Where(j => j.Job.Id == jobId).ToList(); // if Guid.Empty needs to be removed, there could be more than one with this jobId
+      foreach (HiveJob j in jobs) {
+        this.childHiveJobs.Remove(j);
+      }
+      foreach (HiveJob child in ChildHiveJobs) {
+        child.RemoveByJobId(jobId);
+      }
+    }
+
+    public IEnumerable<IItemTree> GetChildItems() {
+      return this.childHiveJobs;
+    }
+
+    #region INotifyObservableCollectionItemsChanged<IItemTree> Members
+
+    public event CollectionItemsChangedEventHandler<IItemTree> CollectionReset;
+    private void OnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
+      var handler = CollectionReset;
+      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
+    }
+
+    public event CollectionItemsChangedEventHandler<IItemTree> ItemsAdded;
+    private void OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
+      var handler = ItemsAdded;
+      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
+    }
+
+    public event CollectionItemsChangedEventHandler<IItemTree> ItemsRemoved;
+    private void OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
+      var handler = ItemsRemoved;
+      if (handler != null) handler(this, ToCollectionItemsChangedEventArgs(e));
+    }
+
+    private static CollectionItemsChangedEventArgs<IItemTree> ToCollectionItemsChangedEventArgs(CollectionItemsChangedEventArgs<IndexedItem<HiveJob>> e) {
+      return new CollectionItemsChangedEventArgs<IItemTree>(e.Items.Select(x => x.Value), e.OldItems == null ? null : e.OldItems.Select(x => x.Value));
+    }
+    #endregion
+
+    public void Pause() {
+      ServiceLocator.Instance.CallHiveService(s => s.PauseJob(this.job.Id));
+    }
+
+    public void Stop() {
+      ServiceLocator.Instance.CallHiveService(s => s.StopJob(this.job.Id));
+    }
+
+    public void Restart() {
+      ServiceLocator.Instance.CallHiveService(service => {
+        JobData jobData = new JobData();
+        jobData.JobId = this.job.Id;
+        jobData.Data = PersistenceUtil.Serialize(this.optimizerJob);
+        service.UpdateJobData(this.Job, jobData);
+        service.RestartJob(this.job.Id);
+        Job job = service.GetJob(this.job.Id);
+        this.job.LastJobDataUpdate = job.LastJobDataUpdate;
+      });
+    }
+  }
+}
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/JobResultPoller.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/JobResultPoller.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/JobResultPoller.cs	(revision 6006)
@@ -31,8 +31,8 @@
     private Thread thread;
 
-    private HiveJob hiveJob;
-    public HiveJob HiveJob {
-      get { return hiveJob; }
-      set { hiveJob = value; }
+    private IEnumerable<HiveJob> hiveJobs;
+    public IEnumerable<HiveJob> HiveJobs {
+      get { return hiveJobs; }
+      set { hiveJobs = value; }
     }
 
@@ -54,7 +54,7 @@
     }
 
-    public JobResultPoller(HiveJob hiveJob, TimeSpan interval) {
+    public JobResultPoller(IEnumerable<HiveJob> hiveJobs, TimeSpan interval) {
       this.isPolling = false;
-      this.hiveJob = hiveJob;
+      this.hiveJobs = hiveJobs;
       this.interval = interval;
     }
@@ -96,6 +96,9 @@
     private void FetchJobResults() {
       ServiceLocator.Instance.CallHiveService(service => {
-        IEnumerable<LightweightJob> response = service.GetLightweightChildJobs(hiveJob.Job.Id, true, true);
-        OnJobResultsReceived(response);
+        var responses = new List<LightweightJob>();
+        foreach (HiveJob hiveJob in HiveJobs) {
+          responses.AddRange(service.GetLightweightChildJobs(hiveJob.Job.Id, true, true));
+        }
+        OnJobResultsReceived(responses);
       });
     }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HeuristicLab.Clients.Hive-3.4.csproj
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HeuristicLab.Clients.Hive-3.4.csproj	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HeuristicLab.Clients.Hive-3.4.csproj	(revision 6006)
@@ -128,5 +128,5 @@
     <Compile Include="Jobs\OptimizerJob.cs" />
     <Compile Include="HeuristicLabClientsHivePlugin.cs" />
-    <Compile Include="ExperimentManager\HiveJobClient.cs" />
+    <Compile Include="ExperimentManager\HiveJob.cs" />
     <Compile Include="ExperimentManager\JobResultPoller.cs" />
     <Compile Include="PersistenceUtil.cs" />
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveExperiment.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveExperiment.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveExperiment.cs	(revision 6006)
@@ -28,10 +28,12 @@
 using HeuristicLab.Core;
 using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Clients.Hive {
-
+  [StorableClass]
   public partial class HiveExperiment : IDeepCloneable, IContent, IProgressReporter {
     private JobResultPoller jobResultPoller;
 
+    [Storable]
     private bool useLocalPlugins;
     public bool UseLocalPlugins {
@@ -40,4 +42,5 @@
     }
 
+    [Storable]
     private ExecutionState executionState;
     public ExecutionState ExecutionState {
@@ -51,4 +54,5 @@
     }
 
+    [Storable]
     private TimeSpan executionTime;
     public TimeSpan ExecutionTime {
@@ -62,17 +66,19 @@
     }
 
-    private HiveJob hiveJob;
-    public HiveJob HiveJob {
-      get { return hiveJob; }
+    [Storable]
+    private ItemCollection<HiveJob> hiveJobs;
+    public ItemCollection<HiveJob> HiveJobs {
+      get { return hiveJobs; }
       set {
-        DeregisterHiveJobEvents();
-        if (hiveJob != value) {
-          hiveJob = value;
-          RegisterHiveJobEvents();
-          OnHiveJobChanged();
-        }
-      }
-    }
-
+        DeregisterHiveJobsEvents();
+        if (hiveJobs != value) {
+          hiveJobs = value;
+          RegisterHiveJobsEvents();
+          OnHiveJobsChanged();
+        }
+      }
+    }
+
+    [Storable]
     private bool isProgressing;
     public bool IsProgressing {
@@ -87,4 +93,5 @@
 
     /** include jobs when refreshing **/
+    [Storable]
     private bool includeJobs;
     public bool IncludeJobs {
@@ -93,4 +100,5 @@
     }
 
+    [Storable]
     private bool refreshAutomatically;
     public bool RefreshAutomatically {
@@ -109,4 +117,5 @@
     }
 
+    [Storable]
     private IProgress progress;
     public IProgress Progress {
@@ -124,5 +133,4 @@
     protected HiveExperiment(HiveExperiment original, Cloner cloner) {
       cloner.RegisterClonedObject(original, this);
-      this.RootJobId = original.RootJobId;
       this.OwnerUserId = original.OwnerUserId;
       this.DateCreated = original.DateCreated;
@@ -158,15 +166,15 @@
     }
 
-    public event EventHandler HiveJobChanged;
-    private void OnHiveJobChanged() {
+    public event EventHandler HiveJobsChanged;
+    private void OnHiveJobsChanged() {
       if (jobResultPoller != null && jobResultPoller.IsPolling) {
         jobResultPoller.Stop();
         DeregisterResultPollingEvents();
       }
-      if (HiveJob != null && HiveJob.Job.Id != Guid.Empty) {
+      if (HiveJobs != null && HiveJobs.Count > 0 && GetAllHiveJobs().All(x => x.Job.Id != Guid.Empty)) {
         if (this.RefreshAutomatically)
           StartResultPolling();
       }
-      EventHandler handler = HiveJobChanged;
+      EventHandler handler = HiveJobsChanged;
       if (handler != null) handler(this, EventArgs.Empty);
     }
@@ -185,31 +193,43 @@
     #endregion
 
-    private void RegisterHiveJobEvents() {
-      if (HiveJob != null) {
-        HiveJob.JobStateChanged += new EventHandler(HiveJob_JobStateChanged);
-      }
-    }
-
-    private void DeregisterHiveJobEvents() {
-      if (HiveJob != null) {
-        HiveJob.JobStateChanged -= new EventHandler(HiveJob_JobStateChanged);
-      }
+    private void RegisterHiveJobsEvents() {
+      //if (HiveJobs != null) {
+      //  HiveJobs.JobStateChanged += new EventHandler(HiveJob_JobStateChanged);
+      //}
+    }
+
+    private void DeregisterHiveJobsEvents() {
+      //if (HiveJobs != null) {
+      //  HiveJobs.JobStateChanged -= new EventHandler(HiveJob_JobStateChanged);
+      //}
     }
 
     private void HiveJob_JobStateChanged(object sender, EventArgs e) {
-      if (this.HiveJob != null) {
-        this.RootJobId = HiveJob.Job.Id;
-      }
-    }
-
-    public Experiment GetExperiment() {
-      if (this.HiveJob != null) {
-        return HiveJob.OptimizerJob.OptimizerAsExperiment;
+      //if (this.HiveJobs != null) {
+      //  this.RootJobId = HiveJobs.Job.Id;
+      //}
+    }
+
+    public Experiment GetExperiment(int idx) {
+      if (this.HiveJobs != null) {
+        var hj = HiveJobs.ElementAtOrDefault(idx);
+        if (hj != null)
+          return hj.OptimizerJob.OptimizerAsExperiment;
       }
       return null;
     }
 
+    public void AddExperiment(Experiment experiment) {
+      if (this.HiveJobs == null) 
+        this.HiveJobs = new ItemCollection<HiveJob>();
+      this.HiveJobs.Add(new HiveJob(experiment));
+    }
+
     public void SetExperiment(Experiment experiment) {
-      this.HiveJob = new HiveJob(experiment);
+      if (this.HiveJobs == null)
+        this.HiveJobs = new ItemCollection<HiveJob>();
+      else
+        this.HiveJobs.Clear();
+      this.HiveJobs.Add(new HiveJob(experiment));
     }
 
@@ -225,5 +245,5 @@
     public void StartResultPolling() {
       if (jobResultPoller == null) {
-        jobResultPoller = new JobResultPoller(HiveJob, /*ApplicationConstants.ResultPollingInterval*/new TimeSpan(0, 0, 5)); //TODO: find a better place for ApplicationConstants
+        jobResultPoller = new JobResultPoller(HiveJobs, /*ApplicationConstants.ResultPollingInterval*/new TimeSpan(0, 0, 5)); //TODO: find a better place for ApplicationConstants
         RegisterResultPollingEvents();
       }
@@ -235,5 +255,5 @@
 
     public void StopResultPolling() {
-      if (jobResultPoller.IsPolling) {
+      if (jobResultPoller != null && jobResultPoller.IsPolling) {
         jobResultPoller.Stop();
       }
@@ -256,5 +276,5 @@
     private void jobResultPoller_JobResultReceived(object sender, EventArgs<IEnumerable<LightweightJob>> e) {
       foreach (LightweightJob lightweightJob in e.Value) {
-        HiveJob hj = hiveJob.GetHiveJobByJobId(lightweightJob.Id);
+        HiveJob hj = GetHiveJobById(lightweightJob.Id);
         if (hj != null) {
           DateTime lastJobDataUpdate = hj.Job.LastJobDataUpdate;
@@ -272,5 +292,5 @@
               } else {
                 if (lightweightJob.ParentJobId.HasValue) {
-                  HiveJob parentHiveJob = HiveJob.GetHiveJobByJobId(lightweightJob.ParentJobId.Value);
+                  HiveJob parentHiveJob = GetHiveJobById(lightweightJob.ParentJobId.Value);
                   parentHiveJob.UpdateChildOptimizer(optimizerJob, hj.Job.Id);
                 }
@@ -290,6 +310,15 @@
     }
 
+    public HiveJob GetHiveJobById(Guid jobId) {
+      foreach (HiveJob job in HiveJobs) {
+        HiveJob hj = job.GetHiveJobByJobId(jobId);
+        if (hj != null)
+          return hj;
+      }
+      return null;
+    }
+
     private void UpdateStats() {
-      var jobs = HiveJob.GetAllHiveJobs();
+      var jobs = GetAllHiveJobs();
       this.JobCount = jobs.Count();
       this.CalculatingCount = jobs.Count(j => j.Job.State == JobState.Calculating);
@@ -297,6 +326,14 @@
     }
 
-    private bool AllJobsFinished() {
-      return HiveJob.GetAllHiveJobs().All(j => j.Job.State == JobState.Finished
+    public IEnumerable<HiveJob> GetAllHiveJobs() {
+      var jobs = new List<HiveJob>();
+      foreach (HiveJob job in HiveJobs) {
+        jobs.AddRange(job.GetAllHiveJobs());
+      }
+      return jobs;
+    }
+
+    public bool AllJobsFinished() {
+      return GetAllHiveJobs().All(j => j.Job.State == JobState.Finished
                                             || j.Job.State == JobState.Aborted
                                             || j.Job.State == JobState.Failed);
@@ -308,5 +345,5 @@
 
     public void UpdateTotalExecutionTime() {
-      this.ExecutionTime = TimeSpan.FromMilliseconds(HiveJob.GetAllHiveJobs().Sum(x => x.Job.ExecutionTime.HasValue ? x.Job.ExecutionTime.Value.TotalMilliseconds : 0));
+      this.ExecutionTime = TimeSpan.FromMilliseconds(GetAllHiveJobs().Sum(x => x.Job.ExecutionTime.HasValue ? x.Job.ExecutionTime.Value.TotalMilliseconds : 0));
     }
     #endregion
@@ -320,4 +357,9 @@
       }
     }
+
+    public bool IsFinished() {
+      return HiveJobs != null
+        && HiveJobs.All(x => x.Job.DateFinished.HasValue && x.Job.DateCreated.HasValue);
+    }
   }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveServiceClient.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveServiceClient.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveServiceClient.cs	(revision 6006)
@@ -352,4 +352,7 @@
         
         [System.Runtime.Serialization.OptionalFieldAttribute()]
+        private System.Guid HiveExperimentIdField;
+        
+        [System.Runtime.Serialization.OptionalFieldAttribute()]
         private bool IsParentJobField;
         
@@ -396,4 +399,21 @@
                     this.FinishWhenChildJobsFinishedField = value;
                     this.RaisePropertyChanged("FinishWhenChildJobsFinished");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid HiveExperimentId
+        {
+            get
+            {
+                return this.HiveExperimentIdField;
+            }
+            set
+            {
+                if ((this.HiveExperimentIdField.Equals(value) != true))
+                {
+                    this.HiveExperimentIdField = value;
+                    this.RaisePropertyChanged("HiveExperimentId");
                 }
             }
@@ -569,7 +589,4 @@
         private string ResourceNamesField;
         
-        [System.Runtime.Serialization.OptionalFieldAttribute()]
-        private System.Guid RootJobIdField;
-        
         [System.Runtime.Serialization.DataMemberAttribute()]
         public int CalculatingCount
@@ -687,21 +704,4 @@
                     this.ResourceNamesField = value;
                     this.RaisePropertyChanged("ResourceNames");
-                }
-            }
-        }
-        
-        [System.Runtime.Serialization.DataMemberAttribute()]
-        public System.Guid RootJobId
-        {
-            get
-            {
-                return this.RootJobIdField;
-            }
-            set
-            {
-                if ((this.RootJobIdField.Equals(value) != true))
-                {
-                    this.RootJobIdField = value;
-                    this.RaisePropertyChanged("RootJobId");
                 }
             }
@@ -1732,4 +1732,7 @@
     {
         
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/TriggerLifecycle", ReplyAction="http://tempuri.org/IHiveService/TriggerLifecycleResponse")]
+        void TriggerLifecycle(bool force);
+        
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/AddAppointment", ReplyAction="http://tempuri.org/IHiveService/AddAppointmentResponse")]
         System.Guid AddAppointment(HeuristicLab.Clients.Hive.Appointment appointment);
@@ -1761,4 +1764,7 @@
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetLightweightChildJobs", ReplyAction="http://tempuri.org/IHiveService/GetLightweightChildJobsResponse")]
         System.Collections.Generic.List<HeuristicLab.Clients.Hive.LightweightJob> GetLightweightChildJobs(System.Nullable<System.Guid> parentJobId, bool recursive, bool includeParent);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetLightweightExperimentJobs", ReplyAction="http://tempuri.org/IHiveService/GetLightweightExperimentJobsResponse")]
+        System.Collections.Generic.List<HeuristicLab.Clients.Hive.LightweightJob> GetLightweightExperimentJobs(System.Guid experimentId);
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetJobData", ReplyAction="http://tempuri.org/IHiveService/GetJobDataResponse")]
@@ -1867,7 +1873,4 @@
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetResourceId", ReplyAction="http://tempuri.org/IHiveService/GetResourceIdResponse")]
         System.Guid GetResourceId(string resourceName);
-        
-        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/TriggerLifecycle", ReplyAction="http://tempuri.org/IHiveService/TriggerLifecycleResponse")]
-        void TriggerLifecycle(bool force);
     }
     
@@ -1906,4 +1909,9 @@
         }
         
+        public void TriggerLifecycle(bool force)
+        {
+            base.Channel.TriggerLifecycle(force);
+        }
+        
         public System.Guid AddAppointment(HeuristicLab.Clients.Hive.Appointment appointment)
         {
@@ -1956,4 +1964,9 @@
         }
         
+        public System.Collections.Generic.List<HeuristicLab.Clients.Hive.LightweightJob> GetLightweightExperimentJobs(System.Guid experimentId)
+        {
+            return base.Channel.GetLightweightExperimentJobs(experimentId);
+        }
+        
         public HeuristicLab.Clients.Hive.JobData GetJobData(System.Guid jobId)
         {
@@ -2130,9 +2143,4 @@
             return base.Channel.GetResourceId(resourceName);
         }
-        
-        public void TriggerLifecycle(bool force)
-        {
-            base.Channel.TriggerLifecycle(force);
-        }
     }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/Job.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/Job.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/Job.cs	(revision 6006)
@@ -23,7 +23,7 @@
 using System.Collections.Generic;
 using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Clients.Hive {
-
   public partial class Job : LightweightJob {
 
@@ -38,4 +38,5 @@
       this.IsParentJob = original.IsParentJob;
       this.FinishWhenChildJobsFinished = original.FinishWhenChildJobsFinished;
+      this.HiveExperimentId = original.HiveExperimentId;
     }
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/LightweightJob.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/LightweightJob.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/LightweightJob.cs	(revision 6006)
@@ -26,5 +26,4 @@
 
 namespace HeuristicLab.Clients.Hive {
-
   public partial class LightweightJob : IDeepCloneable, IContent {
     public StateLog CurrentStateLog { get { return StateLog.LastOrDefault(); } }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/HeuristicLab.HiveEngine.Test.csproj
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/HeuristicLab.HiveEngine.Test.csproj	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/HeuristicLab.HiveEngine.Test.csproj	(revision 6006)
@@ -126,4 +126,5 @@
   </ItemGroup>
   <ItemGroup>
+    <None Include="app_services.config" />
     <None Include="app.config" />
   </ItemGroup>
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/Program.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/Program.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/Program.cs	(revision 6006)
@@ -33,5 +33,5 @@
       #region Credentials
       ServiceLocator.Instance.Username = "cneumuel";
-      ServiceLocator.Instance.Password = "Stormlord105.";
+      ServiceLocator.Instance.Password = "YouWillNeverKnow";
       #endregion
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/app_services.config
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/app_services.config	(revision 6006)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/app_services.config	(revision 6006)
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <configSections>
+    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+      <section name="HeuristicLab.PluginInfrastructure.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+      <section name="HeuristicLab.Optimizer.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+      <section name="HeuristicLab.Persistence.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+    </sectionGroup>
+  </configSections>
+  <connectionStrings>
+    <add name="HeuristicLab.Services.Hive.DataAccess.Properties.Settings.HeuristicLab_Hive_LinqConnectionString" connectionString="Data Source=localhost;Initial Catalog=HeuristicLab.Hive-3.4;Integrated Security=True;" providerName="System.Data.SqlClient" />
+  </connectionStrings>
+  <!-- [chn] TODO: system.web should be located in HeuristicLab.Hive.Server.Core/app.config, but the ConfigMerger does not merge system.web (yet) -->
+  <system.web>
+    <membership>
+      <providers>
+        <clear />
+        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="HeuristicLab.Authentication" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="HeuristicLab.Authentication" />
+      </providers>
+    </membership>
+    <roleManager enabled="true">
+      <providers>
+        <clear />
+        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="HeuristicLab.Authentication" applicationName="HeuristicLab.Authentication" />
+      </providers>
+    </roleManager>
+  </system.web>
+  <system.serviceModel>
+    <behaviors>
+      <endpointBehaviors>
+        <behavior name="SerializationBehavior">
+          <dataContractSerializer maxItemsInObjectGraph="1000000" />
+        </behavior>
+      </endpointBehaviors>
+    </behaviors>
+    <bindings>
+      <wsHttpBinding>
+        <binding name="WSHttpBinding_IUpdate" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="200000000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
+          <readerQuotas maxDepth="32" maxStringContentLength="32000" maxArrayLength="200000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
+          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
+          <security mode="Message">
+            <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
+            <message clientCredentialType="UserName" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" />
+          </security>
+        </binding>
+        <binding name="WSHttpBinding_IAdmin" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="200000000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
+          <readerQuotas maxDepth="32" maxStringContentLength="32000" maxArrayLength="200000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
+          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
+          <security mode="Message">
+            <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
+            <message clientCredentialType="UserName" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" />
+          </security>
+        </binding>
+        <binding name="wsHttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
+          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
+          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
+          <security mode="Message">
+            <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
+            <message clientCredentialType="UserName" negotiateServiceCredential="true" algorithmSuite="Default" />
+          </security>
+        </binding>
+      </wsHttpBinding>
+    </bindings>
+    <client>
+      <endpoint address="http://services.heuristiclab.com/Deployment-3.3/Update.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IUpdate" contract="HeuristicLab.PluginInfrastructure.Advanced.DeploymentService.IUpdate" name="WSHttpBinding_IUpdate">
+        <identity>
+          <certificate encodedValue="AwAAAAEAAAAUAAAAwK1+2oAmcy/mI2P2QjyiJRh0y60gAAAAAQAAACoCAAAwggImMIIBj6ADAgECAhAIkseQ2EEhgU720qJA61gqMA0GCSqGSIb3DQEBBAUAMCQxIjAgBgNVBAMTGXNlcnZpY2VzLmhldXJpc3RpY2xhYi5jb20wHhcNMTAwNTExMTExNDAyWhcNMzkxMjMxMjM1OTU5WjAkMSIwIAYDVQQDExlzZXJ2aWNlcy5oZXVyaXN0aWNsYWIuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq26Bwmwc7k+4W30qLQ2j+FInEL5BuH6opDY6CSlrtt3xQS/anrhvpbf3QghLDVINzcHkzbPmm/SguG4F85QLB6xO+tJaOvRo0iEK5g3c307vMIru7FJwk/OhplEQ5J1hbDgL3zOJlrWlgtqRVxCtVdF3XroI9BctOt1NkeKv9ewIDAQABo1kwVzBVBgNVHQEETjBMgBCjbgdYd4j5JgUuJ1Wo/GxroSYwJDEiMCAGA1UEAxMZc2VydmljZXMuaGV1cmlzdGljbGFiLmNvbYIQCJLHkNhBIYFO9tKiQOtYKjANBgkqhkiG9w0BAQQFAAOBgQAb/2xk2uQad68shSPl/uixWgvFI8WkxOTBopOLaLtDxwCeZ3mWVHdV9VnixHtThubnEBXAhYOCQSIXWtQuXFWO+gH3YyjTRJY5kTmXyuvBRTn3/so5SrQ7Rdlm9hf6E5YVX3tCjAy7ybUyaDUkQfmH5vmvgvpMzRfsJ1qhnUpJiQ==" />
+        </identity>
+      </endpoint>
+      <endpoint address="http://services.heuristiclab.com/Deployment-3.3/Admin.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IAdmin" contract="HeuristicLab.PluginInfrastructure.Advanced.DeploymentService.IAdmin" name="WSHttpBinding_IAdmin">
+        <identity>
+          <certificate encodedValue="AwAAAAEAAAAUAAAAwK1+2oAmcy/mI2P2QjyiJRh0y60gAAAAAQAAACoCAAAwggImMIIBj6ADAgECAhAIkseQ2EEhgU720qJA61gqMA0GCSqGSIb3DQEBBAUAMCQxIjAgBgNVBAMTGXNlcnZpY2VzLmhldXJpc3RpY2xhYi5jb20wHhcNMTAwNTExMTExNDAyWhcNMzkxMjMxMjM1OTU5WjAkMSIwIAYDVQQDExlzZXJ2aWNlcy5oZXVyaXN0aWNsYWIuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq26Bwmwc7k+4W30qLQ2j+FInEL5BuH6opDY6CSlrtt3xQS/anrhvpbf3QghLDVINzcHkzbPmm/SguG4F85QLB6xO+tJaOvRo0iEK5g3c307vMIru7FJwk/OhplEQ5J1hbDgL3zOJlrWlgtqRVxCtVdF3XroI9BctOt1NkeKv9ewIDAQABo1kwVzBVBgNVHQEETjBMgBCjbgdYd4j5JgUuJ1Wo/GxroSYwJDEiMCAGA1UEAxMZc2VydmljZXMuaGV1cmlzdGljbGFiLmNvbYIQCJLHkNhBIYFO9tKiQOtYKjANBgkqhkiG9w0BAQQFAAOBgQAb/2xk2uQad68shSPl/uixWgvFI8WkxOTBopOLaLtDxwCeZ3mWVHdV9VnixHtThubnEBXAhYOCQSIXWtQuXFWO+gH3YyjTRJY5kTmXyuvBRTn3/so5SrQ7Rdlm9hf6E5YVX3tCjAy7ybUyaDUkQfmH5vmvgvpMzRfsJ1qhnUpJiQ==" />
+        </identity>
+      </endpoint>
+      <endpoint address="http://services.heuristiclab.com/Hive-3.4/HiveService.svc" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding" contract="HeuristicLab.Clients.Hive.IHiveService" name="wsHttpBinding_IHiveService">
+        <identity>
+          <certificate encodedValue="AwAAAAEAAAAUAAAAwK1+2oAmcy/mI2P2QjyiJRh0y60gAAAAAQAAACoCAAAwggImMIIBj6ADAgECAhAIkseQ2EEhgU720qJA61gqMA0GCSqGSIb3DQEBBAUAMCQxIjAgBgNVBAMTGXNlcnZpY2VzLmhldXJpc3RpY2xhYi5jb20wHhcNMTAwNTExMTExNDAyWhcNMzkxMjMxMjM1OTU5WjAkMSIwIAYDVQQDExlzZXJ2aWNlcy5oZXVyaXN0aWNsYWIuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq26Bwmwc7k+4W30qLQ2j+FInEL5BuH6opDY6CSlrtt3xQS/anrhvpbf3QghLDVINzcHkzbPmm/SguG4F85QLB6xO+tJaOvRo0iEK5g3c307vMIru7FJwk/OhplEQ5J1hbDgL3zOJlrWlgtqRVxCtVdF3XroI9BctOt1NkeKv9ewIDAQABo1kwVzBVBgNVHQEETjBMgBCjbgdYd4j5JgUuJ1Wo/GxroSYwJDEiMCAGA1UEAxMZc2VydmljZXMuaGV1cmlzdGljbGFiLmNvbYIQCJLHkNhBIYFO9tKiQOtYKjANBgkqhkiG9w0BAQQFAAOBgQAb/2xk2uQad68shSPl/uixWgvFI8WkxOTBopOLaLtDxwCeZ3mWVHdV9VnixHtThubnEBXAhYOCQSIXWtQuXFWO+gH3YyjTRJY5kTmXyuvBRTn3/so5SrQ7Rdlm9hf6E5YVX3tCjAy7ybUyaDUkQfmH5vmvgvpMzRfsJ1qhnUpJiQ==" />
+        </identity>
+      </endpoint>
+    </client>
+  </system.serviceModel>
+  <runtime>
+    <gcServer enabled="true" />
+  </runtime>
+  <system.data>
+    <DbProviderFactories>
+      <remove invariant="System.Data.SQLite" />
+      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
+      <remove invariant="System.Data.SqlServerCe.3.5" />
+      <add name="Microsoft SQL Server Compact Data Provider" invariant="System.Data.SqlServerCe.3.5" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=3.5.1.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
+    </DbProviderFactories>
+  </system.data>
+  <userSettings>
+    <HeuristicLab.PluginInfrastructure.Properties.Settings>
+      <setting name="UpdateLocation" serializeAs="String">
+        <value>http://services.heuristiclab.com/Deployment-3.3/Update.svc</value>
+      </setting>
+      <setting name="UpdateLocationUserName" serializeAs="String">
+        <value>anonymous</value>
+      </setting>
+      <setting name="UpdateLocationPassword" serializeAs="String">
+        <value>GetTheLab!</value>
+      </setting>
+      <setting name="UpdateLocationAdministrationAddress" serializeAs="String">
+        <value>http://services.heuristiclab.com/Deployment-3.3/Admin.svc</value>
+      </setting>
+      <setting name="ShowPluginUploadControls" serializeAs="String">
+        <value>False</value>
+      </setting>
+    </HeuristicLab.PluginInfrastructure.Properties.Settings>
+    <HeuristicLab.Optimizer.Properties.Settings>
+      <setting name="ShowStartPage" serializeAs="String">
+        <value>True</value>
+      </setting>
+      <setting name="ShowOperatorsSidebar" serializeAs="String">
+        <value>False</value>
+      </setting>
+      <setting name="ShowClipboard" serializeAs="String">
+        <value>True</value>
+      </setting>
+      <setting name="ShowMaximized" serializeAs="String">
+        <value>True</value>
+      </setting>
+      <setting name="CollapseClipboard" serializeAs="String">
+        <value>True</value>
+      </setting>
+      <setting name="CollapseOperatorsSidebar" serializeAs="String">
+        <value>False</value>
+      </setting>
+    </HeuristicLab.Optimizer.Properties.Settings>
+    <HeuristicLab.Persistence.Properties.Settings>
+      <setting name="CustomConfigurations" serializeAs="String">
+        <value />
+      </setting>
+      <setting name="CustomConfigurationsTypeCache" serializeAs="String">
+        <value />
+      </setting>
+    </HeuristicLab.Persistence.Properties.Settings>
+  </userSettings>
+</configuration>
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HeuristicLab.HiveEngine-3.4.csproj
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HeuristicLab.HiveEngine-3.4.csproj	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HeuristicLab.HiveEngine-3.4.csproj	(revision 6006)
@@ -104,4 +104,7 @@
     <Reference Include="HeuristicLab.Clients.Common-3.3">
       <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Clients.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Clients.Hive.Views-3.4">
+      <HintPath>..\..\HeuristicLab.Clients.Hive.Views\3.4\obj\Debug\HeuristicLab.Clients.Hive.Views-3.4.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Collections-3.3">
@@ -162,6 +165,5 @@
     <Compile Include="HiveEngine.cs" />
     <Compile Include="Exceptions\HiveEngineException.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <None Include="Properties\AssemblyInfo.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
   </ItemGroup>
   <ItemGroup>
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HeuristicLabHiveEnginePlugin.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HeuristicLabHiveEnginePlugin.cs	(revision 6004)
+++ 	(revision )
@@ -1,40 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.PluginInfrastructure;
-
-namespace HeuristicLab.HiveEngine {
-  [Plugin("HeuristicLab.HiveEngine", "3.4.0.5958")]
-  [PluginFile("HeuristicLab.HiveEngine-3.4.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.Clients.Common", "3.3")]
-  [PluginDependency("HeuristicLab.Collections", "3.3")]
-  [PluginDependency("HeuristicLab.Common", "3.3")]
-  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
-  [PluginDependency("HeuristicLab.Core", "3.3")]
-  [PluginDependency("HeuristicLab.DataAccess", "3.3")]
-  [PluginDependency("HeuristicLab.Hive.Contracts", "3.3")]
-  [PluginDependency("HeuristicLab.Hive.ExperimentManager", "3.3")]
-  [PluginDependency("HeuristicLab.Hive.JobBase", "3.3")]
-  [PluginDependency("HeuristicLab.Persistence", "3.3")]
-  [PluginDependency("HeuristicLab.SequentialEngine", "3.3")]
-  public class HeuristicLabHiveEnginePlugin : PluginBase {
-  }
-}
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HiveEngine.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HiveEngine.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HiveEngine.cs	(revision 6006)
@@ -25,5 +25,5 @@
 
     [Storable]
-    public string ResourceIds { get; set; }
+    public string ResourceNames { get; set; }
 
     [Storable]
@@ -46,4 +46,18 @@
     }
 
+    [Storable]
+    private bool useLocalPlugins;
+    public bool UseLocalPlugins {
+      get { return useLocalPlugins; }
+      set { useLocalPlugins = value; }
+    }
+
+    [Storable]
+    private ItemCollection<HiveExperiment> hiveExperiments;
+    public ItemCollection<HiveExperiment> HiveExperiments {
+      get { return hiveExperiments; }
+      set { hiveExperiments = value; }
+    }
+
     private List<Plugin> onlinePlugins;
     public List<Plugin> OnlinePlugins {
@@ -60,5 +74,7 @@
     #region constructors and cloning
     public HiveEngine() {
-      ResourceIds = "HEAL";
+      ResourceNames = "HEAL";
+      HiveExperiments = new ItemCollection<HiveExperiment>();
+      Priority = 0;
     }
 
@@ -67,8 +83,9 @@
     protected HiveEngine(HiveEngine original, Cloner cloner)
       : base(original, cloner) {
-      this.ResourceIds = original.ResourceIds;
+      this.ResourceNames = original.ResourceNames;
       this.currentOperator = cloner.Clone(original.currentOperator);
       this.priority = original.priority;
       this.executionTimeOnHive = original.executionTimeOnHive;
+      this.useLocalPlugins = original.useLocalPlugins;
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -123,5 +140,4 @@
 
             IScope[] scopes = ExecuteOnHive(jobs, parentScopeClone, cancellationToken);
-            //IScope[] scopes = ExecuteLocally(jobs, parentScopeClone, cancellationToken);
             
             for (int i = 0; i < coll.Count; i++) {
@@ -186,18 +202,17 @@
     }
 
-    private IScope[] ExecuteLocally(EngineJob[] jobs, IScope parentScopeClone, CancellationToken cancellationToken) {
-      IScope[] scopes = new Scope[jobs.Length];
-
-      for (int i = 0; i < jobs.Length; i++) {
-        var job = (EngineJob)jobs[i].Clone();
-        job.Start();
-        while (job.ExecutionState != ExecutionState.Stopped) {
-          Thread.Sleep(100);
-        }
-        scopes[i] = ((IAtomicOperation)job.InitialOperation).Scope;
-      }
-
-      return scopes;
-    }
+    // testfunction:
+    //private IScope[] ExecuteLocally(EngineJob[] jobs, IScope parentScopeClone, CancellationToken cancellationToken) {
+    //  IScope[] scopes = new Scope[jobs.Length];
+    //  for (int i = 0; i < jobs.Length; i++) {
+    //    var job = (EngineJob)jobs[i].Clone();
+    //    job.Start();
+    //    while (job.ExecutionState != ExecutionState.Stopped) {
+    //      Thread.Sleep(100);
+    //    }
+    //    scopes[i] = ((IAtomicOperation)job.InitialOperation).Scope;
+    //  }
+    //  return scopes;
+    //}
 
     /// <summary>
@@ -211,4 +226,5 @@
       object locker = new object();
       IDictionary<Guid, int> jobIndices = new Dictionary<Guid, int>();
+      var hiveExperiment = new HiveExperiment();;
 
       try {
@@ -218,4 +234,12 @@
         int finishedCount = 0;
         int uploadCount = 0;
+
+        // create hive experiment
+        hiveExperiment.Name = "HiveEngine Run " + hiveExperiments.Count;
+        hiveExperiment.UseLocalPlugins = this.UseLocalPlugins;
+        hiveExperiment.ResourceNames = this.ResourceNames;
+        hiveExperiment.RefreshAutomatically = false;
+        hiveExperiment.Id = ServiceLocator.Instance.CallHiveService(s => s.AddHiveExperiment(hiveExperiment));
+        hiveExperiments.Add(hiveExperiment);
 
         // create upload-tasks
@@ -230,5 +254,5 @@
 
           uploadTasks.Add(Task.Factory.StartNew<Job>((keyValuePairObj) => {
-            return UploadJob(keyValuePairObj, parentScopeClone, cancellationToken, GetResourceIds());
+            return UploadJob(keyValuePairObj, parentScopeClone, cancellationToken, GetResourceIds(), hiveExperiment.Id);
           }, new KeyValuePair<int, EngineJob>(i, job), cancellationToken));
         }
@@ -313,5 +337,5 @@
 
         LogMessage(string.Format("All jobs finished (TotalExecutionTime: {0}).", executionTimes.Sum()));
-        DeleteJobs(jobIndices);
+        DeleteHiveExperiment(hiveExperiment.Id);
 
         return scopes;
@@ -319,5 +343,5 @@
       catch (OperationCanceledException e) {
         lock (locker) {
-          if (jobIndices != null) DeleteJobs(jobIndices);
+          if (jobIndices != null) DeleteHiveExperiment(hiveExperiment.Id);
         }
         throw e;
@@ -325,5 +349,5 @@
       catch (Exception e) {
         lock (locker) {
-          if (jobIndices != null) DeleteJobs(jobIndices);
+          if (jobIndices != null) DeleteHiveExperiment(hiveExperiment.Id);
         }
         LogException(e);
@@ -332,20 +356,12 @@
     }
 
-    private void DeleteJobs(IDictionary<Guid, int> jobIndices) {
-      if (jobIndices.Count > 0) {
-        TryAndRepeat(() => {
-          LogMessage(string.Format("Deleting {0} jobs on hive.", jobIndices.Count));
-          ServiceLocator.Instance.CallHiveService(service => {
-            foreach (Guid jobId in jobIndices.Keys) {
-              service.DeleteJob(jobId);
-            }
-            jobIndices.Clear();
-          });
-        }, 5, string.Format("Could not delete {0} jobs", jobIndices.Count));
-      }
+    private void DeleteHiveExperiment(Guid hiveExperimentId) {
+      TryAndRepeat(() => {
+        ServiceLocator.Instance.CallHiveService(s => s.DeleteHiveExperiment(hiveExperimentId));
+      }, 5, string.Format("Could not delete jobs"));
     }
 
     private static object locker = new object();
-    private Job UploadJob(object keyValuePairObj, IScope parentScopeClone, CancellationToken cancellationToken, List<Guid> resourceIds) {
+    private Job UploadJob(object keyValuePairObj, IScope parentScopeClone, CancellationToken cancellationToken, List<Guid> resourceIds, Guid hiveExperimentId) {
       var keyValuePair = (KeyValuePair<int, EngineJob>)keyValuePairObj;
       Job job = new Job();
@@ -370,4 +386,5 @@
         job.PluginsNeededIds = ServiceLocator.Instance.CallHiveService(s => PluginUtil.GetPluginDependencies(s, this.OnlinePlugins, this.AlreadyUploadedPlugins, neededPlugins, false));
         job.Priority = priority;
+        job.HiveExperimentId = hiveExperimentId;
 
         try {
@@ -396,5 +413,5 @@
     private List<Guid> GetResourceIds() {
       return ServiceLocator.Instance.CallHiveService(service => {
-        var resourceNames = ResourceIds.Split(';');
+        var resourceNames = ResourceNames.Split(';');
         var resourceIds = new List<Guid>();
         foreach (var resourceName in resourceNames) {
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/Views/HiveEngineView.Designer.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/Views/HiveEngineView.Designer.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/Views/HiveEngineView.Designer.cs	(revision 6006)
@@ -30,14 +30,16 @@
       this.label1 = new System.Windows.Forms.Label();
       this.executionTimeOnHiveTextBox = new System.Windows.Forms.TextBox();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.jobsTabPage = new System.Windows.Forms.TabPage();
+      this.hiveExperimentListView = new HeuristicLab.Clients.Hive.Views.HiveExperimentListView();
+      this.logTabPage = new System.Windows.Forms.TabPage();
+      this.logView = new HeuristicLab.Core.Views.LogView();
+      this.executionTimeLabel = new System.Windows.Forms.Label();
+      this.executionTimeTextBox = new System.Windows.Forms.TextBox();
+      this.useLocalPluginsCheckBox = new System.Windows.Forms.CheckBox();
+      this.tabControl.SuspendLayout();
+      this.jobsTabPage.SuspendLayout();
+      this.logTabPage.SuspendLayout();
       this.SuspendLayout();
-      // 
-      // executionTimeTextBox
-      // 
-      this.executionTimeTextBox.Size = new System.Drawing.Size(623, 20);
-      // 
-      // logView
-      // 
-      this.logView.Location = new System.Drawing.Point(0, 78);
-      this.logView.Size = new System.Drawing.Size(715, 469);
       // 
       // resourceIdsLabel
@@ -57,5 +59,5 @@
       this.resourceIdsTextBox.Location = new System.Drawing.Point(189, 52);
       this.resourceIdsTextBox.Name = "resourceIdsTextBox";
-      this.resourceIdsTextBox.Size = new System.Drawing.Size(526, 20);
+      this.resourceIdsTextBox.Size = new System.Drawing.Size(405, 20);
       this.resourceIdsTextBox.TabIndex = 4;
       this.resourceIdsTextBox.Text = "HEAL";
@@ -97,6 +99,95 @@
       this.executionTimeOnHiveTextBox.Name = "executionTimeOnHiveTextBox";
       this.executionTimeOnHiveTextBox.ReadOnly = true;
-      this.executionTimeOnHiveTextBox.Size = new System.Drawing.Size(586, 20);
+      this.executionTimeOnHiveTextBox.Size = new System.Drawing.Size(577, 20);
       this.executionTimeOnHiveTextBox.TabIndex = 8;
+      // 
+      // tabControl
+      // 
+      this.tabControl.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.tabControl.Controls.Add(this.jobsTabPage);
+      this.tabControl.Controls.Add(this.logTabPage);
+      this.tabControl.Location = new System.Drawing.Point(3, 78);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(700, 460);
+      this.tabControl.TabIndex = 9;
+      // 
+      // jobsTabPage
+      // 
+      this.jobsTabPage.Controls.Add(this.hiveExperimentListView);
+      this.jobsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.jobsTabPage.Name = "jobsTabPage";
+      this.jobsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.jobsTabPage.Size = new System.Drawing.Size(692, 434);
+      this.jobsTabPage.TabIndex = 0;
+      this.jobsTabPage.Text = "Jobs";
+      this.jobsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // hiveExperimentListView
+      // 
+      this.hiveExperimentListView.Caption = "HiveExperimentList View";
+      this.hiveExperimentListView.Content = null;
+      this.hiveExperimentListView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.hiveExperimentListView.Location = new System.Drawing.Point(3, 3);
+      this.hiveExperimentListView.Name = "hiveExperimentListView";
+      this.hiveExperimentListView.ReadOnly = false;
+      this.hiveExperimentListView.Size = new System.Drawing.Size(686, 428);
+      this.hiveExperimentListView.TabIndex = 0;
+      // 
+      // logTabPage
+      // 
+      this.logTabPage.Controls.Add(this.logView);
+      this.logTabPage.Location = new System.Drawing.Point(4, 22);
+      this.logTabPage.Name = "logTabPage";
+      this.logTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.logTabPage.Size = new System.Drawing.Size(692, 434);
+      this.logTabPage.TabIndex = 1;
+      this.logTabPage.Text = "Log";
+      this.logTabPage.UseVisualStyleBackColor = true;
+      // 
+      // logView
+      // 
+      this.logView.Caption = "SlaveView";
+      this.logView.Content = null;
+      this.logView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.logView.Location = new System.Drawing.Point(3, 3);
+      this.logView.Name = "logView";
+      this.logView.ReadOnly = false;
+      this.logView.Size = new System.Drawing.Size(686, 428);
+      this.logView.TabIndex = 0;
+      // 
+      // executionTimeLabel
+      // 
+      this.executionTimeLabel.AutoSize = true;
+      this.executionTimeLabel.Location = new System.Drawing.Point(4, 6);
+      this.executionTimeLabel.Name = "executionTimeLabel";
+      this.executionTimeLabel.Size = new System.Drawing.Size(83, 13);
+      this.executionTimeLabel.TabIndex = 10;
+      this.executionTimeLabel.Text = "Execution Time:";
+      // 
+      // executionTimeTextBox
+      // 
+      this.executionTimeTextBox.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.executionTimeTextBox.Location = new System.Drawing.Point(129, 3);
+      this.executionTimeTextBox.Name = "executionTimeTextBox";
+      this.executionTimeTextBox.ReadOnly = true;
+      this.executionTimeTextBox.Size = new System.Drawing.Size(577, 20);
+      this.executionTimeTextBox.TabIndex = 11;
+      // 
+      // useLocalPluginsCheckBox
+      // 
+      this.useLocalPluginsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.useLocalPluginsCheckBox.AutoSize = true;
+      this.useLocalPluginsCheckBox.Location = new System.Drawing.Point(600, 55);
+      this.useLocalPluginsCheckBox.Name = "useLocalPluginsCheckBox";
+      this.useLocalPluginsCheckBox.Size = new System.Drawing.Size(103, 17);
+      this.useLocalPluginsCheckBox.TabIndex = 12;
+      this.useLocalPluginsCheckBox.Text = "useLocalPlugins";
+      this.useLocalPluginsCheckBox.UseVisualStyleBackColor = true;
+      this.useLocalPluginsCheckBox.CheckedChanged += new System.EventHandler(this.useLocalPluginsCheckBox_CheckedChanged);
       // 
       // HiveEngineView
@@ -104,4 +195,8 @@
       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.useLocalPluginsCheckBox);
+      this.Controls.Add(this.executionTimeTextBox);
+      this.Controls.Add(this.executionTimeLabel);
+      this.Controls.Add(this.tabControl);
       this.Controls.Add(this.label1);
       this.Controls.Add(this.executionTimeOnHiveTextBox);
@@ -111,14 +206,8 @@
       this.Controls.Add(this.resourceIdsTextBox);
       this.Name = "HiveEngineView";
-      this.Size = new System.Drawing.Size(715, 550);
-      this.Controls.SetChildIndex(this.resourceIdsTextBox, 0);
-      this.Controls.SetChildIndex(this.resourceIdsLabel, 0);
-      this.Controls.SetChildIndex(this.priorityLabel, 0);
-      this.Controls.SetChildIndex(this.priorityTextBox, 0);
-      this.Controls.SetChildIndex(this.logView, 0);
-      this.Controls.SetChildIndex(this.executionTimeLabel, 0);
-      this.Controls.SetChildIndex(this.executionTimeTextBox, 0);
-      this.Controls.SetChildIndex(this.executionTimeOnHiveTextBox, 0);
-      this.Controls.SetChildIndex(this.label1, 0);
+      this.Size = new System.Drawing.Size(706, 541);
+      this.tabControl.ResumeLayout(false);
+      this.jobsTabPage.ResumeLayout(false);
+      this.logTabPage.ResumeLayout(false);
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -134,4 +223,12 @@
     private System.Windows.Forms.Label label1;
     protected System.Windows.Forms.TextBox executionTimeOnHiveTextBox;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage jobsTabPage;
+    private System.Windows.Forms.TabPage logTabPage;
+    private System.Windows.Forms.Label executionTimeLabel;
+    protected System.Windows.Forms.TextBox executionTimeTextBox;
+    private System.Windows.Forms.CheckBox useLocalPluginsCheckBox;
+    private HeuristicLab.Core.Views.LogView logView;
+    private Clients.Hive.Views.HiveExperimentListView hiveExperimentListView;
   }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/Views/HiveEngineView.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/Views/HiveEngineView.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/Views/HiveEngineView.cs	(revision 6006)
@@ -1,17 +1,10 @@
 ﻿using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.Data;
-using System.Linq;
-using System.Text;
+using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
-using HeuristicLab.Optimization.Views;
-using HeuristicLab.Core.Views;
 
 namespace HeuristicLab.HiveEngine.Views {
   [View("Hive Engine View")]
   [Content(typeof(HiveEngine), IsDefaultView = true)]
-  public sealed partial class HiveEngineView : EngineView {
+  public sealed partial class HiveEngineView : ItemView {
     public new HiveEngine Content {
       get { return (HiveEngine)base.Content; }
@@ -24,4 +17,5 @@
 
     protected override void DeregisterContentEvents() {
+      Content.ExecutionStateChanged -= new EventHandler(Content_ExecutionStateChanged);
       Content.ExecutionTimeOnHiveChanged -= new EventHandler(Content_ExecutionTimeOnHiveChanged);
       base.DeregisterContentEvents();
@@ -30,8 +24,17 @@
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
+      Content.ExecutionStateChanged += new EventHandler(Content_ExecutionStateChanged);
       Content.ExecutionTimeOnHiveChanged += new EventHandler(Content_ExecutionTimeOnHiveChanged);
     }
 
     #region Event Handlers (Content)
+    private void Content_ExecutionStateChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler(Content_ExecutionStateChanged), sender, e);
+      } else {
+        executionTimeTextBox.Text = Content.ExecutionTime.ToString();
+      }
+    }
+
     private void Content_ExecutionTimeOnHiveChanged(object sender, EventArgs e) {
       if (InvokeRequired) {
@@ -49,8 +52,14 @@
         priorityTextBox.Text = string.Empty;
         executionTimeOnHiveTextBox.Text = string.Empty;
+        useLocalPluginsCheckBox.Checked = false;
+        hiveExperimentListView.Content = null;
+        logView.Content = null;
       } else {
-        resourceIdsTextBox.Text = Content.ResourceIds;
+        resourceIdsTextBox.Text = Content.ResourceNames;
         priorityTextBox.Text = Content.Priority.ToString();
         executionTimeOnHiveTextBox.Text = Content.ExecutionTimeOnHive.ToString();
+        useLocalPluginsCheckBox.Checked = Content.UseLocalPlugins;
+        hiveExperimentListView.Content = Content.HiveExperiments;
+        logView.Content = Content.Log;
       }
     }
@@ -62,7 +71,9 @@
         resourceIdsTextBox.ReadOnly = this.ReadOnly;
         priorityTextBox.ReadOnly = this.ReadOnly;
+        useLocalPluginsCheckBox.Enabled = !this.ReadOnly;
       } else {
         resourceIdsTextBox.ReadOnly = false;
         priorityTextBox.ReadOnly = false;
+        useLocalPluginsCheckBox.Enabled = false;
       }
     }
@@ -70,11 +81,17 @@
     #region Event Handlers (child controls)
     private void resourceIdsTextBox_TextChanged(object sender, EventArgs e) {
-      Content.ResourceIds = resourceIdsTextBox.Text;
+      Content.ResourceNames = resourceIdsTextBox.Text;
     }
-    #endregion
 
     private void priorityTextBox_TextChanged(object sender, EventArgs e) {
       Content.Priority = int.Parse(priorityTextBox.Text);
     }
+
+    private void useLocalPluginsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      Content.UseLocalPlugins = useLocalPluginsCheckBox.Checked;
+    }
+    #endregion
+
+
   }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/HiveExperiment.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/HiveExperiment.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/HiveExperiment.cs	(revision 6006)
@@ -30,6 +30,4 @@
     public Guid OwnerUserId { get; set; }
     [DataMember]
-    public Guid RootJobId { get; set; }
-    [DataMember]
     public DateTime DateCreated { get; set; }
     [DataMember]
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Job.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Job.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Job.cs	(revision 6006)
@@ -42,4 +42,6 @@
     [DataMember]
     public bool FinishWhenChildJobsFinished { get; set; }
+    [DataMember]
+    public Guid HiveExperimentId { get; set; }
 
     public Job() {
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/ServiceContracts/IHiveService.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/ServiceContracts/IHiveService.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/ServiceContracts/IHiveService.cs	(revision 6006)
@@ -17,17 +17,20 @@
     Guid AddChildJob(Guid parentJobId, Job job, JobData jobData);
 
-    [OperationContract] // formerly GetJobById
+    [OperationContract] 
     Job GetJob(Guid jobId);
 
-    [OperationContract] // formerly GetAllJobs
+    [OperationContract] 
     IEnumerable<Job> GetJobs();
 
-    [OperationContract] // formerly GetJobResults
+    [OperationContract] 
     IEnumerable<LightweightJob> GetLightweightJobs(IEnumerable<Guid> jobIds);
 
-    [OperationContract] // formerly GetChildJobResults
+    [OperationContract] 
     IEnumerable<LightweightJob> GetLightweightChildJobs(Guid? parentJobId, bool recursive, bool includeParent);
 
-    [OperationContract] // formerly GetLastSerializedResult
+    [OperationContract] 
+    IEnumerable<LightweightJob> GetLightweightExperimentJobs(Guid experimentId);
+
+    [OperationContract]
     JobData GetJobData(Guid jobId);
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Convert.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Convert.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Convert.cs	(revision 6006)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Data.Linq;
 using System.Linq;
@@ -37,12 +38,13 @@
         ParentJobId = source.ParentJobId,
         Priority = source.Priority,
-        PluginsNeededIds = source.RequiredPlugins.Select(x => x.PluginId).ToList(),
+        PluginsNeededIds = (source.RequiredPlugins == null ? new List<Guid>() : source.RequiredPlugins.Select(x => x.PluginId).ToList()),
         LastHeartbeat = source.LastHeartbeat,
         State = source.State,
-        StateLog = source.StateLogs.Select(x => Convert.ToDto(x)).OrderBy(x => x.DateTime).ToList(),
+        StateLog = (source.StateLogs == null ? new List<DT.StateLog>() : source.StateLogs.Select(x => Convert.ToDto(x)).OrderBy(x => x.DateTime).ToList()),
         IsParentJob = source.IsParentJob,
         FinishWhenChildJobsFinished = source.FinishWhenChildJobsFinished,
         Command = source.Command,
-        LastJobDataUpdate = source.JobData.LastUpdate
+        LastJobDataUpdate = (source.JobData == null ? DateTime.MinValue : source.JobData.LastUpdate),
+        HiveExperimentId = source.HiveExperimentId
       };
     }
@@ -71,4 +73,5 @@
         target.Command = source.Command;
         // RequiredPlugins are added by Dao
+        target.HiveExperimentId = source.HiveExperimentId;
       }
     }
@@ -129,5 +132,5 @@
     public static DT.HiveExperiment ToDto(HiveExperiment source) {
       if (source == null) return null;
-      return new DT.HiveExperiment { Id = source.HiveExperimentId, Description = source.Description, Name = source.Name, RootJobId = source.RootJobId, OwnerUserId = source.OwnerUserId, DateCreated = source.DateCreated, ResourceNames = source.ResourceIds, LastAccessed = source.LastAccessed };
+      return new DT.HiveExperiment { Id = source.HiveExperimentId, Description = source.Description, Name = source.Name, OwnerUserId = source.OwnerUserId, DateCreated = source.DateCreated, ResourceNames = source.ResourceIds, LastAccessed = source.LastAccessed };
     }
     public static HiveExperiment ToEntity(DT.HiveExperiment source) {
@@ -138,5 +141,5 @@
     public static void ToEntity(DT.HiveExperiment source, HiveExperiment target) {
       if ((source != null) && (target != null)) {
-        target.HiveExperimentId = source.Id; target.Description = source.Description; target.Name = source.Name; target.RootJobId = source.RootJobId; target.OwnerUserId = source.OwnerUserId; target.DateCreated = source.DateCreated; target.ResourceIds = source.ResourceNames; target.LastAccessed = source.LastAccessed;
+        target.HiveExperimentId = source.Id; target.Description = source.Description; target.Name = source.Name; target.OwnerUserId = source.OwnerUserId; target.DateCreated = source.DateCreated; target.ResourceIds = source.ResourceNames; target.LastAccessed = source.LastAccessed;
       }
     }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDao.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDao.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDao.cs	(revision 6006)
@@ -237,7 +237,9 @@
 
     private DT.HiveExperiment AddStatsToExperiment(HiveDataContext db, DT.HiveExperiment exp) {
-      var jobs = new List<Job>();
-      CollectChildJobs(db, exp.RootJobId, jobs);
-      exp.JobCount = jobs.Count;
+      if (exp == null)
+        return null;
+
+      var jobs = db.Jobs.Where(j => j.HiveExperimentId == exp.Id);
+      exp.JobCount = jobs.Count();
       exp.CalculatingCount = jobs.Count(j => j.State == JobState.Calculating);
       exp.FinishedCount = jobs.Count(j => j.State == JobState.Finished);
@@ -575,10 +577,5 @@
     public Guid GetExperimentForJob(Guid jobId) {
       using (var db = CreateContext()) {
-        var job = db.Jobs.SingleOrDefault(j => j.JobId == jobId);
-        if (job.ParentJobId.HasValue) {
-          return GetExperimentForJob(job.ParentJobId.Value);
-        } else {
-          return db.HiveExperiments.SingleOrDefault(he => he.RootJobId == jobId).HiveExperimentId;
-        }
+        return db.Jobs.Single(j => j.JobId == jobId).HiveExperimentId;
       }
     }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml	(revision 6006)
@@ -70,4 +70,5 @@
       <Column Name="FinishWhenChildJobsFinished" Type="System.Boolean" DbType="Bit" CanBeNull="false" />
       <Column Name="Command" Type="global::HeuristicLab.Services.Hive.Common.DataTransfer.Command?" DbType="VarChar(30)" CanBeNull="true" />
+      <Column Name="HiveExperimentId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" CanBeNull="false" />
       <Association Name="Job_AssignedResource" Member="AssignedResources" ThisKey="JobId" OtherKey="JobId" Type="AssignedResource" />
       <Association Name="Job_RequiredPlugin" Member="RequiredPlugins" ThisKey="JobId" OtherKey="JobId" Type="RequiredPlugin" />
@@ -76,4 +77,5 @@
       <Association Name="Job_StateLog" Member="StateLogs" ThisKey="JobId" OtherKey="JobId" Type="StateLog" />
       <Association Name="Job_Job" Member="ParentJob" Storage="_Job1" ThisKey="ParentJobId" OtherKey="JobId" Type="Job" IsForeignKey="true" />
+      <Association Name="HiveExperiment_Job" Member="HiveExperiment" ThisKey="HiveExperimentId" OtherKey="HiveExperimentId" Type="HiveExperiment" IsForeignKey="true" />
     </Type>
   </Table>
@@ -97,10 +99,9 @@
       <Column Name="ResourceIds" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
       <Column Name="OwnerUserId" Storage="_UserId" Type="System.Guid" DbType="UniqueIdentifier" CanBeNull="false" />
-      <Column Name="RootJobId" Type="System.Guid" DbType="UniqueIdentifier" CanBeNull="false" />
       <Column Name="DateCreated" Type="System.DateTime" DbType="DateTime" CanBeNull="false" />
       <Column Name="LastAccessed" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
       <Column Name="IsHiveEngine" Type="System.Boolean" DbType="Bit" CanBeNull="false" />
       <Association Name="HiveExperiment_HiveExperimentPermission" Member="HiveExperimentPermissions" ThisKey="HiveExperimentId" OtherKey="HiveExperimentId" Type="HiveExperimentPermission" />
-      <Association Name="Job_HiveExperiment" Member="RootJob" Storage="_Job" ThisKey="RootJobId" OtherKey="JobId" Type="Job" IsForeignKey="true" DeleteRule="CASCADE" />
+      <Association Name="HiveExperiment_Job" Member="Jobs" ThisKey="HiveExperimentId" OtherKey="HiveExperimentId" Type="Job" />
     </Type>
   </Table>
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml.layout
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml.layout	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml.layout	(revision 6006)
@@ -27,8 +27,8 @@
       </nestedChildShapes>
     </classShape>
-    <classShape Id="695bfc39-59f3-4e60-8644-f847964bf62c" absoluteBounds="6.5, 1, 2, 2.9247054036458331">
+    <classShape Id="695bfc39-59f3-4e60-8644-f847964bf62c" absoluteBounds="6.5, 1, 2, 3.1170068359374996">
       <DataClassMoniker Name="/HiveDataContext/Job" />
       <nestedChildShapes>
-        <elementListCompartment Id="a6a30e11-03d1-4869-82e6-b733f4ef9974" absoluteBounds="6.5150000000000006, 1.46, 1.9700000000000002, 2.364705403645833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+        <elementListCompartment Id="a6a30e11-03d1-4869-82e6-b733f4ef9974" absoluteBounds="6.5150000000000006, 1.46, 1.9700000000000002, 2.5570068359375" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
       </nestedChildShapes>
     </classShape>
@@ -39,8 +39,8 @@
       </nestedChildShapes>
     </classShape>
-    <classShape Id="e6f840cc-2968-4be1-b234-eef624ccacbb" absoluteBounds="4.125, 2.625, 2, 2.5401025390624996">
+    <classShape Id="e6f840cc-2968-4be1-b234-eef624ccacbb" absoluteBounds="4.125, 2.625, 2, 2.3478011067708326">
       <DataClassMoniker Name="/HiveDataContext/HiveExperiment" />
       <nestedChildShapes>
-        <elementListCompartment Id="0c65d4e1-256a-4a91-9a57-392f25e4de7f" absoluteBounds="4.1400000000000006, 3.0850000000000009, 1.9700000000000002, 1.9801025390625" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+        <elementListCompartment Id="0c65d4e1-256a-4a91-9a57-392f25e4de7f" absoluteBounds="4.1400000000000006, 3.0850000000000009, 1.9700000000000002, 1.7878011067708333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
       </nestedChildShapes>
     </classShape>
@@ -76,5 +76,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(7.98437325 : 3.92470540364583); (7.98437325 : 4.59300017447917); (8.875 : 4.59300017447917)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(7.8398428125 : 4.1170068359375); (7.8398428125 : 4.689150890625); (8.875 : 4.689150890625)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/Job/Job_AssignedResource" />
       <nodes>
@@ -83,5 +83,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(7.179686625 : 3.92470540364583); (7.179686625 : 5.5)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(7.10742140625 : 4.1170068359375); (7.10742140625 : 5.5)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/Job/Job_RequiredPlugin" />
       <nodes>
@@ -102,11 +102,4 @@
         <classShapeMoniker Id="706a4581-6daf-4e71-ae2a-87d50b27a051" />
         <classShapeMoniker Id="8d5712f7-7a1a-4a89-bd4d-fd60200d3306" />
-      </nodes>
-    </associationConnector>
-    <associationConnector edgePoints="[(6.5 : 3.27485270182292); (6.125 : 3.27485270182292)]" fixedFrom="Algorithm" fixedTo="Algorithm">
-      <AssociationMoniker Name="/HiveDataContext/Job/Job_HiveExperiment" />
-      <nodes>
-        <classShapeMoniker Id="695bfc39-59f3-4e60-8644-f847964bf62c" />
-        <classShapeMoniker Id="e6f840cc-2968-4be1-b234-eef624ccacbb" />
       </nodes>
     </associationConnector>
@@ -177,5 +170,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(4.125 : 4.39505126953125); (3.75 : 4.39505126953125)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+    <associationConnector edgePoints="[(4.125 : 4.29890055338542); (3.75 : 4.29890055338542)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/HiveExperiment/HiveExperiment_HiveExperimentPermission" />
       <nodes>
@@ -190,4 +183,11 @@
       </nestedChildShapes>
     </classShape>
+    <associationConnector edgePoints="[(6.125 : 3.37100341796875); (6.5 : 3.37100341796875)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/HiveDataContext/HiveExperiment/HiveExperiment_Job" />
+      <nodes>
+        <classShapeMoniker Id="e6f840cc-2968-4be1-b234-eef624ccacbb" />
+        <classShapeMoniker Id="695bfc39-59f3-4e60-8644-f847964bf62c" />
+      </nodes>
+    </associationConnector>
   </nestedChildShapes>
 </ordesignerObjectsDiagram>
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.designer.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.designer.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.designer.cs	(revision 6006)
@@ -1424,4 +1424,6 @@
 		private global::HeuristicLab.Services.Hive.Common.DataTransfer.Command? _Command;
 		
+		private System.Guid _HiveExperimentId;
+		
 		private EntitySet<AssignedResource> _AssignedResources;
 		
@@ -1435,4 +1437,6 @@
 		
 		private EntityRef<Job> _Job1;
+		
+		private EntityRef<HiveExperiment> _HiveExperiment;
 		
     #region Extensibility Method Definitions
@@ -1462,4 +1466,6 @@
     partial void OnCommandChanging(global::HeuristicLab.Services.Hive.Common.DataTransfer.Command? value);
     partial void OnCommandChanged();
+    partial void OnHiveExperimentIdChanging(System.Guid value);
+    partial void OnHiveExperimentIdChanged();
     #endregion
 		
@@ -1472,4 +1478,5 @@
 			this._StateLogs = new EntitySet<StateLog>(new Action<StateLog>(this.attach_StateLogs), new Action<StateLog>(this.detach_StateLogs));
 			this._Job1 = default(EntityRef<Job>);
+			this._HiveExperiment = default(EntityRef<HiveExperiment>);
 			OnCreated();
 		}
@@ -1699,4 +1706,28 @@
 		}
 		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_HiveExperimentId", DbType="UniqueIdentifier NOT NULL")]
+		public System.Guid HiveExperimentId
+		{
+			get
+			{
+				return this._HiveExperimentId;
+			}
+			set
+			{
+				if ((this._HiveExperimentId != value))
+				{
+					if (this._HiveExperiment.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnHiveExperimentIdChanging(value);
+					this.SendPropertyChanging();
+					this._HiveExperimentId = value;
+					this.SendPropertyChanged("HiveExperimentId");
+					this.OnHiveExperimentIdChanged();
+				}
+			}
+		}
+		
 		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Job_AssignedResource", Storage="_AssignedResources", ThisKey="JobId", OtherKey="JobId")]
 		public EntitySet<AssignedResource> AssignedResources
@@ -1810,4 +1841,38 @@
 					}
 					this.SendPropertyChanged("ParentJob");
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="HiveExperiment_Job", Storage="_HiveExperiment", ThisKey="HiveExperimentId", OtherKey="HiveExperimentId", IsForeignKey=true)]
+		public HiveExperiment HiveExperiment
+		{
+			get
+			{
+				return this._HiveExperiment.Entity;
+			}
+			set
+			{
+				HiveExperiment previousValue = this._HiveExperiment.Entity;
+				if (((previousValue != value) 
+							|| (this._HiveExperiment.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._HiveExperiment.Entity = null;
+						previousValue.Jobs.Remove(this);
+					}
+					this._HiveExperiment.Entity = value;
+					if ((value != null))
+					{
+						value.Jobs.Add(this);
+						this._HiveExperimentId = value.HiveExperimentId;
+					}
+					else
+					{
+						this._HiveExperimentId = default(System.Guid);
+					}
+					this.SendPropertyChanged("HiveExperiment");
 				}
 			}
@@ -2146,6 +2211,4 @@
 		private System.Guid _UserId;
 		
-		private System.Guid _RootJobId;
-		
 		private System.DateTime _DateCreated;
 		
@@ -2156,5 +2219,5 @@
 		private EntitySet<HiveExperimentPermission> _HiveExperimentPermissions;
 		
-		private EntityRef<Job> _Job;
+		private EntitySet<Job> _Jobs;
 		
     #region Extensibility Method Definitions
@@ -2172,6 +2235,4 @@
     partial void OnOwnerUserIdChanging(System.Guid value);
     partial void OnOwnerUserIdChanged();
-    partial void OnRootJobIdChanging(System.Guid value);
-    partial void OnRootJobIdChanged();
     partial void OnDateCreatedChanging(System.DateTime value);
     partial void OnDateCreatedChanged();
@@ -2185,5 +2246,5 @@
 		{
 			this._HiveExperimentPermissions = new EntitySet<HiveExperimentPermission>(new Action<HiveExperimentPermission>(this.attach_HiveExperimentPermissions), new Action<HiveExperimentPermission>(this.detach_HiveExperimentPermissions));
-			this._Job = default(EntityRef<Job>);
+			this._Jobs = new EntitySet<Job>(new Action<Job>(this.attach_Jobs), new Action<Job>(this.detach_Jobs));
 			OnCreated();
 		}
@@ -2289,28 +2350,4 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RootJobId", DbType="UniqueIdentifier")]
-		public System.Guid RootJobId
-		{
-			get
-			{
-				return this._RootJobId;
-			}
-			set
-			{
-				if ((this._RootJobId != value))
-				{
-					if (this._Job.HasLoadedOrAssignedValue)
-					{
-						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
-					}
-					this.OnRootJobIdChanging(value);
-					this.SendPropertyChanging();
-					this._RootJobId = value;
-					this.SendPropertyChanged("RootJobId");
-					this.OnRootJobIdChanged();
-				}
-			}
-		}
-		
 		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_DateCreated", DbType="DateTime")]
 		public System.DateTime DateCreated
@@ -2386,19 +2423,14 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Job_HiveExperiment", Storage="_Job", ThisKey="RootJobId", OtherKey="JobId", IsForeignKey=true, DeleteRule="CASCADE")]
-		public Job RootJob
-		{
-			get
-			{
-				return this._Job.Entity;
-			}
-			set
-			{
-				if ((this._Job.Entity != value))
-				{
-					this.SendPropertyChanging();
-					this._Job.Entity = value;
-					this.SendPropertyChanged("RootJob");
-				}
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="HiveExperiment_Job", Storage="_Jobs", ThisKey="HiveExperimentId", OtherKey="HiveExperimentId")]
+		public EntitySet<Job> Jobs
+		{
+			get
+			{
+				return this._Jobs;
+			}
+			set
+			{
+				this._Jobs.Assign(value);
 			}
 		}
@@ -2431,4 +2463,16 @@
 		
 		private void detach_HiveExperimentPermissions(HiveExperimentPermission entity)
+		{
+			this.SendPropertyChanging();
+			entity.HiveExperiment = null;
+		}
+		
+		private void attach_Jobs(Job entity)
+		{
+			this.SendPropertyChanging();
+			entity.HiveExperiment = this;
+		}
+		
+		private void detach_Jobs(Job entity)
 		{
 			this.SendPropertyChanging();
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Tools/prepareHiveDatabase.sql
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Tools/prepareHiveDatabase.sql	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Tools/prepareHiveDatabase.sql	(revision 6006)
@@ -55,4 +55,11 @@
 GO
 
+--ALTER TABLE [dbo].[Job]  DROP  CONSTRAINT [HiveExperiment_Job]
+--ALTER TABLE [dbo].[Job]  WITH CHECK ADD CONSTRAINT [HiveExperiment_Job] FOREIGN KEY([HiveExperimentId])
+--REFERENCES [dbo].[HiveExperiment] ([HiveExperimentId])
+--ON UPDATE CASCADE
+--ON DELETE CASCADE
+--GO
+
 ALTER TABLE dbo.Plugin ALTER COLUMN PluginId ADD ROWGUIDCOL;
 ALTER TABLE dbo.Plugin WITH NOCHECK ADD CONSTRAINT [DF_Plugin_PluginId] DEFAULT (newid()) FOR PluginId;
@@ -107,11 +114,13 @@
 -- =============================================
 -- Author:		cneumuel
--- Create date: 11.11.2010
--- Description:	Deletes the root-job of the experiment when experiment is deleted
+-- Create date: 11.04.2011
+-- Description:	Deletes all associated jobs. This cannot be done with cascading delete, 
+--              because the job table defines a INSTEAD OF DELETE trigger itself, which
+--              is not compatible with cascading deletes.
 -- =============================================
-CREATE TRIGGER [dbo].[tr_HiveExperimentDeleteCascade] ON [dbo].[HiveExperiment] FOR DELETE AS 
-SET NOCOUNT ON
-DELETE Job FROM deleted, Job WHERE Job.JobId = deleted.RootJobId
-GO
+ALTER TRIGGER [dbo].[tr_HiveExperimentDeleteCascade] ON [dbo].[HiveExperiment] INSTEAD OF DELETE AS 
+BEGIN
+	DELETE Job FROM Job WHERE Job.HiveExperimentId = HiveExperimentId
+END
 
 SET ANSI_NULLS ON
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/DaoTests.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/DaoTests.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/DaoTests.cs	(revision 6006)
@@ -15,5 +15,4 @@
     [ClassInitialize]
     public static void MyClassInitialize(TestContext testContext) {
-      PluginLoader.pluginAssemblies.Any();
       ServiceLocator.Instance = new MockServiceLocator(ServiceLocator.Instance);
     }
@@ -26,4 +25,11 @@
     public void TestJobDao() {
       IHiveDao dao = ServiceLocator.Instance.HiveDao;
+
+      DT.HiveExperiment he = new DT.HiveExperiment();
+      he.DateCreated = DateTime.Now;
+      he.Name = "TestExperiment";
+      he.OwnerUserId = Guid.NewGuid();
+      he.ResourceNames = "HEAL";
+      he.Id = dao.AddHiveExperiment(he);
 
       DT.Job job1 = new DT.Job();
@@ -31,4 +37,5 @@
       job1.StateLog.Add(new DT.StateLog { State = JobState.Offline, DateTime = DateTime.Now });
       job1.Command = Command.Pause;
+      job1.HiveExperimentId = he.Id;
 
       DT.JobData jobData1 = new DT.JobData();
@@ -66,4 +73,5 @@
       Assert.AreEqual(job1.StateLog.Count, job1loaded.StateLog.Count);
       Assert.AreEqual(job1.Command, job1loaded.Command);
+      Assert.AreEqual(job1.HiveExperimentId, job1loaded.HiveExperimentId);
       Assert.IsTrue(Math.Abs((job1loaded.LastJobDataUpdate - jobData1.LastUpdate).TotalSeconds) < 1);
       for (int i = 0; i < job1.StateLog.Count; i++) {
@@ -99,9 +107,10 @@
       Assert.IsTrue(Math.Abs((jobData1.LastUpdate - jobData1Loaded.LastUpdate).TotalSeconds) < 1);
       Assert.IsTrue(jobData1.Data.SequenceEqual(jobData1Loaded.Data));
-      
-      dao.DeleteJob(job1.Id);
+
+      dao.DeleteHiveExperiment(he.Id);
 
       Assert.AreEqual(null, dao.GetJob(job1.Id));
       Assert.AreEqual(null, dao.GetJobData(job1.Id));
+      Assert.AreEqual(null, dao.GetHiveExperiment(he.Id));
     }
 
@@ -184,17 +193,15 @@
 
       DT.HiveExperiment he = new DT.HiveExperiment();
-
-      DT.Job job = new DT.Job();
-      job.State = JobState.Offline;
-      job.StateLog.Add(new DT.StateLog { State = JobState.Offline, DateTime = DateTime.Now });
-      job.Id = dao.AddJob(job);
-
-      he.RootJobId = job.Id;
       he.DateCreated = DateTime.Now;
       he.Name = "TestExperiment";
       he.OwnerUserId = Guid.NewGuid();
       he.ResourceNames = "HEAL";
-
       he.Id = dao.AddHiveExperiment(he);
+
+      DT.Job job = new DT.Job();
+      job.State = JobState.Offline;
+      job.StateLog.Add(new DT.StateLog { State = JobState.Offline, DateTime = DateTime.Now });
+      job.HiveExperimentId = he.Id;
+      job.Id = dao.AddJob(job);
 
       DT.HiveExperimentPermission perm = new DT.HiveExperimentPermission();
@@ -209,11 +216,11 @@
       Assert.AreEqual(he.Name, heLoaded.Name);
       Assert.AreEqual(he.ResourceNames, heLoaded.ResourceNames);
-      Assert.AreEqual(he.RootJobId, heLoaded.RootJobId);
       //Assert.AreEqual(he.LastAccessed, heLoaded.LastAccessed);
       //Assert.AreEqual(he.DateCreated, heLoaded.DateCreated);
 
-      DT.Job jobLoaded = dao.GetJob(he.RootJobId);
+      DT.Job jobLoaded = dao.GetJob(job.Id);
       Assert.AreEqual(job.Id, jobLoaded.Id);
       Assert.AreEqual(job.State, jobLoaded.State);
+      Assert.AreEqual(job.HiveExperimentId, jobLoaded.HiveExperimentId);
 
       DT.HiveExperimentPermission permLoaded = dao.GetHiveExperimentPermission(he.Id, perm.GrantedUserId);
@@ -225,5 +232,5 @@
       dao.DeleteHiveExperiment(he.Id);
       Assert.AreEqual(null, dao.GetHiveExperiment(he.Id));
-      Assert.AreEqual(null, dao.GetJob(he.RootJobId));
+      Assert.AreEqual(null, dao.GetJob(job.Id));
       Assert.AreEqual(null, dao.GetHiveExperimentPermission(perm.HiveExperimentId, perm.GrantedUserId));
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/HeuristicLab.Services.Hive.Tests-3.4.csproj
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/HeuristicLab.Services.Hive.Tests-3.4.csproj	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/HeuristicLab.Services.Hive.Tests-3.4.csproj	(revision 6006)
@@ -66,284 +66,4 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-2.5.0">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\ALGLIB-2.5.0.dll</HintPath>
-    </Reference>
-    <Reference Include="ALGLIB-3.1.0">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\ALGLIB-3.1.0.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.ProtocolBuffers-0.9.1">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\Google.ProtocolBuffers-0.9.1.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.ALGLIB-2.5.0">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.ALGLIB-2.5.0.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.ALGLIB-3.1.0">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.ALGLIB-3.1.0.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Algorithms.DataAnalysis-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Algorithms.DataAnalysis.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Algorithms.DataAnalysis.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Algorithms.EvolutionStrategy-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Algorithms.EvolutionStrategy-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Algorithms.GeneticAlgorithm-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Algorithms.GeneticAlgorithm-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Algorithms.LocalSearch-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Algorithms.LocalSearch-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Algorithms.SimulatedAnnealing-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Algorithms.SimulatedAnnealing-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Algorithms.TabuSearch-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Algorithms.TabuSearch-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Analysis-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Analysis-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Analysis.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Analysis.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Clients.Common-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Clients.Common-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.CodeEditor-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.CodeEditor-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Collections-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Collections-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Common-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Common-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Common.Resources-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Common.Resources-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Core-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Core-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Core.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Core.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Data-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Data-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Data.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Data.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Encodings.BinaryVectorEncoding-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Encodings.BinaryVectorEncoding-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Encodings.IntegerVectorEncoding-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Encodings.IntegerVectorEncoding-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Encodings.PermutationEncoding-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Encodings.PermutationEncoding-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Encodings.PermutationEncoding.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Encodings.PermutationEncoding.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Encodings.RealVectorEncoding-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Encodings.RealVectorEncoding-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.LibSVM-1.6.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.LibSVM-1.6.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.log4net-1.2.10.0">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.log4net-1.2.10.0.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.MainForm-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.MainForm-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Netron-3.0.2672.12446">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Netron-3.0.2672.12446.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Operators-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Operators-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Operators.Programmable-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Operators.Programmable-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Operators.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Operators.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Operators.Views.GraphVisualization-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Operators.Views.GraphVisualization-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Optimization-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Optimization-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Optimization.Operators-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Optimization.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Optimization.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Optimizer-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Optimizer-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Parameters-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Parameters-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Parameters.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Parameters.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Persistence-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Persistence-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Persistence.GUI-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Persistence.GUI-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.ArtificialAnt-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.ArtificialAnt-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.ArtificialAnt.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.ArtificialAnt.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.DataAnalysis-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.DataAnalysis.Classification-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.DataAnalysis.Classification-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.DataAnalysis.Classification.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.DataAnalysis.Classification.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.DataAnalysis.Regression-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.DataAnalysis.Regression-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.DataAnalysis.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.DataAnalysis.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.ExternalEvaluation-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.ExternalEvaluation-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.ExternalEvaluation.GP-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.ExternalEvaluation.GP-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.ExternalEvaluation.GP.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.ExternalEvaluation.GP.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.ExternalEvaluation.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.ExternalEvaluation.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.Knapsack-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.Knapsack-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.Knapsack.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.Knapsack.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.OneMax-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.OneMax-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.OneMax.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.OneMax.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.TestFunctions-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.TestFunctions-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.TestFunctions.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.TestFunctions.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.TravelingSalesman-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.TravelingSalesman-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.TravelingSalesman.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.TravelingSalesman.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.VehicleRouting-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.VehicleRouting-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.VehicleRouting.Views-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.VehicleRouting.Views-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.ProtobufCS-0.9.1">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.ProtobufCS-0.9.1.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Random-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Random-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Selection-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Selection-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.SequentialEngine-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.SequentialEngine-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.SharpDevelop-3.1.1.5327">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.SharpDevelop-3.1.1.5327.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Tracing-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Tracing-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Visualization.ChartControlsExtensions-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.WinFormsUI-2.3.1">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.WinFormsUI-2.3.1.dll</HintPath>
-    </Reference>
-    <Reference Include="ICSharpCode.NRefactory">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\ICSharpCode.NRefactory.dll</HintPath>
-    </Reference>
-    <Reference Include="ICSharpCode.SharpDevelop.Dom">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\ICSharpCode.SharpDevelop.Dom.dll</HintPath>
-    </Reference>
-    <Reference Include="ICSharpCode.SharpZipLib">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\ICSharpCode.SharpZipLib.dll</HintPath>
-    </Reference>
-    <Reference Include="ICSharpCode.TextEditor">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\ICSharpCode.TextEditor.dll</HintPath>
-    </Reference>
-    <Reference Include="LibSVM-1.6.3">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\LibSVM-1.6.3.dll</HintPath>
-    </Reference>
-    <Reference Include="log4net">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\log4net.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
-    <Reference Include="Mono.Cecil">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\Mono.Cecil.dll</HintPath>
-    </Reference>
-    <Reference Include="Netron.Diagramming.Core-3.0.2672.12446">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\Netron.Diagramming.Core-3.0.2672.12446.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Data" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="System.Drawing" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.Security" />
-    <Reference Include="System.ServiceModel" />
-    <Reference Include="System.ServiceProcess" />
-    <Reference Include="System.Web" />
-    <Reference Include="System.Web.ApplicationServices" />
-    <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="WeifenLuo.WinFormsUI.Docking-2.3.1">
-      <HintPath>C:\Program Files\HeuristicLab 3.3\WeifenLuo.WinFormsUI.Docking-2.3.1.dll</HintPath>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
     <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
       <Visible>False</Visible>
@@ -351,5 +71,4 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="PluginLoader.cs" />
     <Compile Include="ServiceTests.cs" />
     <Compile Include="Mocks\MockAuthorizationManager.cs" />
@@ -360,28 +79,45 @@
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\HeuristicLab.Clients.Hive.Slave.Tests\HeuristicLab.Clients.Hive.Slave.Tests-3.4.csproj">
-      <Project>{C4CBD11E-1B83-464A-B0AD-0DC0FF7E57AA}</Project>
-      <Name>HeuristicLab.Clients.Hive.Slave.Tests-3.4</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.Clients.Hive.Slave.Views\3.4\HeuristicLab.Clients.Hive.Slave.Views-3.4.csproj">
-      <Project>{8C0D9F39-397F-4DBE-856F-BC4DC0FE23F8}</Project>
-      <Name>HeuristicLab.Clients.Hive.Slave.Views-3.4</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.Clients.Hive.Slave\3.4\HeuristicLab.Clients.Hive.Slave-3.4.csproj">
-      <Project>{989FE92B-484E-41EE-87E2-6A24AF0381D8}</Project>
-      <Name>HeuristicLab.Clients.Hive.Slave-3.4</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.Clients.Hive.Views\3.4\HeuristicLab.Clients.Hive.Views-3.4.csproj">
-      <Project>{E1D6C801-892A-406A-B606-F158E36DD3C3}</Project>
-      <Name>HeuristicLab.Clients.Hive.Views-3.4</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.Clients.Hive\3.4\HeuristicLab.Clients.Hive-3.4.csproj">
-      <Project>{B5EF1E5A-9F3D-40B9-B4B0-30AADF2E2CEB}</Project>
-      <Name>HeuristicLab.Clients.Hive-3.4</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.Hive\3.4\HeuristicLab.Hive-3.4.csproj">
-      <Project>{F98A1740-9AC9-4D36-A582-6A2D0D06978D}</Project>
-      <Name>HeuristicLab.Hive-3.4</Name>
-    </ProjectReference>
+    <None Include="HeuristicLab 3.3.exe.config">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      <SubType>Designer</SubType>
+    </None>
+    <Shadow Include="Test References\HeuristicLab.Services.Hive-3.4.accessor" />
+  </ItemGroup>
+  <ItemGroup />
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Clients.Common-3.3">
+      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Clients.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3">
+      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Persistence-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Data.Linq" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.Transactions" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Web.ApplicationServices" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq" />
+  </ItemGroup>
+  <ItemGroup>
     <ProjectReference Include="..\HeuristicLab.Services.Hive.Common\3.4\HeuristicLab.Services.Hive.Common-3.4.csproj">
       <Project>{14424A16-48D4-445E-80BF-DDF617548BBB}</Project>
@@ -397,12 +133,4 @@
     </ProjectReference>
   </ItemGroup>
-  <ItemGroup>
-    <None Include="HeuristicLab 3.3.exe.config">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-      <SubType>Designer</SubType>
-    </None>
-    <Shadow Include="Test References\HeuristicLab.Clients.Hive.Views-3.4.accessor" />
-    <Shadow Include="Test References\HeuristicLab.Clients.Hive-3.4.accessor" />
-  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/ServiceTests.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/ServiceTests.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/ServiceTests.cs	(revision 6006)
@@ -37,5 +37,4 @@
     [ClassInitialize]
     public static void MyClassInitialize(TestContext testContext) {
-      PluginLoader.pluginAssemblies.Any();
       ServiceLocator.Instance = new MockServiceLocator(ServiceLocator.Instance);
     }
@@ -100,11 +99,11 @@
       service.AddSlave(slave);
 
-      // add job
-      job.Id = service.AddJob(job, jobData, new List<Guid> { slave.Id });
-      experiment.RootJobId = job.Id;
-
       // add hive experiment
       experiment.Id = service.AddHiveExperiment(experiment);
 
+      // add job
+      job.HiveExperimentId = experiment.Id;
+      job.Id = service.AddJob(job, jobData, new List<Guid> { slave.Id });
+      
       // test job
       DT.Job jobLoaded = service.GetJob(job.Id);
@@ -115,4 +114,5 @@
       Assert.AreEqual(JobState.Waiting, jobLoaded.State);
       Assert.IsTrue(job.PluginsNeededIds.SequenceEqual(jobLoaded.PluginsNeededIds));
+      Assert.AreEqual(job.HiveExperimentId, jobLoaded.HiveExperimentId);
 
       DT.JobData jobDataLoaded = service.GetJobData(job.Id);
@@ -125,5 +125,4 @@
       Assert.AreEqual(experiment.Name, experimentLoaded.Name);
       Assert.AreEqual(experiment.Description, experimentLoaded.Description);
-      Assert.AreEqual(experiment.RootJobId, experimentLoaded.RootJobId);
 
       // test assigned ressources
@@ -167,6 +166,5 @@
 
     List<DT.Job> jobs = new List<DT.Job>();
-
-
+    
     [TestMethod]
     public void TestParentJobs() {
@@ -216,18 +214,20 @@
       service.AddSlave(slave);
 
+      // add hive experiment
+      experiment.Id = service.AddHiveExperiment(experiment);
+
       // add parent job
+      parentJob.HiveExperimentId = experiment.Id;
       parentJob.Id = service.AddJob(parentJob, parentJobData, new List<Guid> { slave.Id });
-      experiment.RootJobId = parentJob.Id;
 
       // add child job
+      childJob.HiveExperimentId = experiment.Id;
       childJob.Id = service.AddChildJob(parentJob.Id, childJob, childJobData);
       childJob.ParentJobId = parentJob.Id;
-
-      // add hive experiment
-      experiment.Id = service.AddHiveExperiment(experiment);
 
       // test child job
       var childJobLoaded = service.GetJob(childJob.Id);
       Assert.AreEqual(childJob.ParentJobId, childJobLoaded.ParentJobId);
+      Assert.AreEqual(childJob.HiveExperimentId, childJobLoaded.HiveExperimentId);
       Assert.AreEqual(JobState.Waiting, childJobLoaded.State);
       Assert.AreEqual(false, childJobLoaded.FinishWhenChildJobsFinished);
@@ -236,4 +236,5 @@
       // test parent job
       var parentJobLoaded = service.GetJob(parentJob.Id);
+      Assert.AreEqual(parentJob.HiveExperimentId, parentJobLoaded.HiveExperimentId);
       Assert.AreEqual(JobState.Waiting, parentJobLoaded.State);
       Assert.AreEqual(true, parentJobLoaded.FinishWhenChildJobsFinished);
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/Test References/HeuristicLab.Services.Hive-3.4.accessor
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/Test References/HeuristicLab.Services.Hive-3.4.accessor	(revision 6006)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/Test References/HeuristicLab.Services.Hive-3.4.accessor	(revision 6006)
@@ -0,0 +1,2 @@
+HeuristicLab.Services.Hive-3.4.dll
+Desktop
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/HiveService.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/HiveService.cs	(revision 6004)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/HiveService.cs	(revision 6006)
@@ -2,5 +2,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using System.Security.Permissions;
 using System.ServiceModel;
 using HeuristicLab.Services.Hive.Common;
@@ -33,6 +32,6 @@
 
     #region Job Methods
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public Guid AddJob(Job job, JobData jobData, IEnumerable<Guid> resourceIds) {
       return trans.UseTransaction(() => {
@@ -53,6 +52,6 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public Guid AddChildJob(Guid parentJobId, Job job, JobData jobData) {
       return trans.UseTransaction(() => {
@@ -62,39 +61,45 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public Job GetJob(Guid jobId) {
       return dao.GetJob(jobId);
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public IEnumerable<Job> GetJobs() {
       return dao.GetJobs(x => true);
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public IEnumerable<LightweightJob> GetLightweightJobs(IEnumerable<Guid> jobIds) {
       return dao.GetJobs(x => jobIds.Contains(x.JobId)).Select(x => new LightweightJob(x)).ToArray();
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public IEnumerable<LightweightJob> GetLightweightChildJobs(Guid? parentJobId, bool recursive, bool includeParent) {
       return GetChildJobs(parentJobId, recursive, includeParent).Select(x => new LightweightJob(x)).ToArray();
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    public IEnumerable<LightweightJob> GetLightweightExperimentJobs(Guid experimentId) {
+      return dao.GetJobs(x => x.HiveExperimentId == experimentId).Select(x => new LightweightJob(x)).ToArray();
+    }
+
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public JobData GetJobData(Guid jobId) {
       return dao.GetJobData(jobId);
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public void UpdateJob(Job job) {
       trans.UseTransaction(() => {
@@ -103,7 +108,7 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public void UpdateJobData(Job job, JobData jobData) {
       trans.UseTransaction(() => {
@@ -114,7 +119,7 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public void DeleteJob(Guid jobId) {
       trans.UseTransaction(() => {
@@ -123,7 +128,7 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public void DeleteChildJobs(Guid parentJobId) {
       trans.UseTransaction(() => {
@@ -136,7 +141,7 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public Job UpdateJobState(Guid jobId, JobState jobState, Guid? slaveId, Guid? userId, string exception) {
       return trans.UseTransaction(() => {
@@ -156,7 +161,7 @@
 
     #region Job Control Methods
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public void StopJob(Guid jobId) {
       trans.UseTransaction(() => {
@@ -168,7 +173,7 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public void PauseJob(Guid jobId) {
       trans.UseTransaction(() => {
@@ -180,7 +185,7 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public void RestartJob(Guid jobId) {
       trans.UseTransaction(() => {
@@ -193,6 +198,6 @@
 
     #region HiveExperiment Methods
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public HiveExperiment GetHiveExperiment(Guid id) {
       return dao.GetHiveExperiments(x =>
@@ -202,17 +207,17 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public IEnumerable<HiveExperiment> GetHiveExperiments() {
       return dao.GetHiveExperiments(x => x.OwnerUserId == auth.UserId || x.HiveExperimentPermissions.Count(hep => hep.Permission != Permission.NotAllowed && hep.GrantedUserId == auth.UserId) > 0);
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]    
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]    
     public IEnumerable<HiveExperiment> GetAllHiveExperiments() {
       return dao.GetHiveExperiments(x => true);
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public Guid AddHiveExperiment(HiveExperiment hiveExperimentDto) {
       return trans.UseTransaction(() => {
@@ -223,6 +228,6 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public void UpdateHiveExperiment(HiveExperiment hiveExperimentDto) {
       trans.UseTransaction(() => {
@@ -231,6 +236,6 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public void DeleteHiveExperiment(Guid hiveExperimentId) {
       trans.UseTransaction(() => {
@@ -242,5 +247,5 @@
 
     #region Login Methods
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public void Hello(Slave slaveInfo) {
       trans.UseTransaction(() => {
@@ -275,5 +280,5 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public void GoodBye(Guid slaveId) {
       trans.UseTransaction(() => {
@@ -288,5 +293,5 @@
 
     #region Heartbeat Methods
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public List<MessageContainer> Heartbeat(Heartbeat heartbeat) {
       TriggerLifecycle(false);
@@ -296,6 +301,6 @@
 
     #region Plugin Methods
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public Guid AddPlugin(Plugin plugin, List<PluginData> pluginDatas) {
       return trans.UseTransaction(() => {
@@ -318,21 +323,21 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public Plugin GetPlugin(Guid pluginId) {
       return dao.GetPlugin(pluginId);
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public IEnumerable<Plugin> GetPlugins() {
       return dao.GetPlugins(x => x.IsLocal == false);
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Slave)]
     public IEnumerable<PluginData> GetPluginDatas(List<Guid> pluginIds) {
       List<PluginData> pluginDatas = new List<PluginData>();
@@ -354,18 +359,18 @@
 
     #region Slave Methods
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public Guid AddSlave(Slave slave) {
       return trans.UseTransaction(() => dao.AddSlave(slave));
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public Guid AddSlaveGroup(SlaveGroup slaveGroup) {
       return trans.UseTransaction(() => dao.AddSlaveGroup(slaveGroup));
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public Slave GetSlave(Guid slaveId) {
       return dao.GetSlave(slaveId);
@@ -376,18 +381,18 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public IEnumerable<Slave> GetSlaves() {
       return dao.GetSlaves(x => true);
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public IEnumerable<SlaveGroup> GetSlaveGroups() {
       return dao.GetSlaveGroups(x => true);
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public void UpdateSlave(Slave slave) {
       trans.UseTransaction(() => {
@@ -396,6 +401,6 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public void UpdateSlaveGroup(SlaveGroup slaveGroup) {
       trans.UseTransaction(() => {
@@ -404,6 +409,6 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public void DeleteSlave(Guid slaveId) {
       trans.UseTransaction(() => {
@@ -412,6 +417,6 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public void DeleteSlaveGroup(Guid slaveGroupId) {
       trans.UseTransaction(() => {
@@ -420,6 +425,6 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
       trans.UseTransaction(() => {
@@ -430,6 +435,6 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
       trans.UseTransaction(() => {
@@ -440,6 +445,6 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
     public Guid GetResourceId(string resourceName) {
       return trans.UseTransaction(() => {
@@ -485,10 +490,10 @@
     #region Appointment Methods
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
     public Guid AddAppointment(Appointment appointment) {
       return trans.UseTransaction(() => dao.AddAppointment(appointment));
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
     public void DeleteAppointment(Guid appointmentId) {
       trans.UseTransaction(() => {
@@ -497,5 +502,5 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
     public void UpdateAppointment(Appointment appointment) {
       trans.UseTransaction(() => {
@@ -504,5 +509,5 @@
     }
 
-    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    // [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
     public IEnumerable<Appointment> GetScheduleForResource(Guid resourceId) {
       return trans.UseTransaction(() => dao.GetAppointments(x => x.ResourceId == resourceId));
