Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive.Slave.Views/3.3/HeuristicLab.Clients.Hive.Slave.Views-3.3.csproj
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive.Slave.Views/3.3/HeuristicLab.Clients.Hive.Slave.Views-3.3.csproj	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive.Slave.Views/3.3/HeuristicLab.Clients.Hive.Slave.Views-3.3.csproj	(revision 4629)
@@ -31,4 +31,10 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="HeuristicLab.Common-3.3">
@@ -56,4 +62,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive.Slave/3.3/HeuristicLab.Clients.Hive.Slave-3.3.csproj
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive.Slave/3.3/HeuristicLab.Clients.Hive.Slave-3.3.csproj	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive.Slave/3.3/HeuristicLab.Clients.Hive.Slave-3.3.csproj	(revision 4629)
@@ -31,4 +31,10 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="HeuristicLab.Common-3.3">
@@ -55,4 +61,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive.Views/3.3/HeuristicLab.Clients.Hive.Views-3.3.csproj
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive.Views/3.3/HeuristicLab.Clients.Hive.Views-3.3.csproj	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive.Views/3.3/HeuristicLab.Clients.Hive.Views-3.3.csproj	(revision 4629)
@@ -31,4 +31,10 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="HeuristicLab.Common-3.3">
@@ -55,4 +61,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Exceptions/AddJobToHiveException.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Exceptions/AddJobToHiveException.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Exceptions/AddJobToHiveException.cs	(revision 4629)
@@ -0,0 +1,28 @@
+﻿#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;
+
+namespace HeuristicLab.Clients.Hive {
+  class AddJobToHiveException : Exception {
+    public AddJobToHiveException(string message) : base(message) { }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Exceptions/JobResultPollingException.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Exceptions/JobResultPollingException.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Exceptions/JobResultPollingException.cs	(revision 4629)
@@ -0,0 +1,28 @@
+﻿#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;
+
+namespace HeuristicLab.Clients.Hive {
+  class JobResultPollingException : Exception {
+    public JobResultPollingException(string message) : base(message) { }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Exceptions/OptimizerNotFoundException.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Exceptions/OptimizerNotFoundException.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Exceptions/OptimizerNotFoundException.cs	(revision 4629)
@@ -0,0 +1,30 @@
+﻿#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;
+
+namespace HeuristicLab.Clients.Hive {
+  class OptimizerNotFoundException : Exception {
+
+    public OptimizerNotFoundException(string message) : base(message) {
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HeuristicLab.Clients.Hive-3.3.csproj
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HeuristicLab.Clients.Hive-3.3.csproj	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HeuristicLab.Clients.Hive-3.3.csproj	(revision 4629)
@@ -31,10 +31,27 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
   <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.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <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, Version=3.2.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Data-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Optimization-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Persistence-3.3">
@@ -44,6 +61,10 @@
       <HintPath>..\..\..\..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
     </Reference>
+    <Reference Include="HeuristicLab.Tracing-3.3, Version=3.2.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.ServiceModel" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
@@ -52,6 +73,50 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Exceptions\AddJobToHiveException.cs" />
+    <Compile Include="Exceptions\JobResultPollingException.cs" />
+    <Compile Include="Exceptions\OptimizerNotFoundException.cs" />
+    <Compile Include="HiveExperiment\HiveExperimentList.cs" />
+    <Compile Include="HiveExperiment\HiveJobList.cs" />
+    <Compile Include="Jobs\JobList.cs" />
+    <Compile Include="Jobs\OptimizerJob.cs" />
     <Compile Include="HeuristicLabClientsHivePlugin.cs" />
+    <Compile Include="HiveExperiment\HiveClient.cs" />
+    <Compile Include="HiveExperiment\HiveJob.cs" />
+    <Compile Include="HiveExperiment\HiveExperiment.cs" />
+    <Compile Include="HiveExperiment\JobResultPoller.cs" />
+    <Compile Include="Progress\IProgress.cs" />
+    <Compile Include="Progress\IProgressReporter.cs" />
+    <Compile Include="Progress\Progress.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="PersistenceUtil.cs" />
+    <Compile Include="ServiceClients\ServiceClientFactory.cs" />
+    <Compile Include="ServiceClients\ServiceClientFactoryException.cs" />
+    <Compile Include="ServiceLocator.cs" />
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+      <DependentUpon>Settings.settings</DependentUpon>
+    </Compile>
+    <None Include="app.config" />
+    <None Include="HeuristicLab.snk" />
+    <None Include="ServiceClients\GenerateServiceClients.cmd" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Administration\" />
+    <Folder Include="Slave\" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Hive\3.3\HeuristicLab.Hive-3.3.csproj">
+      <Project>{F98A1740-9AC9-4D36-A582-6A2D0D06978D}</Project>
+      <Name>HeuristicLab.Hive-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Services.Hive.Common\3.3\HeuristicLab.Services.Hive.Common-3.3.csproj">
+      <Project>{14424A16-48D4-445E-80BF-DDF617548BBB}</Project>
+      <Name>HeuristicLab.Services.Hive.Common-3.3</Name>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveClient.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveClient.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveClient.cs	(revision 4629)
@@ -0,0 +1,169 @@
+﻿#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.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Core;
+using HeuristicLab.Services.Hive.Common.ServiceContracts;
+using HeuristicLab.Services.Hive.Common;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Clients.Hive {
+  using DT = HeuristicLab.Services.Hive.Common.DataTransfer;
+  using HeuristicLab.Common;
+
+  [Item("Hive Client", "Connects to Hive and lists all submitted experiments by the current user.")]
+  [Creatable("Hive")]
+  public class HiveClient : Item, IProgressReporter {
+    private static object locker = new object();
+    private bool currentlyUpdating;
+
+    private ILog log;
+    public ILog Log {
+      get { return log; }
+    }
+
+    private HiveExperimentList hiveExperiments;
+    public HiveExperimentList HiveExperiments {
+      get { return hiveExperiments; }
+      set {
+        if (hiveExperiments != value) {
+          DeRegisterHiveExperimentsEvents();
+          hiveExperiments = value;
+          RegisterHiveExperimentsEvent();
+          OnHiveExperimentsChanged();
+        }
+      }
+    }
+
+    private bool isProgressing;
+    public bool IsProgressing {
+      get { return isProgressing; }
+      set {
+        if (isProgressing != value) {
+          isProgressing = value;
+          OnIsProgressingChanged();
+        }
+      }
+    }
+
+    private IProgress progress;
+    public IProgress Progress {
+      get { return progress; }
+    }
+
+    private void RegisterHiveExperimentsEvent() {
+      if (hiveExperiments != null) {
+        hiveExperiments.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveExperiment>>(hiveExperiments_ItemsRemoved);
+      }
+    }
+
+    private void DeRegisterHiveExperimentsEvents() {
+      if (hiveExperiments != null) {
+        hiveExperiments.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveExperiment>>(hiveExperiments_ItemsRemoved);
+      }
+    }
+
+    public HiveClient() {
+      this.log = new Log();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      HiveClient clone = (HiveClient)base.Clone(cloner);
+      clone.log = (ILog)cloner.Clone(this.log);
+      clone.hiveExperiments = (HiveExperimentList)cloner.Clone(this.hiveExperiments);
+      return clone;
+    }
+
+    public void UpdateExperimentList() {
+      this.progress = new Progress("Downloading HiveExperiments...");
+      try {
+        IsProgressing = true;
+        if (this.HiveExperiments == null) {
+          this.HiveExperiments = new HiveExperimentList();
+        }
+        using (var service = ServiceLocator.Instance.ServicePool.GetService()) {
+          currentlyUpdating = true;
+          IEnumerable<DT.HiveExperiment> response = service.Obj.GetHiveExperiments();
+          progress.Status = "Populating HiveExperiment list...";
+          RefreshExperimentList(response);
+          currentlyUpdating = false;
+        }
+      }
+      catch (Exception) {
+        this.HiveExperiments = null;
+        throw;
+      }
+      finally {
+        IsProgressing = false;
+      }
+    }
+
+    private void RefreshExperimentList(IEnumerable<DT.HiveExperiment> hiveExperiments) {
+      foreach (DT.HiveExperiment hiveExperimentDto in hiveExperiments) {
+        DT.HiveExperiment hiveExperiment = GetHiveExperiment(hiveExperimentDto.Id);
+        if (hiveExperiment == null) {
+          // not yet there, create new
+          this.HiveExperiments.Add(new HiveExperiment(hiveExperimentDto));
+        } else {
+          // update
+          hiveExperiment.UpdateFromDto(hiveExperimentDto);
+        }
+      }
+    }
+
+    private DT.HiveExperiment GetHiveExperiment(Guid hiveExperimentId) {
+      return this.HiveExperiments.SingleOrDefault(he => he.Id.Equals(hiveExperimentId));
+    }
+
+    private void LogMessage(string message) {
+      // HeuristicLab.Log is not Thread-Safe, so lock on every call
+      lock (locker) {
+        log.LogMessage(message);
+      }
+    }
+
+    public event EventHandler HiveExperimentsChanged;
+    private void OnHiveExperimentsChanged() {
+      var handler = HiveExperimentsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    
+    void hiveExperiments_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<Collections.IndexedItem<HiveExperiment>> e) {
+      if (!currentlyUpdating) {
+        using (Disposable<IHiveService> service = ServiceLocator.Instance.ServicePool.GetService()) {
+          foreach (IndexedItem<HiveExperiment> item in e.Items) {
+            if (item.Value.HiveExperimentId != Guid.Empty) {
+              service.Obj.DeleteHiveExperiment(item.Value.HiveExperimentId);
+            }
+          }
+        }
+      }
+    }
+
+    public event EventHandler IsProgressingChanged;
+    private void OnIsProgressingChanged() {
+      var handler = IsProgressingChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveExperiment.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveExperiment.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveExperiment.cs	(revision 4629)
@@ -0,0 +1,609 @@
+﻿#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.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Tracing;
+using HeuristicLab.Services.Hive.Common;
+using HeuristicLab.Services.Hive.Common.ServiceContracts;
+
+namespace HeuristicLab.Clients.Hive {
+  using DT = HeuristicLab.Services.Hive.Common.DataTransfer;
+  using HeuristicLab.Services.Hive.Common.DataTransfer;
+  using HeuristicLab.Clients.Hive.Jobs;
+
+  /// <summary>
+  /// An experiment which contains multiple batch runs of algorithms.
+  /// </summary>
+  [Item(itemName, itemDescription)]
+  public class HiveExperiment : NamedItem, IExecutable, IProgressReporter {
+    private object locker = new object();
+    private const string itemName = "Hive Experiment";
+    private const string itemDescription = "A runner for a single experiment, which's algorithms are executed in the Hive.";
+    private System.Timers.Timer timer;
+
+    private Guid hiveExperimentId;
+    public Guid HiveExperimentId {
+      get { return hiveExperimentId; }
+      set { hiveExperimentId = value; }
+    }
+
+    private HiveJob hiveJob;
+    public HiveJob HiveJob {
+      get { return hiveJob; }
+      set {
+        DeregisterHiveJobEvents();
+        if (hiveJob != value) {
+          hiveJob = value;
+          RegisterHiveJobEvents();
+          OnHiveJobChanged();
+        }
+      }
+    }
+
+    private ILog log;
+    public ILog Log {
+      get { return log; }
+    }
+
+    private DateTime lastUpdateTime;
+
+    private string resourceIds;
+    public string ResourceIds {
+      get { return resourceIds; }
+      set {
+        if (resourceIds != value) {
+          resourceIds = value;
+          OnResourceIdsChanged();
+        }
+      }
+    }
+
+    private Guid? rootJobId;
+
+    private bool isPollingResults;
+    public bool IsPollingResults {
+      get { return isPollingResults; }
+      private set {
+        if (isPollingResults != value) {
+          isPollingResults = value;
+          OnIsPollingResultsChanged();
+        }
+      }
+    }
+
+    private bool isProgressing;
+    public bool IsProgressing {
+      get { return isProgressing; }
+      set {
+        if (isProgressing != value) {
+          isProgressing = value;
+          OnIsProgressingChanged();
+        }
+      }
+    }
+
+    private IProgress progress;
+    public IProgress Progress {
+      get { return progress; }
+    }
+
+    private JobResultPoller jobResultPoller;
+
+    public HiveExperiment()
+      : base(itemName, itemDescription) {
+      //this.ResourceIds = HeuristicLab.Hive.Experiment.Properties.Settings.Default.ResourceIds;
+      this.ResourceIds = "MyGroup";
+      this.log = new Log();
+      InitTimer();
+    }
+
+    public HiveExperiment(DT.HiveExperiment hiveExperimentDto)
+      : this() {
+      UpdateFromDto(hiveExperimentDto);
+    }
+
+    public void UpdateFromDto(DT.HiveExperiment hiveExperimentDto) {
+      this.HiveExperimentId = hiveExperimentDto.Id;
+      this.Name = hiveExperimentDto.Name;
+      this.Description = hiveExperimentDto.Description;
+      this.ResourceIds = hiveExperimentDto.ResourceIds;
+      this.rootJobId = hiveExperimentDto.RootJobId;
+    }
+
+    public DT.HiveExperiment ToHiveExperimentDto() {
+      return new DT.HiveExperiment() {
+        Id = this.HiveExperimentId,
+        Name = this.Name,
+        Description = this.Description,
+        ResourceIds = this.ResourceIds,
+        RootJobId = this.rootJobId
+      };
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      LogMessage("I am beeing cloned");
+      HiveExperiment clone = (HiveExperiment)base.Clone(cloner);
+      clone.resourceIds = this.resourceIds;
+      clone.executionState = this.executionState;
+      clone.executionTime = this.executionTime;
+      clone.log = (ILog)cloner.Clone(log);
+      clone.lastUpdateTime = this.lastUpdateTime;
+      clone.rootJobId = this.rootJobId;
+      return clone;
+    }
+
+    public void SetExperiment(Optimization.Experiment experiment) {
+      this.HiveJob = new HiveJob(experiment);
+      Prepare();
+    }
+
+    private void RegisterHiveJobEvents() {
+      if (HiveJob != null) {
+        HiveJob.JobStateChanged += new EventHandler(HiveJob_JobStateChanged);
+      }
+    }
+
+    private void DeregisterHiveJobEvents() {
+      if (HiveJob != null) {
+        HiveJob.JobStateChanged -= new EventHandler(HiveJob_JobStateChanged);
+      }
+    }
+
+    /// <summary>
+    /// Returns the experiment from the root HiveJob
+    /// </summary>
+    public Optimization.Experiment GetExperiment() {
+      if (this.HiveJob != null) {
+        return HiveJob.OptimizerJob.OptimizerAsExperiment;
+      }
+      return null;
+    }
+
+    #region IExecutable Members
+    private Core.ExecutionState executionState;
+    public ExecutionState ExecutionState {
+      get { return executionState; }
+      private set {
+        if (executionState != value) {
+          executionState = value;
+          OnExecutionStateChanged();
+        }
+      }
+    }
+
+    private TimeSpan executionTime;
+    public TimeSpan ExecutionTime {
+      get { return executionTime; }
+      private set {
+        if (executionTime != value) {
+          executionTime = value;
+          OnExecutionTimeChanged();
+        }
+      }
+    }
+
+    public void Pause() {
+      throw new NotSupportedException();
+    }
+
+    public void Prepare() {
+      // do nothing
+    }
+
+    public void Start() {
+      OnStarted();
+      ExecutionTime = new TimeSpan();
+      lastUpdateTime = DateTime.Now;
+      this.ExecutionState = Core.ExecutionState.Started;
+
+      Thread t = new Thread(RunUploadExperiment);
+      t.Name = "RunUploadExperimentThread";
+      t.Start();
+    }
+
+    private void RunUploadExperiment() {
+      try {
+        this.progress = new Progress("Connecting to server...");
+        IsProgressing = true;
+        using (Disposable<IHiveService> service = ServiceLocator.Instance.ServicePool.GetService()) {
+          IEnumerable<string> groups = ToResourceIdList(this.ResourceIds);
+          this.HiveJob.SetIndexInParentOptimizerList(null);
+
+          int totalJobCount = this.HiveJob.GetAllHiveJobs().Count();
+          int jobCount = 0;
+
+          this.progress.Status = "Uploading jobs...";
+          UploadJobWithChildren(service.Obj, this.HiveJob, null, groups, ref jobCount, totalJobCount);
+          this.rootJobId = this.HiveJob.Job.Id;
+          LogMessage("Finished sending jobs to hive");
+
+          // insert or update HiveExperiment
+          this.progress.Status = "Uploading HiveExperiment...";
+
+          DT.HiveExperiment he = service.Obj.GetHiveExperiment(service.Obj.AddHiveExperiment(this.ToHiveExperimentDto()));
+          this.UpdateFromDto(he);
+
+          StartResultPolling();
+        }
+      }
+      catch (Exception e) {
+        OnExceptionOccured(e);
+      }
+      finally {
+        IsProgressing = false;
+      }
+    }
+
+    /// <summary>
+    /// Uploads the given job and all its child-jobs while setting the proper parentJobId values for the childs
+    /// 
+    /// </summary>
+    /// <param name="service"></param>
+    /// <param name="hiveJob"></param>
+    /// <param name="parentHiveJob">shall be null if its the root job</param>
+    /// <param name="groups"></param>
+    private void UploadJobWithChildren(IHiveService service, HiveJob hiveJob, HiveJob parentHiveJob, IEnumerable<string> groups, ref int jobCount, int totalJobCount) {
+      jobCount++;
+      this.progress.Status = string.Format("Serializing job {0} of {1}", jobCount, totalJobCount);
+      JobData serializedJob;
+      if (hiveJob.OptimizerJob.ComputeInParallel &&
+        (hiveJob.OptimizerJob.Optimizer is Optimization.Experiment || hiveJob.OptimizerJob.Optimizer is Optimization.BatchRun)) {
+        hiveJob.Job.State = JobState.WaitForChildJobs;
+        hiveJob.OptimizerJob.CollectChildJobs = false; // don't collect child-jobs on slaves
+        serializedJob = hiveJob.GetAsSerializedJob(true);
+      } else {
+        serializedJob = hiveJob.GetAsSerializedJob(false);
+      }
+
+      this.progress.Status = string.Format("Uploading job {0} of {1} ({2} kb)", jobCount, totalJobCount, serializedJob.Data.Count() / 1024);
+      this.progress.ProgressValue = (double)jobCount / totalJobCount;
+      Job response;
+      if (parentHiveJob != null) {
+        response = service.AddChildJob(parentHiveJob.Job.Id, serializedJob);
+      } else {
+        response = service.AddJobWithGroupStrings(serializedJob, groups);
+      }
+
+      if (response != null) {
+        LogMessage(response.Id, "Job sent to Hive");
+        hiveJob.Job = response;
+
+        foreach (HiveJob child in hiveJob.ChildHiveJobs) {
+          UploadJobWithChildren(service, child, hiveJob, groups, ref jobCount, totalJobCount);
+        }
+      } else {
+        throw new AddJobToHiveException("Could not add job");
+      }
+    }
+
+    /// <summary>
+    /// Converts a string which can contain Ids separated by ';' to a enumerable
+    /// </summary>
+    private IEnumerable<string> ToResourceIdList(string resourceGroups) {
+      if (!string.IsNullOrEmpty(resourceGroups)) {
+        return resourceIds.Split(';');
+      } else {
+        return new List<string>();
+      }
+    }
+
+    public void Stop() {
+      using (Disposable<IHiveService> service = ServiceLocator.Instance.ServicePool.GetService()) {
+        foreach (HiveJob hj in HiveJob.GetAllHiveJobs()) {
+          service.Obj.AbortJob(hj.Job.Id);
+        }
+      }
+    }
+
+    #endregion
+
+    public void StartResultPolling() {
+      if (!jobResultPoller.IsPolling) {
+        jobResultPoller.Start();
+      } else {
+        throw new JobResultPollingException("Result polling already running");
+      }
+    }
+
+    public void StopResultPolling() {
+      if (jobResultPoller.IsPolling) {
+        jobResultPoller.Stop();
+      } else {
+        throw new JobResultPollingException("Result polling not running");
+      }
+    }
+
+    #region HiveJob Events
+    void HiveJob_JobStateChanged(object sender, EventArgs e) {
+      if (HiveJob != null) {
+        rootJobId = HiveJob.Job.Id;
+      }
+    }
+    #endregion
+
+    #region Eventhandler
+
+    public event EventHandler ExecutionTimeChanged;
+    private void OnExecutionTimeChanged() {
+      EventHandler handler = ExecutionTimeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler ExecutionStateChanged;
+    private void OnExecutionStateChanged() {
+      LogMessage("ExecutionState changed to " + executionState.ToString());
+      EventHandler handler = ExecutionStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Started;
+    private void OnStarted() {
+      LogMessage("Started");
+      timer.Start();
+      EventHandler handler = Started;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Stopped;
+    private void OnStopped() {
+      LogMessage("Stopped");
+      timer.Stop();
+      EventHandler handler = Stopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Paused;
+    private void OnPaused() {
+      LogMessage("Paused");
+      EventHandler handler = Paused;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Prepared;
+    protected virtual void OnPrepared() {
+      LogMessage("Prepared");
+      EventHandler handler = Prepared;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler ResourceIdsChanged;
+    protected virtual void OnResourceIdsChanged() {
+      EventHandler handler = ResourceIdsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler IsResultsPollingChanged;
+    private void OnIsPollingResultsChanged() {
+      if (this.IsPollingResults) {
+        LogMessage("Results Polling Started");
+      } else {
+        LogMessage("Results Polling Stopped");
+      }
+      EventHandler handler = IsResultsPollingChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+    private void OnExceptionOccured(Exception e) {
+      var handler = ExceptionOccurred;
+      if (handler != null) handler(this, new EventArgs<Exception>(e));
+    }
+
+    public event EventHandler HiveJobChanged;
+    private void OnHiveJobChanged() {
+      if (jobResultPoller != null && jobResultPoller.IsPolling) {
+        jobResultPoller.Stop();
+        DeregisterResultPollingEvents();
+      }
+      if (HiveJob != null) {
+        jobResultPoller = new JobResultPoller(HiveJob, ApplicationConstants.RESULT_POLLING_INTERVAL);
+        RegisterResultPollingEvents();
+      }
+      EventHandler handler = HiveJobChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler IsProgressingChanged;
+    private void OnIsProgressingChanged() {
+      var handler = IsProgressingChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    #region JobResultPoller Events
+    private void RegisterResultPollingEvents() {
+      jobResultPoller.ExceptionOccured += new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
+      jobResultPoller.JobResultsReceived += new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
+      jobResultPoller.PollingStarted += new EventHandler(jobResultPoller_PollingStarted);
+      jobResultPoller.PollingFinished += new EventHandler(jobResultPoller_PollingFinished);
+      jobResultPoller.IsPollingChanged += new EventHandler(jobResultPoller_IsPollingChanged);
+    }
+    private void DeregisterResultPollingEvents() {
+      jobResultPoller.ExceptionOccured -= new EventHandler<EventArgs<Exception>>(jobResultPoller_ExceptionOccured);
+      jobResultPoller.JobResultsReceived -= new EventHandler<EventArgs<IEnumerable<LightweightJob>>>(jobResultPoller_JobResultReceived);
+      jobResultPoller.PollingStarted -= new EventHandler(jobResultPoller_PollingStarted);
+      jobResultPoller.PollingFinished -= new EventHandler(jobResultPoller_PollingFinished);
+      jobResultPoller.IsPollingChanged -= new EventHandler(jobResultPoller_IsPollingChanged);
+    }
+    void jobResultPoller_IsPollingChanged(object sender, EventArgs e) {
+      this.IsPollingResults = jobResultPoller.IsPolling;
+    }
+    void jobResultPoller_PollingFinished(object sender, EventArgs e) {
+      LogMessage("Polling results finished");
+    }
+    void jobResultPoller_PollingStarted(object sender, EventArgs e) {
+      LogMessage("Polling results started");
+    }
+    void jobResultPoller_JobResultReceived(object sender, EventArgs<IEnumerable<LightweightJob>> e) {
+      foreach (LightweightJob lightweightJob in e.Value) {
+        HiveJob hj = hiveJob.GetHiveJobByJobId(lightweightJob.Id);
+        if (hj != null) {
+          hj.UpdateFromLightweightJob(lightweightJob);
+          if ((hj.Job.State == JobState.Aborted ||
+               hj.Job.State == JobState.Failed ||
+               hj.Job.State == JobState.Finished) &&
+              !hj.IsFinishedOptimizerDownloaded) {
+            LogMessage(hj.Job.Id, "Downloading optimizer for job");
+            OptimizerJob optimizerJob = LoadOptimizerJob(hj.Job.Id);
+            if (lightweightJob.ParentJobId.HasValue) {
+              HiveJob parentHiveJob = HiveJob.GetHiveJobByJobId(lightweightJob.ParentJobId.Value);
+              parentHiveJob.UpdateChildOptimizer(optimizerJob, hj.Job.Id);
+            } else {
+              this.HiveJob.IsFinishedOptimizerDownloaded = true;
+            }
+          }
+        }
+      }
+      GC.Collect(); // force GC, because .NET is too lazy here (deserialization takes a lot of memory)
+      if (AllJobsFinished()) {
+        this.ExecutionState = Core.ExecutionState.Stopped;
+        StopResultPolling();
+        OnStopped();
+      }
+    }
+
+    private bool AllJobsFinished() {
+      return HiveJob.GetAllHiveJobs().All(hj => hj.IsFinishedOptimizerDownloaded);
+    }
+
+    void jobResultPoller_ExceptionOccured(object sender, EventArgs<Exception> e) {
+      OnExceptionOccured(e.Value);
+    }
+    #endregion
+
+    #region Execution Time Timer
+    private void InitTimer() {
+      timer = new System.Timers.Timer(100);
+      timer.AutoReset = true;
+      timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
+    }
+
+    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
+      DateTime now = DateTime.Now;
+      ExecutionTime += now - lastUpdateTime;
+      lastUpdateTime = now;
+    }
+    #endregion
+
+    #region Logging
+    private void LogMessage(string message) {
+      // HeuristicLab.Log is not Thread-Safe, so lock on every call
+      lock (locker) {
+        log.LogMessage(message);
+        Logger.Debug(message);
+      }
+    }
+
+    private void LogMessage(Guid jobId, string message) {
+      //GetJobItemById(jobId).LogMessage(message);
+      LogMessage(message + " (jobId: " + jobId + ")");
+    }
+
+    #endregion
+
+    /// <summary>
+    /// Downloads the root job from hive and sets the experiment, rootJob and rootJobItem
+    /// </summary>
+    public void LoadHiveJob() {
+      progress = new Progress();
+      try {
+        IsProgressing = true;
+        int totalJobCount = 0;
+        int jobCount = 0;
+        progress.Status = "Connecting to Server...";
+        using (var service = ServiceLocator.Instance.ServicePool.GetService()) {
+          // fetch all Job objects to create the full tree of tree of HiveJob objects
+          progress.Status = "Downloading list of jobs...";
+          IEnumerable<LightweightJob> allResults = service.Obj.GetLightweightChildJobs(rootJobId.Value, true, true);
+          totalJobCount = allResults.Count();
+
+          // download them first
+          IDictionary<Guid, JobData> allSerializedJobs = new Dictionary<Guid, JobData>();
+          foreach (LightweightJob lightweightJob in allResults) {
+            jobCount++;
+            progress.Status = string.Format("Downloading {0} of {1} jobs...", jobCount, totalJobCount);
+            allSerializedJobs.Add(lightweightJob.Id, service.Obj.GetJobData(lightweightJob.Id));
+            progress.ProgressValue = (double)jobCount / totalJobCount;
+          }
+
+          jobCount = 1;
+          progress.Status = string.Format("Deserializing {0} of {1} jobs... ({2} kb)", jobCount, totalJobCount, allSerializedJobs[this.rootJobId.Value].Data.Count() / 1024);
+          this.HiveJob = new HiveJob(allSerializedJobs[this.rootJobId.Value], false);
+          allSerializedJobs.Remove(this.rootJobId.Value); // reduce memory footprint
+          progress.ProgressValue = (double)jobCount / totalJobCount;
+
+          if (this.HiveJob.Job.DateFinished.HasValue) {
+            this.ExecutionTime = this.HiveJob.Job.DateFinished.Value - this.HiveJob.Job.DateCreated.Value;
+            this.lastUpdateTime = this.HiveJob.Job.DateFinished.Value;
+            this.ExecutionState = Core.ExecutionState.Stopped;
+            OnStopped();
+          } else {
+            this.ExecutionTime = DateTime.Now - this.HiveJob.Job.DateCreated.Value;
+            this.lastUpdateTime = DateTime.Now;
+            this.ExecutionState = Core.ExecutionState.Started;
+            OnStarted();
+          }
+
+          // build child-job tree
+          LoadChildResults(service.Obj, this.HiveJob, allResults, allSerializedJobs, progress, totalJobCount, ref jobCount);
+          StartResultPolling();
+        }
+      }
+      catch (Exception e) {
+        OnExceptionOccured(e);
+      }
+      finally {
+        IsProgressing = false;
+      }
+    }
+
+    private void LoadChildResults(IHiveService service, HiveJob parentHiveJob, IEnumerable<LightweightJob> allResults, IDictionary<Guid, JobData> allSerializedJobs, IProgress progress, int totalJobCount, ref int jobCount) {
+      IEnumerable<LightweightJob> childResults = from result in allResults
+                                                 where result.ParentJobId.HasValue && result.ParentJobId.Value == parentHiveJob.Job.Id
+                                                 orderby result.DateCreated ascending
+                                                 select result;
+      foreach (LightweightJob lightweightJob in childResults) {
+        jobCount++;
+        progress.Status = string.Format("Deserializing {0} of {1} jobs ({2} kb)...", jobCount, totalJobCount, allSerializedJobs[lightweightJob.Id].Data.Count() / 1024);
+        OptimizerJob optimizerJob = PersistenceUtil.Deserialize<OptimizerJob>(allSerializedJobs[lightweightJob.Id].Data);
+        progress.ProgressValue = (double)jobCount / totalJobCount;
+        HiveJob childHiveJob = new HiveJob(optimizerJob, false);
+        parentHiveJob.AddChildHiveJob(childHiveJob);
+        childHiveJob.Job = allSerializedJobs[lightweightJob.Id].JobInfo;
+        allSerializedJobs.Remove(lightweightJob.Id); // reduce memory footprint
+        if (jobCount % 10 == 0) GC.Collect(); // this is needed or otherwise HL takes over the system when the number of jobs is high
+        LoadChildResults(service, childHiveJob, allResults, allSerializedJobs, progress, totalJobCount, ref jobCount);
+      }
+    }
+
+    private OptimizerJob LoadOptimizerJob(Guid jobId) {
+      using (var service = ServiceLocator.Instance.ServicePool.GetService()) {
+        JobData serializedJob = service.Obj.GetJobData(jobId);
+        return PersistenceUtil.Deserialize<OptimizerJob>(serializedJob.Data);
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveExperimentList.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveExperimentList.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveExperimentList.cs	(revision 4629)
@@ -0,0 +1,42 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Clients.Hive {
+  using DT = HeuristicLab.Services.Hive.Common.DataTransfer;
+
+  [Item("HiveExperiment List", "Represents a list of hive experiments.")]
+  [StorableClass]
+  public class HiveExperimentList : ItemList<HiveExperiment> {
+    public HiveExperimentList() : base() { }
+    public HiveExperimentList(int capacity) : base(capacity) { }
+    public HiveExperimentList(IEnumerable<HiveExperiment> collection) : base(collection) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      HiveExperiment clone = (HiveExperiment)base.Clone(cloner);
+      return clone;
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJob.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJob.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJob.cs	(revision 4629)
@@ -0,0 +1,563 @@
+﻿#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.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Services.Hive.Common.DataTransfer;
+using HeuristicLab.Clients.Hive.Jobs;
+
+namespace HeuristicLab.Clients.Hive {
+  [StorableClass]
+  public class HiveJob : Item {
+    private static object locker = new object();
+
+    public override Image ItemImage {
+      get {
+        if (job.Id == Guid.Empty) { // not yet uploaded
+          return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event;
+        } else {
+          if (job.State == JobState.Waiting) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
+          else if (job.State == JobState.WaitForChildJobs) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
+          else if (job.State == JobState.Calculating) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStarted;
+          else if (job.State == JobState.Aborted) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStopped;
+          else if (job.State == JobState.Failed) return HeuristicLab.Common.Resources.VS2008ImageLibrary.Error;
+          else if (job.State == JobState.Finished) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStopped;
+          else return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event;
+        }
+      }
+    }
+
+    [Storable]
+    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; }
+      private set {
+        if (optimizerJob != null && syncJobsWithOptimizers) {
+          this.childHiveJobs.Clear();
+        }
+        if (optimizerJob != value) {
+          DergisterOptimizerEvents();
+          optimizerJob = value;
+          if (optimizerJob.ExecutionState == ExecutionState.Stopped) {
+            IsFinishedOptimizerDownloaded = true;
+          }
+          RegisterOptimizerEvents();
+          OnOptimizerJobChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private HiveJobList childHiveJobs;
+    public ReadOnlyItemList<HiveJob> ChildHiveJobs {
+      get { return childHiveJobs.AsReadOnly(); }
+    }
+
+    [Storable]
+    private bool isFinishedOptimizerDownloaded;
+    public bool IsFinishedOptimizerDownloaded {
+      get { return isFinishedOptimizerDownloaded; }
+      set {
+        if (isFinishedOptimizerDownloaded != value) {
+          isFinishedOptimizerDownloaded = value;
+          OnIsFinishedOptimizerDownloadedChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private bool syncJobsWithOptimizers = true;
+
+    public HiveJob() {
+      this.Job = new Job() {
+        State = JobState.Waiting,
+        DateCreated = DateTime.Now,
+        CoresNeeded = 1,
+        MemoryNeeded = 0
+      };
+      this.childHiveJobs = new HiveJobList();
+      syncJobsWithOptimizers = true;
+    }
+
+    public HiveJob(Job jobDto)
+      : this() {
+      this.Job = jobDto;
+    }
+
+    public HiveJob(LightweightJob lightweightJob)
+      : this() {
+      UpdateFromLightweightJob(lightweightJob);
+    }
+
+    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(JobData serializedJob, bool autoCreateChildHiveJobs)
+      : this() {
+      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
+      this.Job = serializedJob.JobInfo;
+      this.OptimizerJob = PersistenceUtil.Deserialize<OptimizerJob>(serializedJob.Data);
+      this.syncJobsWithOptimizers = true;
+    }
+
+    /// <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.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.Algorithm != null) {
+            while (this.childHiveJobs.Count < batchRun.Repetitions) {
+              this.childHiveJobs.Add(new HiveJob(batchRun.Algorithm));
+            }
+            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 Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+          experiment.Optimizers.ItemsReplaced += new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+          experiment.Optimizers.ItemsRemoved += new Collections.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.AlgorithmChanged += new EventHandler(batchRun_AlgorithmChanged);
+        }
+
+        OptimizerJob.ComputeInParallelChanged += new EventHandler(OptimizerJob_ComputeInParallelChanged);
+        OptimizerJob.ToStringChanged += new EventHandler(OptimizerJob_ToStringChanged);
+      }
+    }
+    private void DergisterOptimizerEvents() {
+      if (Job != null && OptimizerJob.Optimizer is Optimization.Experiment) {
+        if (OptimizerJob.Optimizer is Optimization.Experiment) {
+          Optimization.Experiment experiment = OptimizerJob.OptimizerAsExperiment;
+          experiment.Optimizers.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+          experiment.Optimizers.ItemsReplaced -= new Collections.CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+          experiment.Optimizers.ItemsRemoved -= new Collections.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.AlgorithmChanged -= new EventHandler(batchRun_AlgorithmChanged);
+        }
+
+        OptimizerJob.ComputeInParallelChanged -= new EventHandler(OptimizerJob_ComputeInParallelChanged);
+        OptimizerJob.ToStringChanged -= new EventHandler(OptimizerJob_ToStringChanged);
+      }
+    }
+        
+    void batchRun_AlgorithmChanged(object sender, EventArgs e) {
+      if (syncJobsWithOptimizers) {
+        this.childHiveJobs.Clear();
+        UpdateChildHiveJobs();
+      }
+    }
+
+    void batchRun_RepetitionsChanged(object sender, EventArgs e) {
+      if (syncJobsWithOptimizers) {
+        UpdateChildHiveJobs();
+      }
+    }
+
+    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));
+        }
+      }
+    }
+    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));
+        }
+      }
+    }
+
+    void OptimizerJob_ComputeInParallelChanged(object sender, EventArgs e) {
+      if (OptimizerJob != null && syncJobsWithOptimizers) {
+        if (OptimizerJob.ComputeInParallel) {
+          // child-hive jobs are not yet created, so create them according to the child-optimizers
+          this.UpdateChildHiveJobs();
+        } else {
+          // child-hive jobs need to be deleted
+          this.childHiveJobs.Clear();
+        }
+      }
+    }
+
+    public void AddChildHiveJob(HiveJob hiveJob) {
+      this.childHiveJobs.Add(hiveJob);
+      syncJobsWithOptimizers = false;
+      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);
+      }
+      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 algorithm
+    /// </summary>
+    public void UpdateChildOptimizer(OptimizerJob optimizerJob, Guid childJobId) {
+      syncJobsWithOptimizers = false; // don't sync with optimizers during this method
+      bool childIsFinishedOptimizerDownloaded = false;
+
+      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;
+      }
+      syncJobsWithOptimizers = true;
+    }
+
+    /// <summary>
+    /// Adds the runs from the optimizerJob to the batchrun and replaces the algorithm 
+    /// 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.Algorithm == null) {
+        batchRun.Algorithm = (IAlgorithm)optimizerJob.Optimizer; // only set the first optimizer as algorithm. if every time the Algorithm would be set, the runs would be cleared each time
+      }
+      foreach (IRun run in optimizerJob.Optimizer.Runs) {
+        if (!batchRun.Runs.Contains(run))
+          batchRun.Runs.Add(run);
+      }
+    }
+
+    /// <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.DateCreated = lightweightJob.DateCreated;
+        job.DateCalculated = lightweightJob.DateCalculated;
+        job.DateFinished = lightweightJob.DateFinished;
+        job.Exception = lightweightJob.Exception;
+        job.Id = lightweightJob.Id;
+        job.ExecutionTime = lightweightJob.ExecutionTime;
+        job.State = lightweightJob.State;
+        // what about parentJob
+        OnJobStateChanged();
+        OnToStringChanged();
+        OnItemImageChanged();
+      }
+    }
+
+    /// <summary>
+    /// Creates a SerializedJob 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 GetAsSerializedJob(bool withoutChildOptimizers) {
+      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);
+      } else if (withoutChildOptimizers && this.OptimizerJob.Optimizer is Optimization.BatchRun) {
+        OptimizerJob clonedJob = (OptimizerJob)this.OptimizerJob.Clone();
+        clonedJob.OptimizerAsBatchRun.Algorithm = null;
+        jobByteArray = PersistenceUtil.Serialize(clonedJob);
+      } 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);
+      } else {
+        jobByteArray = PersistenceUtil.Serialize(this.OptimizerJob);
+      }
+
+      UpdateRequiredPlugins();
+
+      JobData serializedJob = new JobData() {
+        JobId = job.Id,
+        Data = jobByteArray
+      };
+
+      return serializedJob;
+    }
+
+    /// <summary>
+    /// find out which which plugins are needed for the given object
+    /// </summary>
+    private void UpdateRequiredPlugins() {
+      //this.Job.PluginsNeeded = HivePluginInfoDto.FindPluginsNeeded(optimizerJob.GetType());
+      throw new NotImplementedException();
+    }
+
+    #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 = JobChanged;
+      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);
+        }
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      LogMessage("I am beeing cloned");
+      HiveJob clone = (HiveJob)base.Clone(cloner);
+      clone.job = (Job)cloner.Clone(this.job);
+      clone.optimizerJob = (OptimizerJob)cloner.Clone(this.optimizerJob);
+      return clone;
+    }
+
+    /// <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);
+      }
+    }
+
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJobList.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJobList.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJobList.cs	(revision 4629)
@@ -0,0 +1,40 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Clients.Hive {
+  [Item("JobItem List", "Represents a list of hive jobs.")]
+  [StorableClass]
+  public class HiveJobList : ItemList<HiveJob> {
+    public HiveJobList() : base() { }
+    public HiveJobList(int capacity) : base(capacity) { }
+    public HiveJobList(IEnumerable<HiveJob> collection) : base(collection) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      HiveJobList clone = (HiveJobList)base.Clone(cloner);
+      return clone;
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/JobResultPoller.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/JobResultPoller.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/JobResultPoller.cs	(revision 4629)
@@ -0,0 +1,131 @@
+﻿#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.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Services.Hive.Common;
+using HeuristicLab.Services.Hive.Common.ServiceContracts;
+using HeuristicLab.Services.Hive.Common.DataTransfer;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Clients.Hive {
+  internal class JobResultPoller {
+    private bool stopRequested { get; set; }
+    private AutoResetEvent waitHandle;
+    private Thread thread;
+
+    private HiveJob hiveJob;
+    public HiveJob HiveJob {
+      get { return hiveJob; }
+      set { hiveJob = value; }
+    }
+
+    private TimeSpan interval;
+    public TimeSpan Interval {
+      get { return interval; }
+      set { interval = value; }
+    }
+
+    private bool isPolling;
+    public bool IsPolling {
+      get { return isPolling; }
+      set {
+        if (isPolling != value) {
+          isPolling = value;
+          OnIsPollingChanged();
+        }
+      }
+    }
+
+    public JobResultPoller(HiveJob hiveJob, TimeSpan interval) {
+      this.isPolling = false;
+      this.hiveJob = hiveJob;
+      this.interval = interval;
+    }
+
+    public void Start() {
+      stopRequested = false;
+      thread = new Thread(RunPolling);
+      thread.Start();
+      IsPolling = true;
+    }
+
+    public void Stop() {
+      // use AutoResetEvent.Set instead if Thread.Interrupt because its much cleaner
+      stopRequested = true;
+      waitHandle.Set();
+      IsPolling = false;
+      thread = null;
+    }
+
+    public void RunPolling() {
+      try {
+        waitHandle = new AutoResetEvent(false);
+        while (!stopRequested) {
+          OnPollingStarted();
+          FetchJobResults();
+          OnPollingFinished();
+          waitHandle.WaitOne(Interval);
+        }
+        waitHandle.Close();
+      }
+      catch (Exception e) {
+        OnExceptionOccured(e);
+      }
+    }
+
+    private void FetchJobResults() {
+      using (Disposable<IHiveService> service = ServiceLocator.Instance.ServicePool.GetService()) {
+        IEnumerable<LightweightJob> response = service.Obj.GetLightweightChildJobs(hiveJob.Job.Id, true, true);
+        OnJobResultsReceived(response);
+      }
+    }
+
+    public event EventHandler<EventArgs<IEnumerable<LightweightJob>>> JobResultsReceived;
+    private void OnJobResultsReceived(IEnumerable<LightweightJob> lightweightJobs) {
+      var handler = JobResultsReceived;
+      if (handler != null) handler(this, new EventArgs<IEnumerable<LightweightJob>>(lightweightJobs));
+    }
+
+    public event EventHandler<EventArgs<Exception>> ExceptionOccured;
+    private void OnExceptionOccured(Exception e) {
+      var handler = ExceptionOccured;
+      if (handler != null) handler(this, new EventArgs<Exception>(e));
+    }
+
+    public event EventHandler IsPollingChanged;
+    private void OnIsPollingChanged() {
+      var handler = IsPollingChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler PollingStarted;
+    private void OnPollingStarted() {
+      var handler = PollingStarted;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler PollingFinished;
+    private void OnPollingFinished() {
+      var handler = PollingFinished;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Jobs/JobList.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Jobs/JobList.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Jobs/JobList.cs	(revision 4629)
@@ -0,0 +1,41 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Hive;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Clients.Hive.Jobs {
+  [Item("IJob List", "Represents a list of Hive Job Objects.")]
+  [StorableClass]
+  public class JobList : ItemList<IJob> {
+    public JobList() : base() { }
+    public JobList(int capacity) : base(capacity) { }
+    public JobList(IEnumerable<IJob> collection) : base(collection) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      HiveJobList clone = (HiveJobList)base.Clone(cloner);
+      return clone;
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Jobs/OptimizerJob.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Jobs/OptimizerJob.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Jobs/OptimizerJob.cs	(revision 4629)
@@ -0,0 +1,349 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Hive;
+
+namespace HeuristicLab.Clients.Hive.Jobs {
+  [StorableClass]
+  public class OptimizerJob : IJob {
+    [Storable]
+    protected IOptimizer optimizer;
+    public IOptimizer Optimizer {
+      get { return optimizer; }
+      set {
+        if (value != optimizer) {
+          if (optimizer != null) DeregisterEvents();
+          optimizer = value;
+          if (optimizer != null) RegisterEvents();
+          OnOptimizerChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected ILog log;
+    public ILog Log {
+      get { return log; }
+    }
+
+    [Storable]
+    protected bool computeInParallel;
+    public bool ComputeInParallel {
+      get { return computeInParallel; }
+      set {
+        if (computeInParallel != value) {
+          computeInParallel = value;
+          OnComputeInParallelChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private int indexInParentOptimizerList = -1;
+    public int IndexInParentOptimizerList {
+      get { return indexInParentOptimizerList; }
+      set { this.indexInParentOptimizerList = value; }
+    }
+
+
+    [Storable]
+    private bool collectChildJobs;
+    public bool CollectChildJobs {
+      get { return collectChildJobs; }
+      set { collectChildJobs = value; }
+    }
+
+    public OptimizerJob() {
+      this.log = new Log();
+    }
+
+    public OptimizerJob(IOptimizer optimizer)
+      : this() {
+      this.Optimizer = optimizer;
+
+      if (optimizer is Optimization.Experiment) {
+        this.ComputeInParallel = true;
+      } else if (optimizer is Optimization.BatchRun) {
+        this.ComputeInParallel = false;
+      } else {
+        this.ComputeInParallel = false;
+      }
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    protected virtual void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    /// <summary>
+    /// Casts the Optimizer to an Experiment. Returns null if cast was not successfull.
+    /// </summary>
+    public Optimization.Experiment OptimizerAsExperiment {
+      get { return Optimizer as Optimization.Experiment; }
+    }
+
+    /// <summary>
+    /// Casts the Optimizer to an BatchRun. Returns null if cast was not successfull.
+    /// </summary>
+    public Optimization.BatchRun OptimizerAsBatchRun {
+      get { return Optimizer as Optimization.BatchRun; }
+    }
+
+    #region IJob Members
+
+    public virtual ExecutionState ExecutionState {
+      get { return optimizer.ExecutionState; }
+    }
+
+    public TimeSpan ExecutionTime {
+      get { return optimizer.ExecutionTime; }
+    }
+
+    public virtual void Run() {
+      throw new NotSupportedException();
+    }
+
+    public virtual void Prepare() {
+      optimizer.Prepare();
+    }
+
+    public virtual void Start() {
+      if ((optimizer is Optimization.Experiment && OptimizerAsExperiment.Optimizers.Count == 0) || // experiment would not fire OnStopped if it has 0 optimizers
+          (optimizer is Optimization.BatchRun && OptimizerAsBatchRun.Algorithm == null)) { // batchrun would not fire OnStopped if algorithm == null
+        OnJobStopped();
+      } else {
+        optimizer.Start();
+      }
+    }
+
+    public virtual void Stop() {
+      optimizer.Stop();
+    }
+
+    public virtual void Resume(IEnumerable<IJob> childJobs) {
+      OnJobStopped();
+    }
+
+    public event EventHandler JobStopped;
+    protected virtual void OnJobStopped() {
+      EventHandler handler = JobStopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler JobFailed;
+    protected virtual void OnJobFailed(EventArgs<Exception> e) {
+      EventHandler handler = JobFailed;
+      if (handler != null) handler(this, e);
+    }
+
+    public event EventHandler<EventArgs<IJob>> NewChildJob;
+    protected virtual void OnNewChildJob(IJob job) {
+      EventHandler<EventArgs<IJob>> handler = NewChildJob;
+      if (handler != null) handler(this, new EventArgs<IJob>(job));
+    }
+
+    public event EventHandler WaitForChildJobs;
+    protected virtual void OnWaitForChildJobs() {
+      EventHandler handler = WaitForChildJobs;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler DeleteChildJobs;
+    protected virtual void OnDeleteChildJobs() {
+      EventHandler handler = DeleteChildJobs;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler ComputeInParallelChanged;
+    protected virtual void OnComputeInParallelChanged() {
+      EventHandler handler = ComputeInParallelChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler OptimizerChanged;
+    protected virtual void OnOptimizerChanged() {
+      EventHandler handler = OptimizerChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    #region Optimizer Events
+    protected virtual void RegisterEvents() {
+      optimizer.Stopped += new EventHandler(optimizer_Stopped);
+      optimizer.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(optimizer_ExceptionOccurred);
+      optimizer.DescriptionChanged += new EventHandler(optimizer_DescriptionChanged);
+      optimizer.ItemImageChanged += new EventHandler(optimizer_ItemImageChanged);
+      optimizer.NameChanged += new EventHandler(optimizer_NameChanged);
+      optimizer.NameChanging += new EventHandler<CancelEventArgs<string>>(optimizer_NameChanging);
+      optimizer.ToStringChanged += new EventHandler(optimizer_ToStringChanged);
+    }
+    protected virtual void DeregisterEvents() {
+      optimizer.Stopped -= new EventHandler(optimizer_Stopped);
+      optimizer.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(optimizer_ExceptionOccurred);
+      optimizer.DescriptionChanged -= this.DescriptionChanged;
+      optimizer.ItemImageChanged -= this.ItemImageChanged;
+      optimizer.NameChanged -= this.NameChanged;
+      optimizer.NameChanging -= this.NameChanging;
+      optimizer.ToStringChanged -= this.ToStringChanged;
+    }
+
+    void optimizer_ToStringChanged(object sender, EventArgs e) {
+      this.OnToStringChanged();
+    }
+
+    void optimizer_NameChanging(object sender, CancelEventArgs<string> e) {
+      this.OnNameChanging(e.Value, e.Cancel);
+    }
+
+    void optimizer_NameChanged(object sender, EventArgs e) {
+      this.OnNameChanged();
+    }
+
+    void optimizer_ItemImageChanged(object sender, EventArgs e) {
+      this.OnItemImageChanged();
+    }
+
+    void optimizer_DescriptionChanged(object sender, EventArgs e) {
+      this.OnDescriptionChanged();
+    }
+
+    protected virtual void optimizer_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      OnJobFailed(e);
+    }
+
+    protected virtual void optimizer_Stopped(object sender, EventArgs e) {
+      OnJobStopped();
+    }
+    #endregion
+
+    #region INamedItem Members
+
+    public bool CanChangeDescription {
+      get { return optimizer.CanChangeDescription; }
+    }
+
+    public bool CanChangeName {
+      get { return optimizer.CanChangeName; }
+    }
+
+    public string Description {
+      get { return optimizer.Description; }
+      set { optimizer.Description = value; }
+    }
+
+    public string Name {
+      get { return optimizer.Name; }
+      set { optimizer.Name = value; }
+    }
+    #endregion
+
+    #region Events
+    public event EventHandler DescriptionChanged;
+    protected virtual void OnDescriptionChanged() {
+      var handler = DescriptionChanged;
+      if(handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ItemImageChanged;
+    protected virtual void OnItemImageChanged() {
+      var handler = ItemImageChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ToStringChanged;
+    protected virtual void OnToStringChanged() {
+      var handler = ToStringChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler NameChanged;
+    protected virtual void OnNameChanged() {
+      var handler = NameChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<CancelEventArgs<string>> NameChanging;
+    protected virtual void OnNameChanging(string value, bool cancel) {
+      var handler = NameChanging;
+      if (handler != null) handler(this, new CancelEventArgs<string>(value, cancel));
+    }
+    #endregion
+
+    #region IItem Members
+
+    public string ItemDescription {
+      get { return optimizer.ItemDescription; }
+    }
+
+    public System.Drawing.Image ItemImage {
+      get { return optimizer.ItemImage; }
+    }
+
+    public string ItemName {
+      get { return optimizer.ItemName; }
+    }
+
+    public Version ItemVersion {
+      get { return optimizer.ItemVersion; }
+    }
+
+    #endregion
+
+    #region IDeepCloneable Members
+
+    public IDeepCloneable Clone(Cloner cloner) {
+      OptimizerJob clone = (OptimizerJob)Activator.CreateInstance(this.GetType());
+      cloner.RegisterClonedObject(this, clone);
+      clone.Optimizer = (IOptimizer)cloner.Clone(this.Optimizer);
+      clone.log = (ILog)cloner.Clone(this.Log);
+      clone.ComputeInParallel = this.ComputeInParallel;
+      clone.IndexInParentOptimizerList = this.IndexInParentOptimizerList;
+      clone.CollectChildJobs = this.CollectChildJobs;
+      clone.RegisterEvents();
+      return clone;
+    }
+
+    #endregion
+
+    #region ICloneable Members
+
+    public object Clone() {
+      return Clone(new Cloner());
+    }
+
+    #endregion
+
+    /// <summary>
+    /// Gets the string representation of the current instance in the format: <c>Name: [null|Value]</c>.
+    /// </summary>
+    /// <returns>The current instance as a string.</returns>
+    public override string ToString() {
+      return Name;
+    }
+
+    public virtual bool IsParallelizable {
+      get { return this.Optimizer is Optimization.Experiment || this.Optimizer is BatchRun; }
+    }
+
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/PersistenceUtil.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/PersistenceUtil.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/PersistenceUtil.cs	(revision 4629)
@@ -0,0 +1,25 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using HeuristicLab.Persistence.Default.Xml;
+
+namespace HeuristicLab.Clients.Hive {
+  public static class PersistenceUtil {
+    public static byte[] Serialize(object obj) {
+      MemoryStream memStream = new MemoryStream();
+      XmlGenerator.Serialize(obj, memStream);
+      byte[] jobByteArray = memStream.ToArray();
+      memStream.Dispose();
+      return jobByteArray;
+    }
+
+    public static T Deserialize<T>(byte[] sjob) {
+      MemoryStream memStream = new MemoryStream(sjob);
+      T job = XmlParser.Deserialize<T>(memStream);
+      memStream.Dispose();
+      return job;
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Progress/IProgress.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Progress/IProgress.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Progress/IProgress.cs	(revision 4629)
@@ -0,0 +1,35 @@
+﻿#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;
+
+namespace HeuristicLab.Clients.Hive {
+  public interface IProgress {
+    string Status { get; set; }
+    double ProgressValue { get; set; }
+
+    void Finish();
+
+    event EventHandler Finished;
+    event EventHandler StatusChanged;
+    event EventHandler ProgressValueChanged;
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Progress/IProgressReporter.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Progress/IProgressReporter.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Progress/IProgressReporter.cs	(revision 4629)
@@ -0,0 +1,31 @@
+﻿#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;
+
+namespace HeuristicLab.Clients.Hive {
+  public interface IProgressReporter {
+    IProgress Progress { get; }
+    bool IsProgressing { get; }
+
+    event EventHandler IsProgressingChanged;
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Progress/Progress.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Progress/Progress.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Progress/Progress.cs	(revision 4629)
@@ -0,0 +1,82 @@
+﻿#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;
+
+namespace HeuristicLab.Clients.Hive {
+  public class Progress : IProgress {
+    private string status;
+    public string Status {
+      get {
+        return this.status;
+      }
+      set {
+        if (this.status != value) {
+          this.status = value;
+          OnStatusChanged();
+        }
+      }
+    }
+
+    private double progressValue;
+    public double ProgressValue {
+      get {
+        return this.progressValue;
+      }
+      set {
+        if (this.progressValue != value) {
+          this.progressValue = value;
+          OnProgressChanged();
+        }
+      }
+    }
+
+    public Progress() { }
+
+    public Progress(string status) {
+      this.Status = status;
+    }
+
+    public void Finish() {
+      OnFinished();
+    }
+
+    #region Event Handler
+    public event EventHandler Finished;
+    private void OnFinished() {
+      var handler = Finished;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler StatusChanged;
+    private void OnStatusChanged() {
+      var handler = StatusChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler ProgressValueChanged;
+    private void OnProgressChanged() {
+      var handler = ProgressValueChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Properties/Settings.Designer.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Properties/Settings.Designer.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Properties/Settings.Designer.cs	(revision 4629)
@@ -0,0 +1,50 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.1
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace HeuristicLab.Clients.Hive.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string HiveUsername {
+            get {
+                return ((string)(this["HiveUsername"]));
+            }
+            set {
+                this["HiveUsername"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string HivePassword {
+            get {
+                return ((string)(this["HivePassword"]));
+            }
+            set {
+                this["HivePassword"] = value;
+            }
+        }
+    }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Properties/Settings.settings
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Properties/Settings.settings	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Properties/Settings.settings	(revision 4629)
@@ -0,0 +1,12 @@
+﻿<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="HeuristicLab.Clients.Hive" GeneratedClassName="Settings">
+  <Profiles />
+  <Settings>
+    <Setting Name="HiveUsername" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="HivePassword" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+  </Settings>
+</SettingsFile>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/GenerateServiceClients.cmd
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/GenerateServiceClients.cmd	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/GenerateServiceClients.cmd	(revision 4629)
@@ -0,0 +1,29 @@
+echo off
+
+echo.
+echo *******************************************************************************************
+echo Generating HiveService client
+echo.
+
+svcutil.exe ^
+  http://localhost:9001/HiveService/mex ^
+  /out:HiveServiceClient ^
+  /namespace:*,HeuristicLab.Clients.Hive ^
+  /targetClientVersion:Version35 ^
+  /enableDataBinding ^
+  /config:..\app.config ^
+  /reference:..\..\..\HeuristicLab.Services.Hive.Common\3.3\bin\debug\HeuristicLab.Services.Hive.Common-3.3.dll
+
+echo.
+echo ---------------------------------------------------------------------------------------
+echo !!! ATTENTION !!! ATTENTION !!! ATTENTION !!! ATTENTION !!! ATTENTION !!! ATTENTION !!!
+echo.
+echo Following modifications have to be done manually in generated data contracts:
+echo  * Remove method "protected void RaisePropertyChanged(string propertyName)" in OKBItem
+echo.
+echo !!! ATTENTION !!! ATTENTION !!! ATTENTION !!! ATTENTION !!! ATTENTION !!! ATTENTION !!!
+echo ---------------------------------------------------------------------------------------
+echo.
+echo Generation of OKBService client finished.
+echo *******************************************************************************************
+
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/ServiceClientFactory.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/ServiceClientFactory.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/ServiceClientFactory.cs	(revision 4629)
@@ -0,0 +1,190 @@
+﻿#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.ServiceModel;
+using HeuristicLab.Common;
+using HeuristicLab.Tracing;
+using HeuristicLab.Services.Hive.Common;
+using System.ServiceModel.Description;
+
+namespace HeuristicLab.Clients.Hive {
+  public class ServiceClientFactory<T> {
+    private static object locker = new object();
+
+    private string endpointName;
+
+    private string username;
+    public string Username {
+      get { return username; }
+      set { 
+        if(username != value) {
+          username = value;
+          this.factory = null;
+        }
+      }
+    }
+
+    private string password;
+    public string Password {
+      set {
+        if (password != value) {
+          password = value;
+          this.factory = null;
+        }
+      }
+    }
+
+    private ChannelFactory<T> factory = null;
+    private Disposable<T> disposableService = null;
+    private int requestCount = 0;
+
+    public ServiceClientFactory(string username, string password, string endpointName) {
+      this.username = username;
+      this.password = password;
+      this.endpointName = endpointName;
+    }
+
+    private T CreateFacade(string endpointName) {
+      lock (locker) {
+        try {
+          return CreateChannel(endpointName);
+        }
+        catch (EndpointNotFoundException ex) {
+          OnExceptionOccured(ex);
+        }
+        return default(T);
+      }
+    }
+
+    protected virtual T CreateChannel(string endpointName) {
+      if (factory == null) {
+        factory = new ChannelFactory<T>(endpointName);
+        factory.Credentials.UserName.UserName = username;
+        factory.Credentials.UserName.Password = password;
+        factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
+      }
+      
+      return factory.CreateChannel();
+    }
+
+    public Disposable<T> GetService() {
+      lock (locker) {
+        requestCount++;
+        Logger.Debug("Request for ServiceProxy (count: " + requestCount + ")");
+        if (disposableService != null) {
+          if (GetServiceState() == CommunicationState.Faulted) {
+            DisposeService();
+          }
+        }
+        if (disposableService == null) {
+          disposableService = new Disposable<T>(CreateFacade(this.endpointName));
+          RegisterServiceEvents();
+        }        
+        return disposableService;
+      }
+    }
+
+    private void RegisterServiceEvents() {
+      disposableService.OnDisposing += new EventHandler(disposableService_OnDisposing);
+      ((ICommunicationObject)disposableService.Obj).Faulted += new EventHandler(WcfServicePool_Faulted);
+    }
+
+    private void DeregisterServiceEvents() {
+      disposableService.OnDisposing -= new EventHandler(disposableService_OnDisposing);
+      ((ICommunicationObject)disposableService.Obj).Faulted -= new EventHandler(WcfServicePool_Faulted);
+    }
+
+    private CommunicationState GetServiceState() {
+      return ((ICommunicationObject)disposableService.Obj).State;
+    }
+
+    void WcfServicePool_Faulted(object sender, EventArgs e) {
+      OnExceptionOccured(new CommunicationException(e.ToString()));
+    }
+
+    private void disposableService_OnDisposing(object sender, EventArgs e) {
+      DisposeService();
+    }
+
+    public void DisposeService() {
+      lock (locker) {
+        requestCount--;
+        Logger.Debug("Disposing ServiceProxy (count: " + requestCount + ")");
+        if (requestCount == 0) {
+          try {
+            DeregisterServiceEvents();
+            ServiceUtil.DisposeWcfClient((ICommunicationObject)disposableService.Obj);
+          }
+          catch (Exception e) {
+            OnExceptionOccured(e);
+          }
+          finally {
+            disposableService = null;
+          }
+        } else if (requestCount < 0) {
+          throw new ServiceClientFactoryException("requestCount cannot be less than 0.");
+        }
+      }
+    }
+
+    public event EventHandler<EventArgs<Exception>> ExceptionOccured;
+    private void OnExceptionOccured(Exception e) {
+      lock (locker) {
+        var handler = ExceptionOccured;
+        if (handler != null) handler(this, new EventArgs<Exception>(e));
+      }
+    }
+  }
+
+  public static class ServiceUtil {
+    /// <summary>
+    /// This method changes the endpoint-address while preserving the identity-certificate defined in the config file
+    /// </summary>
+    public static void ReplaceEndpointAddress(ServiceEndpoint endpoint, string hostAddress) {
+      EndpointAddressBuilder builder = new EndpointAddressBuilder(endpoint.Address);
+      UriBuilder uriBuilder = new UriBuilder(builder.Uri);
+      uriBuilder.Host = hostAddress;
+      builder.Uri = uriBuilder.Uri;
+      endpoint.Address = builder.ToEndpointAddress();
+    }
+
+    /// <summary>
+    /// Safely disposes a WCF client proxy object
+    /// </summary>
+    /// <param name="obj"></param>
+    public static void DisposeWcfClient(ICommunicationObject obj) {
+      if (obj != null) {
+        if (obj.State != CommunicationState.Faulted &&
+            obj.State != CommunicationState.Closed) {
+          try { obj.Close(); }
+          catch (CommunicationObjectFaultedException) { obj.Abort(); }
+          catch (TimeoutException) { obj.Abort(); }
+          catch (Exception e) {
+            obj.Abort();
+            Logger.Error(e);
+          }
+        } else
+          obj.Abort();
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/ServiceClientFactoryException.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/ServiceClientFactoryException.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/ServiceClientFactoryException.cs	(revision 4629)
@@ -0,0 +1,28 @@
+﻿#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;
+
+namespace HeuristicLab.Clients.Hive {
+  public class ServiceClientFactoryException : Exception {
+    public ServiceClientFactoryException(string message) : base(message) { }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceLocator.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceLocator.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceLocator.cs	(revision 4629)
@@ -0,0 +1,59 @@
+﻿#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 HeuristicLab.Services.Hive.Common.ServiceContracts;
+using HeuristicLab.Clients.Hive.Properties;
+
+namespace HeuristicLab.Clients.Hive {
+  internal class ServiceLocator {
+    private static ServiceLocator instance = null;
+    private ServiceClientFactory<IHiveService> serviceFactory = null;
+
+    public static ServiceLocator Instance {
+      get {
+        if (instance == null) {
+          instance = new ServiceLocator();
+        }
+        return instance;
+      }
+    }
+
+    public ServiceLocator() {
+      Settings.Default.SettingChanging += new System.Configuration.SettingChangingEventHandler(Default_SettingChanging);
+    }
+
+    private void Default_SettingChanging(object sender, System.Configuration.SettingChangingEventArgs e) {
+      if (serviceFactory != null) {
+        serviceFactory.Username = Settings.Default.HiveUsername;
+        serviceFactory.Password = Settings.Default.HivePassword;
+      }
+    }
+
+    public ServiceClientFactory<IHiveService> ServicePool {
+      get {
+        if (serviceFactory == null) {
+          serviceFactory = new ServiceClientFactory<IHiveService>(Settings.Default.HiveUsername, Settings.Default.HivePassword, "TcpEndpoint");
+        }
+        return serviceFactory;
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/app.config
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/app.config	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/app.config	(revision 4629)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <system.serviceModel>
+        <bindings>
+            <netTcpBinding>
+                <binding name="TcpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
+                    receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
+                    transferMode="Streamed" transactionProtocol="OleTransactions"
+                    hostNameComparisonMode="StrongWildcard" listenBacklog="10"
+                    maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
+                    maxReceivedMessageSize="65536">
+                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
+                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
+                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
+                        enabled="false" />
+                    <security mode="TransportWithMessageCredential">
+                        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
+                        <message clientCredentialType="UserName" algorithmSuite="Default" />
+                    </security>
+                </binding>
+            </netTcpBinding>
+        </bindings>
+        <client>
+            <endpoint address="net.tcp://localhost:9000/HiveService" binding="netTcpBinding"
+                bindingConfiguration="TcpEndpoint" contract="HeuristicLab.Services.Hive.Common.ServiceContracts.IHiveService"
+                name="TcpEndpoint">
+                <identity>
+                    <dns value="localhost" />
+                </identity>
+            </endpoint>
+        </client>
+    </system.serviceModel>
+</configuration>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Hive.sln
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Hive.sln	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Hive.sln	(revision 4629)
@@ -3,19 +3,8 @@
 # Visual Studio 2010
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Hive-3.3", "HeuristicLab.Hive\3.3\HeuristicLab.Hive-3.3.csproj", "{F98A1740-9AC9-4D36-A582-6A2D0D06978D}"
-	ProjectSection(ProjectDependencies) = postProject
-		{E1D6C801-892A-406A-B606-F158E36DD3C3} = {E1D6C801-892A-406A-B606-F158E36DD3C3}
-		{EC2C8109-6E1E-4C88-9A2B-908CFF2EF4AC} = {EC2C8109-6E1E-4C88-9A2B-908CFF2EF4AC}
-		{14424A16-48D4-445E-80BF-DDF617548BBB} = {14424A16-48D4-445E-80BF-DDF617548BBB}
-		{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE} = {CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}
-		{989FE92B-484E-41EE-87E2-6A24AF0381D8} = {989FE92B-484E-41EE-87E2-6A24AF0381D8}
-		{8C0D9F39-397F-4DBE-856F-BC4DC0FE23F8} = {8C0D9F39-397F-4DBE-856F-BC4DC0FE23F8}
-		{B5EF1E5A-9F3D-40B9-B4B0-30AADF2E2CEB} = {B5EF1E5A-9F3D-40B9-B4B0-30AADF2E2CEB}
-	EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Clients.Hive.Slave-3.3", "HeuristicLab.Clients.Hive.Slave\3.3\HeuristicLab.Clients.Hive.Slave-3.3.csproj", "{989FE92B-484E-41EE-87E2-6A24AF0381D8}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Services.Hive.Common-3.3", "HeuristicLab.Services.Hive.Common\3.3\HeuristicLab.Services.Hive.Common-3.3.csproj", "{14424A16-48D4-445E-80BF-DDF617548BBB}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Services.Hive-3.3", "HeuristicLab.Services.Hive.Server\3.3\HeuristicLab.Services.Hive-3.3.csproj", "{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Services.Hive.DataAccess-3.3", "HeuristicLab.Services.Hive.DataAccess\3.3\HeuristicLab.Services.Hive.DataAccess-3.3.csproj", "{EC2C8109-6E1E-4C88-9A2B-908CFF2EF4AC}"
@@ -35,4 +24,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Clients.Hive.Slave.Views-3.3", "HeuristicLab.Clients.Hive.Slave.Views\3.3\HeuristicLab.Clients.Hive.Slave.Views-3.3.csproj", "{8C0D9F39-397F-4DBE-856F-BC4DC0FE23F8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Services.Hive-3.3", "HeuristicLab.Services.Hive\3.3\HeuristicLab.Services.Hive-3.3.csproj", "{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}"
 EndProject
 Global
@@ -54,8 +45,4 @@
 		{14424A16-48D4-445E-80BF-DDF617548BBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{14424A16-48D4-445E-80BF-DDF617548BBB}.Release|Any CPU.Build.0 = Release|Any CPU
-		{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}.Release|Any CPU.Build.0 = Release|Any CPU
 		{EC2C8109-6E1E-4C88-9A2B-908CFF2EF4AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{EC2C8109-6E1E-4C88-9A2B-908CFF2EF4AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
@@ -74,4 +61,8 @@
 		{8C0D9F39-397F-4DBE-856F-BC4DC0FE23F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{8C0D9F39-397F-4DBE-856F-BC4DC0FE23F8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Hive/3.3/HeuristicLab.Hive-3.3.csproj
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Hive/3.3/HeuristicLab.Hive-3.3.csproj	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Hive/3.3/HeuristicLab.Hive-3.3.csproj	(revision 4629)
@@ -32,4 +32,10 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="HeuristicLab.Common-3.3">
@@ -57,11 +63,15 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
     <PostBuildEvent>set ProjectName=$(ProjectName)
 set TargetPath=$(TargetPath)
+set TargetDir=$(TargetDir)
 set SolutionDir=$(SolutionDir)
-call $(SolutionDir)/MergeConfigs.cmd
-call $(SolutionDir)/CopyAssembly.cmd</PostBuildEvent>
+call $(SolutionDir)/CopyAssembly.cmd
+call $(SolutionDir)/MergeConfigs.cmd</PostBuildEvent>
   </PropertyGroup>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Appointment.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Appointment.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Appointment.cs	(revision 4629)
@@ -22,4 +22,5 @@
 using System;
 using System.Runtime.Serialization;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
@@ -38,4 +39,15 @@
     [DataMember]
     public Guid ResourceId { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      Appointment clone = (Appointment)base.Clone(cloner);
+      clone.AllDayEvent = this.AllDayEvent;
+      clone.EndDate = this.EndDate;
+      clone.Recurring = this.Recurring;
+      clone.RecurringId = this.RecurringId;
+      clone.ResourceId = this.ResourceId;
+      clone.StartDate = this.StartDate;
+      return clone;
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HeartBeat.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HeartBeat.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HeartBeat.cs	(revision 4629)
@@ -27,5 +27,5 @@
 
   [DataContract]
-  public class HeartBeat {
+  public class Heartbeat {
     [DataMember]
     public Guid SlaveId { get; set; }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveExperiment.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveExperiment.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveExperiment.cs	(revision 4629)
@@ -39,6 +39,11 @@
       return base.ToString() + "Name: " + Name + ", Description: " + Description + ", ResourceIds: " + ResourceIds;
     }
-
-    public HiveExperiment() {
+    
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (HiveExperiment)base.Clone(cloner);
+      clone.ResourceIds = this.ResourceIds;
+      clone.RootJobId = this.RootJobId;
+      clone.UserId = this.UserId;
+      return clone;
     }
   }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveItem.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveItem.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveItem.cs	(revision 4629)
@@ -4,10 +4,22 @@
 using System.Text;
 using System.Runtime.Serialization;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
   [DataContract]
-  public abstract class HiveItem {
+  public abstract class HiveItem : IDeepCloneable {
     [DataMember]
     public Guid Id { get; set; }
+
+    public virtual IDeepCloneable Clone(Cloner cloner) {
+      HiveItem clone = (HiveItem)Activator.CreateInstance(this.GetType(), true);
+      cloner.RegisterClonedObject(this, clone);
+      clone.Id = this.Id;
+      return clone;
+    }
+
+    public object Clone() {
+      return Clone(new Cloner());
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HivePlugin.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HivePlugin.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HivePlugin.cs	(revision 4629)
@@ -24,4 +24,5 @@
 using System.Linq;
 using System.Runtime.Serialization;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
@@ -32,5 +33,12 @@
     public Version Version { get; set; }
     [DataMember]
-    public Boolean Update { get; set; }
+    public bool Update { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (HivePlugin)base.Clone(cloner);
+      clone.Version = this.Version;
+      clone.Update = this.Update;
+      return clone;
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HivePluginData.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HivePluginData.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HivePluginData.cs	(revision 4629)
@@ -22,4 +22,5 @@
 using System;
 using System.Runtime.Serialization;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
@@ -34,4 +35,10 @@
       Name = name;
     }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (HivePluginData)base.Clone(cloner);
+      if (this.Data != null) clone.Data = new byte[this.Data.Length]; Array.Copy(this.Data, clone.Data, this.Data.Length);
+      return clone;
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Job.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Job.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Job.cs	(revision 4629)
@@ -55,4 +55,16 @@
       AssignedResourceIds = new List<Guid>();
     }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (Job)base.Clone(cloner);
+      clone.UserId = this.UserId;
+      clone.Priority = this.Priority;
+      clone.CoresNeeded = this.CoresNeeded;
+      clone.MemoryNeeded = this.MemoryNeeded;
+      clone.PluginsNeededIds = new List<Guid>(this.PluginsNeededIds);
+      clone.AssignedResourceIds = new List<Guid>(this.AssignedResourceIds);
+      clone.ProjectId = this.ProjectId;
+      return clone;
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/JobData.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/JobData.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/JobData.cs	(revision 4629)
@@ -23,4 +23,5 @@
 using System.IO;
 using System.Runtime.Serialization;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
@@ -32,4 +33,10 @@
     [DataMember]
     public byte[] Data { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (JobData)base.Clone(cloner);
+      if (this.Data != null) clone.Data = new byte[this.Data.Length]; Array.Copy(this.Data, clone.Data, this.Data.Length);
+      return clone;
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/LightweightJob.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/LightweightJob.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/LightweightJob.cs	(revision 4629)
@@ -22,4 +22,5 @@
 using System;
 using System.Runtime.Serialization;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
@@ -56,4 +57,17 @@
       this.ParentJobId = job.ParentJobId;
     }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (LightweightJob)base.Clone(cloner);
+      clone.SlaveId = this.SlaveId;
+      clone.State = this.State;
+      clone.ExecutionTime = this.ExecutionTime;
+      clone.Exception = this.Exception;
+      clone.DateCreated = this.DateCreated;
+      clone.DateCalculated = this.DateCalculated;
+      clone.DateFinished = this.DateFinished;
+      clone.ParentJobId = this.ParentJobId;
+      return clone;
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/NamedHiveItem.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/NamedHiveItem.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/NamedHiveItem.cs	(revision 4629)
@@ -4,4 +4,5 @@
 using System.Text;
 using System.Runtime.Serialization;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
@@ -12,4 +13,11 @@
     [DataMember]
     public string Description { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (NamedHiveItem)base.Clone(cloner);
+      clone.Name = this.Name;
+      clone.Description = this.Description;
+      return clone;
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Slave.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Slave.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Slave.cs	(revision 4629)
@@ -29,7 +29,7 @@
   public class Slave : Resource {
     [DataMember]
-    public int? NrOfCores { get; set; }
+    public int? Cores { get; set; }
     [DataMember]
-    public int? NrOfFreeCores { get; set; }
+    public int? FreeCores { get; set; }
     [DataMember]
     public int? CpuSpeedPerCore { get; set; }
@@ -39,16 +39,28 @@
     public int? FreeMemory { get; set; }
     [DataMember]
-    public DateTime? Login { get; set; }
-    [DataMember]
     public SlaveState State { get; set; }
     [DataMember]
     public CalendarState CalendarSyncStatus { get; set; }
     [DataMember]
-    public SlaveConfig Config { get; set; }
+    public Guid SlaveConfigId { get; set; }
     [DataMember]
     public bool IsAllowedToCalculate { get; set; }
 
     public override string ToString() {
-      return base.ToString() + ", NrOfCores: " + NrOfCores + ", NrOfFreeCores " + NrOfFreeCores + ", Login: " + Login + ", State: " + State;
+      return base.ToString() + ", NrOfCores: " + Cores + ", NrOfFreeCores " + FreeCores + ", State: " + State;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (Slave)base.Clone(cloner);
+      clone.Cores = this.Cores;
+      clone.FreeCores = this.FreeCores;
+      clone.CpuSpeedPerCore = this.CpuSpeedPerCore;
+      clone.Memory = this.Memory;
+      clone.FreeMemory = this.FreeMemory;
+      clone.State = this.State;
+      clone.CalendarSyncStatus = this.CalendarSyncStatus;
+      clone.SlaveConfigId = this.SlaveConfigId;
+      clone.IsAllowedToCalculate = this.IsAllowedToCalculate;
+      return clone;
     }
   }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveConfig.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveConfig.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveConfig.cs	(revision 4629)
@@ -32,4 +32,11 @@
     [DataMember]
     public int? HeartBeatIntervall { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (SlaveConfig)base.Clone(cloner);
+      clone.UpDownTimeCalendar = this.UpDownTimeCalendar;
+      clone.HeartBeatIntervall = this.HeartBeatIntervall;
+      return clone;
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveGroup.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveGroup.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveGroup.cs	(revision 4629)
@@ -23,4 +23,6 @@
 using System.Linq;
 using System.Runtime.Serialization;
+using System;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
@@ -28,8 +30,14 @@
   public class SlaveGroup : Resource {
     [DataMember]
-    public List<Resource> Resources { get; set; }
+    public List<Guid> ResourcesIds { get; set; }
 
     public SlaveGroup() {
-      Resources = new List<Resource>();
+      ResourcesIds = new List<Guid>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (SlaveGroup)base.Clone(cloner);
+      clone.ResourcesIds = new List<Guid>(this.ResourcesIds);
+      return clone;
     }
   }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveState.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveState.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveState.cs	(revision 4629)
@@ -23,5 +23,4 @@
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
   public enum SlaveState {
-    NullState,
     Idle,
     Calculating,
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/UpTimeStatistics.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/UpTimeStatistics.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/UpTimeStatistics.cs	(revision 4629)
@@ -22,4 +22,5 @@
 using System;
 using System.Runtime.Serialization;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
@@ -27,9 +28,17 @@
   public class UpTimeStatistics : HiveItem {
     [DataMember]
-    public Slave Slave { get; set; }
+    public Guid SlaveId { get; set; }
     [DataMember]
     public DateTime Login { get; set; }
     [DataMember]
     public DateTime Logout { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      var clone = (UpTimeStatistics)base.Clone(cloner);
+      clone.SlaveId = this.SlaveId;
+      clone.Login = this.Login;
+      clone.Logout = this.Logout;
+      return clone;
+    }
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/HeuristicLab.Services.Hive.Common-3.3.csproj
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/HeuristicLab.Services.Hive.Common-3.3.csproj	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/HeuristicLab.Services.Hive.Common-3.3.csproj	(revision 4629)
@@ -30,4 +30,10 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
@@ -81,4 +87,7 @@
     <Compile Include="ServiceContracts\IHiveService.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/MessageContainer.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/MessageContainer.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/MessageContainer.cs	(revision 4629)
@@ -43,5 +43,5 @@
       JobFailed, 
       UptimeLimitDisconnect,
-      FetchOrForceFetchCalendar, 
+      UpdateCalendar, 
       AddChildJob,
       PauseJob,
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/ServiceContracts/IHiveService.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/ServiceContracts/IHiveService.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/ServiceContracts/IHiveService.cs	(revision 4629)
@@ -6,10 +6,11 @@
 using System.IO;
 using HeuristicLab.Services.Hive.Common.DataTransfer;
+using System.Net.Security;
 
 namespace HeuristicLab.Services.Hive.Common.ServiceContracts {
+
+  [ServiceContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
   public interface IHiveService {
 
-    // todo: Rename:
-    //  Result is ambiguous; sometimes it refers to a serialized job which has finished, sometimes it is the current state of the job
     #region Job Methods
     [OperationContract]
@@ -81,4 +82,7 @@
 
     #region HiveExperiment Methods
+    [OperationContract]
+    HiveExperiment GetHiveExperiment(Guid id);
+
     /// <summary>
     /// Returns all experiments for the current user
@@ -86,4 +90,7 @@
     [OperationContract]
     IEnumerable<HiveExperiment> GetHiveExperiments();
+
+    [OperationContract]
+    Guid AddHiveExperiment(HiveExperiment hiveExperimentDto);
 
     [OperationContract]
@@ -113,18 +120,18 @@
     /// </summary>
     /// <returns></returns>
-    [OperationContract]
-    void Login();
-    /// <summary>
-    /// This method registers the slave and marks it as online
-    /// </summary>
-    [OperationContract]
-    void Login(Slave slave);
-    [OperationContract]
-    void Logout(Guid clientId);
+    //[OperationContract]
+    //void Login();
+    ///// <summary>
+    ///// This method registers the slave and marks it as online
+    ///// </summary>
+    //[OperationContract]
+    //void Login(Slave slave);
+    //[OperationContract]
+    //void Logout(Guid clientId);
     #endregion
 
     #region Heartbeat Methods
     [OperationContract]
-    List<MessageContainer> ProcessHeartBeat(HeartBeat heartbeat);
+    List<MessageContainer> ProcessHeartbeat(Heartbeat heartbeat);
     #endregion
 
@@ -138,5 +145,5 @@
     #region Calendar Methods
     [OperationContract]
-    IEnumerable<Appointment> GetCalendar(Guid clientId);
+    IEnumerable<Appointment> GetCalendar(Guid slaveId);
     [OperationContract]
     void SetCalendarStatus(Guid clientId, CalendarState state);
@@ -171,4 +178,7 @@
     [OperationContract]
     void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId);
+
+    [OperationContract]
+    void UpdateSlave(Slave slave);
     #endregion
     
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/ContextFactory.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/ContextFactory.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/ContextFactory.cs	(revision 4629)
@@ -75,5 +75,5 @@
           transactions.Add(threadId, transaction);
         }
-        return context;
+        return disposableContext;
       }
     }
@@ -96,5 +96,5 @@
       lock (locker) {
         int threadId = Thread.CurrentThread.ManagedThreadId;
-        contexts[threadId].Dispose();
+        contexts[threadId].Obj.Dispose();
         contexts.Remove(threadId);
         // context gets disposed implicitly, when it is used as IDisposable
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj	(revision 4629)
@@ -30,4 +30,10 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
@@ -75,4 +81,5 @@
       <DependentUpon>Settings.settings</DependentUpon>
     </Compile>
+    <Compile Include="Tools\CreateHiveDatabaseApplication.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -83,4 +90,5 @@
       <SubType>Designer</SubType>
     </None>
+    <None Include="HeuristicLab.snk" />
     <None Include="HiveDataContext.dbml">
       <Generator>MSLinqToSQLGenerator</Generator>
@@ -104,4 +112,8 @@
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <Content Include="Tools\cleanHiveDatabase.sql" />
+    <Content Include="Tools\prepareHiveDatabase.sql" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDao.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDao.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDao.cs	(revision 4629)
@@ -58,5 +58,13 @@
                   orderby ar.Job.Priority descending
                   select Convert.ToDto(ar.Job);
-      return query.ToArray();
+      return query;
+    }
+
+    public IEnumerable<DT.Job> GetAvailableJobs(DT.Slave slave) {
+      var query = from j in db.Jobs
+                  where j.JobState == JobState.Waiting && j.CoresNeeded <= slave.FreeCores && j.MemoryNeeded <= slave.FreeMemory
+                  orderby j.Priority descending
+                  select Convert.ToDto(j);
+      return query.Union(GetAvailableParentJobs(slave.Id)).OrderByDescending(x => x.Priority).ToArray();
     }
     #endregion
@@ -217,6 +225,6 @@
     public bool IsUserAuthorizedForJobs(Guid userId, params Guid[] jobIds) {
       var userIds = from job in db.Jobs // this needs to be fast!
-                 where jobIds.Contains(job.JobId)
-                 select job.UserId;
+                    where jobIds.Contains(job.JobId)
+                    select job.UserId;
       return userIds.All(x => x == userId);
     }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Interfaces/IHiveDao.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Interfaces/IHiveDao.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Interfaces/IHiveDao.cs	(revision 4629)
@@ -15,5 +15,5 @@
     void UpdateJob(DT.Job dto);
     void DeleteJob(Guid id);
-    IEnumerable<DT.Job> GetAvailableParentJobs(Guid slaveId);
+    IEnumerable<DT.Job> GetAvailableJobs(DT.Slave slave);
     #endregion
 
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Tools/CreateHiveDatabaseApplication.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Tools/CreateHiveDatabaseApplication.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Tools/CreateHiveDatabaseApplication.cs	(revision 4629)
@@ -0,0 +1,39 @@
+﻿#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 HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Services.Hive.DataAccess {
+  [Application("Create Hive Database", "Creates new empty Hive Database.", true)]
+  class CreateHiveDatabaseApplication : ApplicationBase {
+
+    public override void Run() {
+      CreateDataContext<HiveDataContext> contextCreator = new CreateDataContext<HiveDataContext>(ContextFactory<HiveDataContext>.CreateHiveContext);
+      IContextFactory<HiveDataContext> contextFactory = new ContextFactory<HiveDataContext>(contextCreator);
+
+      using (contextFactory.GetContext(false)) {
+        if (contextFactory.CurrentContext.DatabaseExists())
+          contextFactory.CurrentContext.DeleteDatabase();
+        contextFactory.CurrentContext.CreateDatabase();
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Tools/cleanHiveDatabase.sql
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Tools/cleanHiveDatabase.sql	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Tools/cleanHiveDatabase.sql	(revision 4629)
@@ -0,0 +1,17 @@
+DELETE FROM [HeuristicLab.Hive].[dbo].AssignedResources
+DELETE FROM [HeuristicLab.Hive].[dbo].RequiredPlugins
+DELETE FROM [HeuristicLab.Hive].[dbo].PluginInfo
+DELETE FROM [HeuristicLab.Hive].[dbo].UptimeStatistics
+DELETE FROM [HeuristicLab.Hive].[dbo].UptimeCalendar
+DELETE FROM [HeuristicLab.Hive].[dbo].SlaveConfig
+DELETE FROM [HeuristicLab.Hive].[dbo].SlaveGroup_Resource
+DELETE FROM [HeuristicLab.Hive].[dbo].[Resource]
+DELETE FROM [HeuristicLab.Hive].[dbo].HiveExperiment
+DELETE FROM [HeuristicLab.Hive].[dbo].Job
+
+/** only jobs & experiments **/
+DELETE FROM [HeuristicLab.Hive].[dbo].AssignedResources
+DELETE FROM [HeuristicLab.Hive].[dbo].RequiredPlugins
+DELETE FROM [HeuristicLab.Hive].[dbo].PluginInfo
+DELETE FROM [HeuristicLab.Hive].[dbo].HiveExperiment
+DELETE FROM [HeuristicLab.Hive].[dbo].Job
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Tools/prepareHiveDatabase.sql
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Tools/prepareHiveDatabase.sql	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Tools/prepareHiveDatabase.sql	(revision 4629)
@@ -0,0 +1,65 @@
+/* this script is supposed to be executed after the plain DB is generated by the linq-to-sql schema */
+
+/*
+use these DROP commands if you want to run this query a second time on the same db */
+/*
+ALTER TABLE dbo.AssignedResources ALTER COLUMN AssignedRessourcesId DROP ROWGUIDCOL;
+ALTER TABLE dbo.Job ALTER COLUMN JobId DROP ROWGUIDCOL;
+ALTER TABLE dbo.SlaveConfig ALTER COLUMN SlaveConfigId DROP ROWGUIDCOL;
+ALTER TABLE dbo.SlaveGroup_Resource ALTER COLUMN SlaveGroup_RessourceId DROP ROWGUIDCOL;
+ALTER TABLE dbo.Plugin ALTER COLUMN PluginId DROP ROWGUIDCOL;
+ALTER TABLE dbo.Project ALTER COLUMN ProjectId DROP ROWGUIDCOL;
+ALTER TABLE dbo.RequiredPlugins ALTER COLUMN RequiredPluginId DROP ROWGUIDCOL;
+ALTER TABLE dbo.Resource ALTER COLUMN ResourceId DROP ROWGUIDCOL;
+ALTER TABLE dbo.UptimeCalendar ALTER COLUMN UptimeCalendarId DROP ROWGUIDCOL;
+ALTER TABLE dbo.UptimeStatistics ALTER COLUMN UptimeStatisticsId DROP ROWGUIDCOL;
+ALTER TABLE dbo.HiveExperiment ALTER COLUMN HiveExperimentId DROP ROWGUIDCOL;
+
+ALTER TABLE dbo.AssignedResources DROP CONSTRAINT [DF_AssignedResources_AssignedRessourcesId];
+ALTER TABLE dbo.Job DROP CONSTRAINT [DF_Job_JobId];
+ALTER TABLE dbo.SlaveConfig DROP CONSTRAINT [DF_SlaveConfig_SlaveConfigId];
+ALTER TABLE dbo.SlaveGroup_Resource DROP CONSTRAINT [DF_SlaveGroup_ResourceSlaveGroup_RessourceId];
+ALTER TABLE dbo.Plugin DROP CONSTRAINT [DF_Plugin_PluginId];
+ALTER TABLE dbo.Project DROP CONSTRAINT [DF_Project_ProjectId];
+ALTER TABLE dbo.RequiredPlugins DROP CONSTRAINT [DF_RequiredPlugins_RequiredPluginId];
+ALTER TABLE dbo.Resource DROP CONSTRAINT [DF_Resource_ResourceId];
+ALTER TABLE dbo.UptimeCalendar DROP CONSTRAINT [DF_UptimeCalendar_UptimeCalendarId];
+ALTER TABLE dbo.UptimeStatistics DROP CONSTRAINT [DF_UptimeStatistics_UptimeStatisticsId];
+ALTER TABLE dbo.HiveExperiment DROP CONSTRAINT [DF_HiveExperiment_HiveExperimentId];
+*/
+
+ALTER TABLE dbo.AssignedResources ALTER COLUMN AssignedRessourcesId ADD ROWGUIDCOL;
+ALTER TABLE dbo.AssignedResources WITH NOCHECK ADD CONSTRAINT [DF_AssignedResources_AssignedRessourcesId] DEFAULT (newid()) FOR AssignedRessourcesId;
+
+ALTER TABLE dbo.Job ALTER COLUMN JobId ADD ROWGUIDCOL;
+ALTER TABLE dbo.Job WITH NOCHECK ADD CONSTRAINT [DF_Job_JobId] DEFAULT (newid()) FOR JobId;
+
+ALTER TABLE dbo.SlaveConfig ALTER COLUMN SlaveConfigId ADD ROWGUIDCOL;
+ALTER TABLE dbo.SlaveConfig WITH NOCHECK ADD CONSTRAINT [DF_SlaveConfig_SlaveConfigId] DEFAULT (newid()) FOR SlaveConfigId;
+
+ALTER TABLE dbo.SlaveGroup_Resource ALTER COLUMN SlaveGroup_RessourceId ADD ROWGUIDCOL;
+ALTER TABLE dbo.SlaveGroup_Resource WITH NOCHECK ADD CONSTRAINT [DF_SlaveGroup_Resource_SlaveGroup_RessourceId] DEFAULT (newid()) FOR SlaveGroup_RessourceId;
+
+ALTER TABLE dbo.Plugin ALTER COLUMN PluginId ADD ROWGUIDCOL;
+ALTER TABLE dbo.Plugin WITH NOCHECK ADD CONSTRAINT [DF_Plugin_PluginId] DEFAULT (newid()) FOR PluginId;
+
+ALTER TABLE dbo.Project ALTER COLUMN ProjectId ADD ROWGUIDCOL;
+ALTER TABLE dbo.Project WITH NOCHECK ADD CONSTRAINT [DF_Project_ProjectId] DEFAULT (newid()) FOR ProjectId;
+
+ALTER TABLE dbo.RequiredPlugins ALTER COLUMN RequiredPluginId ADD ROWGUIDCOL;
+ALTER TABLE dbo.RequiredPlugins WITH NOCHECK ADD CONSTRAINT [DF_RequiredPlugins_RequiredPluginId] DEFAULT (newid()) FOR RequiredPluginId;
+
+ALTER TABLE dbo.Resource ALTER COLUMN ResourceId ADD ROWGUIDCOL;
+ALTER TABLE dbo.Resource WITH NOCHECK ADD CONSTRAINT [DF_Resource_ResourceId] DEFAULT (newid()) FOR ResourceId;
+
+ALTER TABLE dbo.UptimeCalendar ALTER COLUMN UptimeCalendarId ADD ROWGUIDCOL;
+ALTER TABLE dbo.UptimeCalendar WITH NOCHECK ADD CONSTRAINT [DF_UptimeCalendar_UptimeCalendarId] DEFAULT (newid()) FOR UptimeCalendarId;
+
+ALTER TABLE dbo.UptimeStatistics ALTER COLUMN UptimeStatisticsId ADD ROWGUIDCOL;
+ALTER TABLE dbo.UptimeStatistics WITH NOCHECK ADD CONSTRAINT [DF_UptimeStatistics_UptimeStatisticsId] DEFAULT (newid()) FOR UptimeStatisticsId;
+
+ALTER TABLE dbo.HiveExperiment ALTER COLUMN HiveExperimentId ADD ROWGUIDCOL;
+ALTER TABLE dbo.HiveExperiment WITH NOCHECK ADD CONSTRAINT [DF_HiveExperiment_HiveExperimentId] DEFAULT (newid()) FOR HiveExperimentId;
+
+/* create indices */
+CREATE INDEX Index_RequiredPlugins_JobId ON RequiredPlugins(JobId);
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/MergeConfigs.cmd
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/MergeConfigs.cmd	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/MergeConfigs.cmd	(revision 4629)
@@ -1,10 +1,10 @@
-copy "%SolutionDir%HeuristicLab.Hive-3.3.dll.config" "%TargetPath%"
-echo HeuristicLab.Hive-3.3.dll.config copied
+copy "%SolutionDir%HeuristicLab.Hive-3.3.dll.config" "%TargetDir%"
 
-%SolutionDir%ConfigMerger "%SolutionDir%HeuristicLab.Services.Hive\3.3\app.config" "%TargetPath%HeuristicLab.Hive-3.3.dll.config"
-%SolutionDir%ConfigMerger "%SolutionDir%HeuristicLab.Services.Hive.DataAccess\3.3\app.config" "%TargetPath%HeuristicLab.Hive-3.3.dll.config"
+%SolutionDir%ConfigMerger "%SolutionDir%HeuristicLab.Services.Hive\3.3\app.config" "%TargetDir%HeuristicLab.Hive-3.3.dll.config"
+%SolutionDir%ConfigMerger "%SolutionDir%HeuristicLab.Services.Hive.DataAccess\3.3\app.config" "%TargetDir%HeuristicLab.Hive-3.3.dll.config"
 
-copy "%SolutionDir%HeuristicLab-3.3.dll.config" "%TargetPath%"
-echo HeuristicLab-3.3.dll.config copied
+copy "%SolutionDir%HeuristicLab 3.3.exe.config" "%TargetDir%"
 
-%SolutionDir%ConfigMerger "HeuristicLab.Hive-3.3.dll.config" "HeuristicLab 3.3.exe.config"
+%SolutionDir%ConfigMerger "%SolutionDir%HeuristicLab.Hive-3.3.dll.config" "HeuristicLab 3.3.exe.config"
+
+copy "HeuristicLab 3.3.exe.config" "%target%"
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Calendar/3.3/Properties/AssemblyInfo.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Calendar/3.3/Properties/AssemblyInfo.cs	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Calendar/3.3/Properties/AssemblyInfo.cs	(revision 4629)
@@ -58,3 +58,3 @@
 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("3.3.0.0")]
-[assembly: AssemblyFileVersion("3.3.0.4560")]
+[assembly: AssemblyFileVersion("3.3.0.4598")]
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive 3.3.sln
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive 3.3.sln	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive 3.3.sln	(revision 4629)
@@ -81,4 +81,24 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Hive.Slave.ExecutionEngine-3.3", "HeuristicLab.Hive.Slave.ExecutionEngine\3.3\HeuristicLab.Hive.Slave.ExecutionEngine-3.3.csproj", "{1605256A-1CB3-44AB-AAFF-577093EE5789}"
+EndProject
+Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "HiveWeb", "..\..\..\..\..\Web\HiveWeb\", "{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}"
+	ProjectSection(WebsiteProperties) = preProject
+		TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0"
+		Debug.AspNetCompiler.VirtualPath = "/HiveWeb"
+		Debug.AspNetCompiler.PhysicalPath = "..\..\..\..\..\Web\HiveWeb\"
+		Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\HiveWeb\"
+		Debug.AspNetCompiler.Updateable = "true"
+		Debug.AspNetCompiler.ForceOverwrite = "true"
+		Debug.AspNetCompiler.FixedNames = "false"
+		Debug.AspNetCompiler.Debug = "True"
+		Release.AspNetCompiler.VirtualPath = "/HiveWeb"
+		Release.AspNetCompiler.PhysicalPath = "..\..\..\..\..\Web\HiveWeb\"
+		Release.AspNetCompiler.TargetPath = "PrecompiledWeb\HiveWeb\"
+		Release.AspNetCompiler.Updateable = "true"
+		Release.AspNetCompiler.ForceOverwrite = "true"
+		Release.AspNetCompiler.FixedNames = "false"
+		Release.AspNetCompiler.Debug = "False"
+		VWDPort = "2681"
+	EndProjectSection
 EndProject
 Global
@@ -372,4 +392,16 @@
 		{1605256A-1CB3-44AB-AAFF-577093EE5789}.Release|x86.ActiveCfg = Release|x86
 		{1605256A-1CB3-44AB-AAFF-577093EE5789}.Release|x86.Build.0 = Release|x86
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Release|Any CPU.ActiveCfg = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Release|Any CPU.Build.0 = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Release|x64.ActiveCfg = Debug|Any CPU
+		{F8E2A0BB-5B04-49EE-88CE-F0DF12474221}.Release|x86.ActiveCfg = Debug|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Core/3.3/HeuristicLab.Hive.Server.Core-3.3.csproj
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Core/3.3/HeuristicLab.Hive.Server.Core-3.3.csproj	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Core/3.3/HeuristicLab.Hive.Server.Core-3.3.csproj	(revision 4629)
@@ -192,3 +192,7 @@
 call PreBuildEvent.cmd</PreBuildEvent>
   </PropertyGroup>
+  <PropertyGroup>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
 </Project>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Core/3.3/app.config
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Core/3.3/app.config	(revision 4624)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Core/3.3/app.config	(revision 4629)
@@ -63,5 +63,4 @@
 
   <system.serviceModel>
-
     <diagnostics>
       <messageLogging logEntireMessage="true" logMalformedMessages="true"
@@ -141,5 +140,4 @@
       </service>
     </services>
-
   </system.serviceModel>
 
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/App_Code/HiveServerModule.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/App_Code/HiveServerModule.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/App_Code/HiveServerModule.cs	(revision 4629)
@@ -0,0 +1,41 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Web;
+using System.Threading;
+using HeuristicLab.Tracing;
+using System.IO;
+
+namespace HeuristicLab.Hive.Server.Core.IISModules {
+  public class HiveServerModule : IHttpModule {
+    Thread t;
+
+    #region IHttpModule Members
+
+    public void Dispose() {
+      if (t != null && t.ThreadState == ThreadState.Running) {
+        t.Abort();
+      }
+      File.Create(@"C:\ch\stuff\Log\Dispose" + Thread.CurrentThread.ManagedThreadId).Dispose();
+    }
+
+    public void Init(HttpApplication context) {
+
+      File.Create(@"C:\ch\stuff\Log\Init." + Thread.CurrentThread.ManagedThreadId).Dispose();
+      t = new Thread(DoSomething);
+      t.Start();
+    }
+
+    private void DoSomething() {
+      int i = 0;
+      while (true) {
+        Thread.Sleep(1000);
+        File.Create(@"C:\ch\stuff\Log\file" + Thread.CurrentThread.ManagedThreadId + "." + i).Dispose();
+        i++;
+      }
+    }
+
+    #endregion
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/ClientService.svc
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/ClientService.svc	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/ClientService.svc	(revision 4629)
@@ -0,0 +1,5 @@
+﻿<%@ ServiceHost 
+  Language="C#" 
+  Debug="true" 
+  Service="HeuristicLab.Hive.Server.Core.ClientFacade" 
+  %>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/HeuristicLab.log4net.xml
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/HeuristicLab.log4net.xml	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/HeuristicLab.log4net.xml	(revision 4629)
@@ -0,0 +1,30 @@
+﻿<log4net>
+  
+  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
+    <file value="HeuristicLab.log" />
+    <appendToFile value="true" />
+    <rollingStyle value="Size" />
+    <maxSizeRollBackups value="10" />
+    <maximumFileSize value="100KB" />
+    <staticLogFileName value="true" />
+    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
+    <layout type="log4net.Layout.PatternLayout">
+      <conversionPattern value="%-4timestamp [%appdomain/%thread] %-5level %logger %ndc - %message%newline%exception" />
+    </layout>
+  </appender>
+  
+  <appender name="BufferingForwardingAppender" type="log4net.Appender.BufferingForwardingAppender" >
+    <bufferSize value="128" />
+    <lossy value="true" />
+    <evaluator type="log4net.Core.LevelEvaluator">
+        <threshold value="INFO"/>
+    </evaluator>
+    <appender-ref ref="RollingFileAppender" />
+  </appender>
+  
+  <root>
+    <level value="INFO" />
+    <appender-ref ref="BufferingForwardingAppender" />
+  </root>
+  
+</log4net>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/ServerConsoleService.svc
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/ServerConsoleService.svc	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/ServerConsoleService.svc	(revision 4629)
@@ -0,0 +1,5 @@
+﻿<%@ ServiceHost 
+  Language="C#" 
+  Debug="true" 
+  Service="HeuristicLab.Hive.Server.Core.ServerConsoleFacade" 
+  %>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/SlaveService.svc
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/SlaveService.svc	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/SlaveService.svc	(revision 4629)
@@ -0,0 +1,5 @@
+﻿<%@ ServiceHost 
+  Language="C#" 
+  Debug="true" 
+  Service="HeuristicLab.Hive.Server.Core.SlaveFacade" 
+  %>
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/Web.config
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/Web.config	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HiveWeb/Web.config	(revision 4629)
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+  <configSections>
+    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+      <section name="HeuristicLab.Tracing.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+    </sectionGroup>
+  </configSections>
+
+  <applicationSettings>
+    <HeuristicLab.Tracing.Properties.Settings>
+      <setting name="TracingLog4netConfigFile" serializeAs="String">
+        <value />
+      </setting>
+    </HeuristicLab.Tracing.Properties.Settings>
+  </applicationSettings>
+  
+  <connectionStrings>
+    <add name="HeuristicLab.Authentication"
+         connectionString="data source=localhost;Integrated Security=SSPI;Initial Catalog=HeuristicLab.Authentication"/>
+  </connectionStrings>
+
+  <system.web>
+
+    <compilation debug="true" targetFramework="4.0" />
+
+    <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>
+    <diagnostics>
+      <messageLogging logEntireMessage="true" logMalformedMessages="true"
+        logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"
+        maxMessagesToLog="3000" />
+    </diagnostics>
+    <bindings>
+      <netTcpBinding>
+        <binding name="TcpStreamedBinding" sendTimeout="00:10:00" transferMode="Streamed"
+          maxBufferPoolSize="104857600" maxBufferSize="104857600"
+          maxReceivedMessageSize="104857600" maxConnections="50">
+          <readerQuotas maxStringContentLength="104857600" maxArrayLength="104857600" />
+          <security mode="TransportWithMessageCredential">
+            <transport clientCredentialType="Certificate"/>
+            <message clientCredentialType="UserName" />
+          </security>
+        </binding>
+      </netTcpBinding>
+      <wsHttpBinding>
+        <binding name="HiveServerHttpBinding">
+          <security mode="Message">
+            <transport/>
+            <message clientCredentialType="UserName" />
+          </security>
+        </binding>
+      </wsHttpBinding>
+    </bindings>
+    <behaviors>
+      <serviceBehaviors>
+        <behavior name="ServiceBehaviour">
+          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
+          <serviceDebug includeExceptionDetailInFaults="true" />
+          <serviceAuthorization principalPermissionMode="UseAspNetRoles"
+            roleProviderName="AspNetSqlRoleProvider" />
+          <serviceCredentials>
+            <serviceCertificate findValue="localhost" x509FindType="FindBySubjectName" />
+            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
+              membershipProviderName="AspNetSqlMembershipProvider" />
+          </serviceCredentials>
+          <serviceSecurityAudit auditLogLocation="Application" suppressAuditFailure="false"
+            messageAuthenticationAuditLevel="SuccessOrFailure" />
+          <serviceThrottling maxConcurrentCalls="100"/>
+        </behavior>
+      </serviceBehaviors>
+    </behaviors>
+    <services>
+      <service behaviorConfiguration="ServiceBehaviour" name="HeuristicLab.Hive.Server.Core.SlaveFacade">
+        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="HiveServerHttpBinding" name="SlaveHttpEndpoint" contract="HeuristicLab.Hive.Contracts.Interfaces.ISlaveFacade" />
+        <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" name="SlaveMexEndpoint" contract="IMetadataExchange" />
+        <!--<endpoint binding="netTcpBinding" bindingConfiguration="TcpStreamedBinding" name="SlaveTcpStreamedEndpoint" contract="HeuristicLab.Hive.Contracts.Interfaces.ISlaveFacade" />-->
+        <host>
+          <baseAddresses>
+            <add baseAddress="http://localhost:9000/SlaveService" />
+            <!--<add baseAddress="net.tcp://localhost:9001/SlaveServiceStreamed" />-->
+          </baseAddresses>
+        </host>
+      </service>
+      <service behaviorConfiguration="ServiceBehaviour" name="HeuristicLab.Hive.Server.Core.ServerConsoleFacade">
+        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="HiveServerHttpBinding" name="ServerConsoleHttpEndpoint" contract="HeuristicLab.Hive.Contracts.Interfaces.IServerConsoleFacade" />
+        <endpoint address="mex" binding="mexHttpBinding" name="ServerConsoleMexEndpoint" contract="IMetadataExchange" />
+        <host>
+          <baseAddresses>
+            <add baseAddress="http://localhost:9000/ServerConsoleService" />
+          </baseAddresses>
+        </host>
+      </service>
+      <service behaviorConfiguration="ServiceBehaviour" name="HeuristicLab.Hive.Server.Core.ClientFacade">
+        <!--<endpoint address="" binding="netTcpBinding" bindingConfiguration="TcpStreamedBinding" name="ClientTcpStreamedEndpoint" contract="HeuristicLab.Hive.Contracts.Interfaces.IClientFacade" />-->
+        <endpoint binding="wsHttpBinding" bindingConfiguration="HiveServerHttpBinding" name="ClientHttpEndpoint" contract="HeuristicLab.Hive.Contracts.Interfaces.IClientFacade" />
+        <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" name="ClientHttpMexEndpoint" contract="IMetadataExchange" />
+        <host>
+          <baseAddresses>
+            <!--<add baseAddress="net.tcp://localhost:9001/ClientServiceStreamed" />-->
+            <add baseAddress="http://localhost:9000/ClientService" />
+          </baseAddresses>
+        </host>
+      </service>
+    </services>
+  </system.serviceModel>
+
+
+  <system.webServer>
+    <modules runAllManagedModulesForAllRequests="true">
+      <add name="HiveServerModule" type="HeuristicLab.Hive.Server.Core.IISModules.HiveServerModule" />
+    </modules>
+    <directoryBrowse enabled="true" />
+  </system.webServer>
+
+</configuration>
