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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HeuristicLab.Clients.Hive-3.3.csproj	(revision 4649)
@@ -76,12 +76,9 @@
     <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\HiveJobClient.cs" />
+    <Compile Include="HiveExperiment\HiveExperimentClient.cs" />
     <Compile Include="HiveExperiment\JobResultPoller.cs" />
     <Compile Include="Progress\IProgress.cs" />
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 4649)
@@ -38,11 +38,6 @@
     private bool currentlyUpdating;
 
-    private ILog log;
-    public ILog Log {
-      get { return log; }
-    }
-
-    private HiveExperimentList hiveExperiments;
-    public HiveExperimentList HiveExperiments {
+    private ItemList<HiveExperimentClient> hiveExperiments;
+    public ItemList<HiveExperimentClient> HiveExperiments {
       get { return hiveExperiments; }
       set {
@@ -74,5 +69,5 @@
     private void RegisterHiveExperimentsEvent() {
       if (hiveExperiments != null) {
-        hiveExperiments.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveExperiment>>(hiveExperiments_ItemsRemoved);
+        hiveExperiments.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<HiveExperimentClient>>(hiveExperiments_ItemsRemoved);
       }
     }
@@ -80,16 +75,15 @@
     private void DeRegisterHiveExperimentsEvents() {
       if (hiveExperiments != null) {
-        hiveExperiments.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveExperiment>>(hiveExperiments_ItemsRemoved);
+        hiveExperiments.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<HiveExperimentClient>>(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);
+      clone.hiveExperiments = (ItemList<HiveExperimentClient>)cloner.Clone(this.hiveExperiments);
       return clone;
     }
@@ -100,5 +94,5 @@
         IsProgressing = true;
         if (this.HiveExperiments == null) {
-          this.HiveExperiments = new HiveExperimentList();
+          this.HiveExperiments = new ItemList<HiveExperimentClient>();
         }
         using (var service = ServiceLocator.Instance.ServicePool.GetService()) {
@@ -121,8 +115,8 @@
     private void RefreshExperimentList(IEnumerable<DT.HiveExperiment> hiveExperiments) {
       foreach (DT.HiveExperiment hiveExperimentDto in hiveExperiments) {
-        DT.HiveExperiment hiveExperiment = GetHiveExperiment(hiveExperimentDto.Id);
+        HiveExperimentClient hiveExperiment = GetHiveExperiment(hiveExperimentDto.Id);
         if (hiveExperiment == null) {
           // not yet there, create new
-          this.HiveExperiments.Add(new HiveExperiment(hiveExperimentDto));
+          this.HiveExperiments.Add(new HiveExperimentClient(hiveExperimentDto));
         } else {
           // update
@@ -132,13 +126,6 @@
     }
 
-    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);
-      }
+    private HiveExperimentClient GetHiveExperiment(Guid hiveExperimentId) {
+      return this.HiveExperiments.SingleOrDefault(he => he.HiveExperimentId.Equals(hiveExperimentId));
     }
 
@@ -149,8 +136,8 @@
     }
     
-    void hiveExperiments_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<Collections.IndexedItem<HiveExperiment>> e) {
+    void hiveExperiments_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<Collections.IndexedItem<HiveExperimentClient>> e) {
       if (!currentlyUpdating) {
         using (Disposable<IHiveService> service = ServiceLocator.Instance.ServicePool.GetService()) {
-          foreach (IndexedItem<HiveExperiment> item in e.Items) {
+          foreach (IndexedItem<HiveExperimentClient> item in e.Items) {
             if (item.Value.HiveExperimentId != Guid.Empty) {
               service.Obj.DeleteHiveExperiment(item.Value.HiveExperimentId);
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)
+++ 	(revision )
@@ -1,609 +1,0 @@
-﻿#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/HiveExperimentClient.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveExperimentClient.cs	(revision 4649)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveExperimentClient.cs	(revision 4649)
@@ -0,0 +1,610 @@
+﻿#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 HiveExperimentClient : 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 HiveExperimentClient()
+      : base(itemName, itemDescription) {
+      //this.ResourceIds = HeuristicLab.Hive.Experiment.Properties.Settings.Default.ResourceIds;
+      this.ResourceIds = "MyGroup";
+      this.log = new Log();
+      InitTimer();
+    }
+
+    public HiveExperimentClient(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");
+      HiveExperimentClient clone = (HiveExperimentClient)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.JobState = JobState.WaitingForChildJobs;
+        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;
+
+      if (parentHiveJob != null) {
+        //response = service.AddChildJob(parentHiveJob.Job.Id, serializedJob);
+        hiveJob.Job.Id = service.AddChildJob(parentHiveJob.Job.Id, hiveJob.Job, serializedJob);
+      } else {
+        // response = service.AddJobWithGroupStrings(serializedJob, groups);
+        hiveJob.Job.Id = service.AddJob(hiveJob.Job, serializedJob);
+      }
+
+      LogMessage(hiveJob.Job.Id, "Job sent to Hive");
+
+      foreach (HiveJob child in hiveJob.ChildHiveJobs) {
+        UploadJobWithChildren(service, child, hiveJob, groups, ref jobCount, totalJobCount);
+      }
+    }
+
+    /// <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.JobState == JobState.Aborted ||
+               hj.Job.JobState == JobState.Failed ||
+               hj.Job.JobState == 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, Job> allJobs = new Dictionary<Guid, Job>();
+          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);
+            allJobs.Add(lightweightJob.Id, service.Obj.GetJob(lightweightJob.Id));
+            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(allJobs[this.rootJobId.Value], allSerializedJobs[this.rootJobId.Value], false);
+          allSerializedJobs.Remove(this.rootJobId.Value); // reduce memory footprint
+          allJobs.Remove(this.rootJobId.Value);
+          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, allJobs, 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, Job> allJobs, 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 = allJobs[lightweightJob.Id];
+        allSerializedJobs.Remove(lightweightJob.Id); // reduce memory footprint
+        allJobs.Remove(lightweightJob.Id);
+        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, allJobs, 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)
+++ 	(revision )
@@ -1,42 +1,0 @@
-﻿#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)
+++ 	(revision )
@@ -1,563 +1,0 @@
-﻿#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/HiveJobClient.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJobClient.cs	(revision 4649)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/HiveExperiment/HiveJobClient.cs	(revision 4649)
@@ -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.JobState == JobState.Waiting) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
+          else if (job.JobState == JobState.WaitingForChildJobs) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutablePrepared;
+          else if (job.JobState == JobState.Calculating) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStarted;
+          else if (job.JobState == JobState.Aborted) return HeuristicLab.Common.Resources.VS2008ImageLibrary.ExecutableStopped;
+          else if (job.JobState == JobState.Failed) return HeuristicLab.Common.Resources.VS2008ImageLibrary.Error;
+          else if (job.JobState == 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 ItemList<HiveJob> 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() {
+        JobState = JobState.Waiting,
+        DateCreated = DateTime.Now,
+        CoresNeeded = 1,
+        MemoryNeeded = 0
+      };
+      this.childHiveJobs = new ItemList<HiveJob>();
+      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(Job job, JobData serializedJob, bool autoCreateChildHiveJobs)
+      : this() {
+      this.syncJobsWithOptimizers = autoCreateChildHiveJobs;
+      this.Job = job;
+      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.JobState = lightweightJob.JobState;
+        // 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.JobState + ", 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)
+++ 	(revision )
@@ -1,40 +1,0 @@
-﻿#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/Jobs/JobList.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/Jobs/JobList.cs	(revision 4629)
+++ 	(revision )
@@ -1,41 +1,0 @@
-﻿#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/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 4649)
@@ -7,11 +7,10 @@
 
 svcutil.exe ^
-  http://localhost:9001/HiveService/mex ^
+  http://localhost:9000/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
+  /config:..\app.config 
 
 echo.
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/HiveServiceClient.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/HiveServiceClient.cs	(revision 4649)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Clients.Hive/3.3/ServiceClients/HiveServiceClient.cs	(revision 4649)
@@ -0,0 +1,1621 @@
+﻿//------------------------------------------------------------------------------
+// <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
+{
+    using System.Runtime.Serialization;
+    
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="HiveItem", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.JobData))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.NamedHiveItem))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.HiveExperiment))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Project))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.HivePlugin))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.HivePluginData))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Resource))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.SlaveGroup))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Slave))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Appointment))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.LightweightJob))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Job))]
+    public partial class HiveItem : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
+    {
+        
+        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
+        
+        private System.Guid IdField;
+        
+        public System.Runtime.Serialization.ExtensionDataObject ExtensionData
+        {
+            get
+            {
+                return this.extensionDataField;
+            }
+            set
+            {
+                this.extensionDataField = value;
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid Id
+        {
+            get
+            {
+                return this.IdField;
+            }
+            set
+            {
+                if ((this.IdField.Equals(value) != true))
+                {
+                    this.IdField = value;
+                    this.RaisePropertyChanged("Id");
+                }
+            }
+        }
+        
+        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
+        
+        protected void RaisePropertyChanged(string propertyName)
+        {
+            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
+            if ((propertyChanged != null))
+            {
+                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="JobData", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class JobData : HeuristicLab.Clients.Hive.HiveItem
+    {
+        
+        private byte[] DataField;
+        
+        private System.Guid JobIdField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public byte[] Data
+        {
+            get
+            {
+                return this.DataField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.DataField, value) != true))
+                {
+                    this.DataField = value;
+                    this.RaisePropertyChanged("Data");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid JobId
+        {
+            get
+            {
+                return this.JobIdField;
+            }
+            set
+            {
+                if ((this.JobIdField.Equals(value) != true))
+                {
+                    this.JobIdField = value;
+                    this.RaisePropertyChanged("JobId");
+                }
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="NamedHiveItem", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.HiveExperiment))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Project))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.HivePlugin))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.HivePluginData))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Resource))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.SlaveGroup))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Slave))]
+    public partial class NamedHiveItem : HeuristicLab.Clients.Hive.HiveItem
+    {
+        
+        private string DescriptionField;
+        
+        private string NameField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public string Description
+        {
+            get
+            {
+                return this.DescriptionField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.DescriptionField, value) != true))
+                {
+                    this.DescriptionField = value;
+                    this.RaisePropertyChanged("Description");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public string Name
+        {
+            get
+            {
+                return this.NameField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.NameField, value) != true))
+                {
+                    this.NameField = value;
+                    this.RaisePropertyChanged("Name");
+                }
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="HiveExperiment", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class HiveExperiment : HeuristicLab.Clients.Hive.NamedHiveItem
+    {
+        
+        private string ResourceIdsField;
+        
+        private System.Nullable<System.Guid> RootJobIdField;
+        
+        private System.Guid UserIdField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public string ResourceIds
+        {
+            get
+            {
+                return this.ResourceIdsField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.ResourceIdsField, value) != true))
+                {
+                    this.ResourceIdsField = value;
+                    this.RaisePropertyChanged("ResourceIds");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<System.Guid> RootJobId
+        {
+            get
+            {
+                return this.RootJobIdField;
+            }
+            set
+            {
+                if ((this.RootJobIdField.Equals(value) != true))
+                {
+                    this.RootJobIdField = value;
+                    this.RaisePropertyChanged("RootJobId");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid UserId
+        {
+            get
+            {
+                return this.UserIdField;
+            }
+            set
+            {
+                if ((this.UserIdField.Equals(value) != true))
+                {
+                    this.UserIdField = value;
+                    this.RaisePropertyChanged("UserId");
+                }
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="Project", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class Project : HeuristicLab.Clients.Hive.NamedHiveItem
+    {
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="HivePlugin", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class HivePlugin : HeuristicLab.Clients.Hive.NamedHiveItem
+    {
+        
+        private bool UpdateField;
+        
+        private System.Version VersionField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public bool Update
+        {
+            get
+            {
+                return this.UpdateField;
+            }
+            set
+            {
+                if ((this.UpdateField.Equals(value) != true))
+                {
+                    this.UpdateField = value;
+                    this.RaisePropertyChanged("Update");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Version Version
+        {
+            get
+            {
+                return this.VersionField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.VersionField, value) != true))
+                {
+                    this.VersionField = value;
+                    this.RaisePropertyChanged("Version");
+                }
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="HivePluginData", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class HivePluginData : HeuristicLab.Clients.Hive.NamedHiveItem
+    {
+        
+        private byte[] DataField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public byte[] Data
+        {
+            get
+            {
+                return this.DataField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.DataField, value) != true))
+                {
+                    this.DataField = value;
+                    this.RaisePropertyChanged("Data");
+                }
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="Resource", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.SlaveGroup))]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Slave))]
+    public partial class Resource : HeuristicLab.Clients.Hive.NamedHiveItem
+    {
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="SlaveGroup", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class SlaveGroup : HeuristicLab.Clients.Hive.Resource
+    {
+        
+        private System.Guid[] ResourcesIdsField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid[] ResourcesIds
+        {
+            get
+            {
+                return this.ResourcesIdsField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.ResourcesIdsField, value) != true))
+                {
+                    this.ResourcesIdsField = value;
+                    this.RaisePropertyChanged("ResourcesIds");
+                }
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="Slave", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class Slave : HeuristicLab.Clients.Hive.Resource
+    {
+        
+        private HeuristicLab.Clients.Hive.CalendarState CalendarSyncStatusField;
+        
+        private System.Nullable<int> CoresField;
+        
+        private System.Nullable<int> CpuSpeedPerCoreField;
+        
+        private System.Nullable<int> FreeCoresField;
+        
+        private System.Nullable<int> FreeMemoryField;
+        
+        private bool IsAllowedToCalculateField;
+        
+        private System.Nullable<int> MemoryField;
+        
+        private System.Guid SlaveConfigIdField;
+        
+        private HeuristicLab.Clients.Hive.SlaveState StateField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public HeuristicLab.Clients.Hive.CalendarState CalendarSyncStatus
+        {
+            get
+            {
+                return this.CalendarSyncStatusField;
+            }
+            set
+            {
+                if ((this.CalendarSyncStatusField.Equals(value) != true))
+                {
+                    this.CalendarSyncStatusField = value;
+                    this.RaisePropertyChanged("CalendarSyncStatus");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<int> Cores
+        {
+            get
+            {
+                return this.CoresField;
+            }
+            set
+            {
+                if ((this.CoresField.Equals(value) != true))
+                {
+                    this.CoresField = value;
+                    this.RaisePropertyChanged("Cores");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<int> CpuSpeedPerCore
+        {
+            get
+            {
+                return this.CpuSpeedPerCoreField;
+            }
+            set
+            {
+                if ((this.CpuSpeedPerCoreField.Equals(value) != true))
+                {
+                    this.CpuSpeedPerCoreField = value;
+                    this.RaisePropertyChanged("CpuSpeedPerCore");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<int> FreeCores
+        {
+            get
+            {
+                return this.FreeCoresField;
+            }
+            set
+            {
+                if ((this.FreeCoresField.Equals(value) != true))
+                {
+                    this.FreeCoresField = value;
+                    this.RaisePropertyChanged("FreeCores");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<int> FreeMemory
+        {
+            get
+            {
+                return this.FreeMemoryField;
+            }
+            set
+            {
+                if ((this.FreeMemoryField.Equals(value) != true))
+                {
+                    this.FreeMemoryField = value;
+                    this.RaisePropertyChanged("FreeMemory");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public bool IsAllowedToCalculate
+        {
+            get
+            {
+                return this.IsAllowedToCalculateField;
+            }
+            set
+            {
+                if ((this.IsAllowedToCalculateField.Equals(value) != true))
+                {
+                    this.IsAllowedToCalculateField = value;
+                    this.RaisePropertyChanged("IsAllowedToCalculate");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<int> Memory
+        {
+            get
+            {
+                return this.MemoryField;
+            }
+            set
+            {
+                if ((this.MemoryField.Equals(value) != true))
+                {
+                    this.MemoryField = value;
+                    this.RaisePropertyChanged("Memory");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid SlaveConfigId
+        {
+            get
+            {
+                return this.SlaveConfigIdField;
+            }
+            set
+            {
+                if ((this.SlaveConfigIdField.Equals(value) != true))
+                {
+                    this.SlaveConfigIdField = value;
+                    this.RaisePropertyChanged("SlaveConfigId");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public HeuristicLab.Clients.Hive.SlaveState State
+        {
+            get
+            {
+                return this.StateField;
+            }
+            set
+            {
+                if ((this.StateField.Equals(value) != true))
+                {
+                    this.StateField = value;
+                    this.RaisePropertyChanged("State");
+                }
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="Appointment", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class Appointment : HeuristicLab.Clients.Hive.HiveItem
+    {
+        
+        private bool AllDayEventField;
+        
+        private System.DateTime EndDateField;
+        
+        private bool RecurringField;
+        
+        private System.Guid RecurringIdField;
+        
+        private System.Guid ResourceIdField;
+        
+        private System.DateTime StartDateField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public bool AllDayEvent
+        {
+            get
+            {
+                return this.AllDayEventField;
+            }
+            set
+            {
+                if ((this.AllDayEventField.Equals(value) != true))
+                {
+                    this.AllDayEventField = value;
+                    this.RaisePropertyChanged("AllDayEvent");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.DateTime EndDate
+        {
+            get
+            {
+                return this.EndDateField;
+            }
+            set
+            {
+                if ((this.EndDateField.Equals(value) != true))
+                {
+                    this.EndDateField = value;
+                    this.RaisePropertyChanged("EndDate");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public bool Recurring
+        {
+            get
+            {
+                return this.RecurringField;
+            }
+            set
+            {
+                if ((this.RecurringField.Equals(value) != true))
+                {
+                    this.RecurringField = value;
+                    this.RaisePropertyChanged("Recurring");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid RecurringId
+        {
+            get
+            {
+                return this.RecurringIdField;
+            }
+            set
+            {
+                if ((this.RecurringIdField.Equals(value) != true))
+                {
+                    this.RecurringIdField = value;
+                    this.RaisePropertyChanged("RecurringId");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid ResourceId
+        {
+            get
+            {
+                return this.ResourceIdField;
+            }
+            set
+            {
+                if ((this.ResourceIdField.Equals(value) != true))
+                {
+                    this.ResourceIdField = value;
+                    this.RaisePropertyChanged("ResourceId");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.DateTime StartDate
+        {
+            get
+            {
+                return this.StartDateField;
+            }
+            set
+            {
+                if ((this.StartDateField.Equals(value) != true))
+                {
+                    this.StartDateField = value;
+                    this.RaisePropertyChanged("StartDate");
+                }
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="LightweightJob", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    [System.Runtime.Serialization.KnownTypeAttribute(typeof(HeuristicLab.Clients.Hive.Job))]
+    public partial class LightweightJob : HeuristicLab.Clients.Hive.HiveItem
+    {
+        
+        private System.Nullable<System.DateTime> DateCalculatedField;
+        
+        private System.Nullable<System.DateTime> DateCreatedField;
+        
+        private System.Nullable<System.DateTime> DateFinishedField;
+        
+        private string ExceptionField;
+        
+        private System.TimeSpan ExecutionTimeField;
+        
+        private System.Nullable<System.Guid> ParentJobIdField;
+        
+        private System.Guid SlaveIdField;
+        
+        private HeuristicLab.Clients.Hive.JobState StateField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<System.DateTime> DateCalculated
+        {
+            get
+            {
+                return this.DateCalculatedField;
+            }
+            set
+            {
+                if ((this.DateCalculatedField.Equals(value) != true))
+                {
+                    this.DateCalculatedField = value;
+                    this.RaisePropertyChanged("DateCalculated");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<System.DateTime> DateCreated
+        {
+            get
+            {
+                return this.DateCreatedField;
+            }
+            set
+            {
+                if ((this.DateCreatedField.Equals(value) != true))
+                {
+                    this.DateCreatedField = value;
+                    this.RaisePropertyChanged("DateCreated");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<System.DateTime> DateFinished
+        {
+            get
+            {
+                return this.DateFinishedField;
+            }
+            set
+            {
+                if ((this.DateFinishedField.Equals(value) != true))
+                {
+                    this.DateFinishedField = value;
+                    this.RaisePropertyChanged("DateFinished");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public string Exception
+        {
+            get
+            {
+                return this.ExceptionField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.ExceptionField, value) != true))
+                {
+                    this.ExceptionField = value;
+                    this.RaisePropertyChanged("Exception");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.TimeSpan ExecutionTime
+        {
+            get
+            {
+                return this.ExecutionTimeField;
+            }
+            set
+            {
+                if ((this.ExecutionTimeField.Equals(value) != true))
+                {
+                    this.ExecutionTimeField = value;
+                    this.RaisePropertyChanged("ExecutionTime");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Nullable<System.Guid> ParentJobId
+        {
+            get
+            {
+                return this.ParentJobIdField;
+            }
+            set
+            {
+                if ((this.ParentJobIdField.Equals(value) != true))
+                {
+                    this.ParentJobIdField = value;
+                    this.RaisePropertyChanged("ParentJobId");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid SlaveId
+        {
+            get
+            {
+                return this.SlaveIdField;
+            }
+            set
+            {
+                if ((this.SlaveIdField.Equals(value) != true))
+                {
+                    this.SlaveIdField = value;
+                    this.RaisePropertyChanged("SlaveId");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public HeuristicLab.Clients.Hive.JobState State
+        {
+            get
+            {
+                return this.StateField;
+            }
+            set
+            {
+                if ((this.StateField.Equals(value) != true))
+                {
+                    this.StateField = value;
+                    this.RaisePropertyChanged("State");
+                }
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="Job", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class Job : HeuristicLab.Clients.Hive.LightweightJob
+    {
+        
+        private System.Guid[] AssignedResourceIdsField;
+        
+        private int CoresNeededField;
+        
+        private int MemoryNeededField;
+        
+        private System.Guid[] PluginsNeededIdsField;
+        
+        private int PriorityField;
+        
+        private System.Guid ProjectIdField;
+        
+        private System.Guid UserIdField;
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid[] AssignedResourceIds
+        {
+            get
+            {
+                return this.AssignedResourceIdsField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.AssignedResourceIdsField, value) != true))
+                {
+                    this.AssignedResourceIdsField = value;
+                    this.RaisePropertyChanged("AssignedResourceIds");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public int CoresNeeded
+        {
+            get
+            {
+                return this.CoresNeededField;
+            }
+            set
+            {
+                if ((this.CoresNeededField.Equals(value) != true))
+                {
+                    this.CoresNeededField = value;
+                    this.RaisePropertyChanged("CoresNeeded");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public int MemoryNeeded
+        {
+            get
+            {
+                return this.MemoryNeededField;
+            }
+            set
+            {
+                if ((this.MemoryNeededField.Equals(value) != true))
+                {
+                    this.MemoryNeededField = value;
+                    this.RaisePropertyChanged("MemoryNeeded");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid[] PluginsNeededIds
+        {
+            get
+            {
+                return this.PluginsNeededIdsField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.PluginsNeededIdsField, value) != true))
+                {
+                    this.PluginsNeededIdsField = value;
+                    this.RaisePropertyChanged("PluginsNeededIds");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public int Priority
+        {
+            get
+            {
+                return this.PriorityField;
+            }
+            set
+            {
+                if ((this.PriorityField.Equals(value) != true))
+                {
+                    this.PriorityField = value;
+                    this.RaisePropertyChanged("Priority");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid ProjectId
+        {
+            get
+            {
+                return this.ProjectIdField;
+            }
+            set
+            {
+                if ((this.ProjectIdField.Equals(value) != true))
+                {
+                    this.ProjectIdField = value;
+                    this.RaisePropertyChanged("ProjectId");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid UserId
+        {
+            get
+            {
+                return this.UserIdField;
+            }
+            set
+            {
+                if ((this.UserIdField.Equals(value) != true))
+                {
+                    this.UserIdField = value;
+                    this.RaisePropertyChanged("UserId");
+                }
+            }
+        }
+    }
+    
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="JobState", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public enum JobState : int
+    {
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Calculating = 0,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Waiting = 1,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Finished = 2,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Aborted = 3,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Failed = 4,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        WaitForChildJobs = 5,
+    }
+    
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="CalendarState", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public enum CalendarState : int
+    {
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Fetch = 0,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        ForceFetch = 1,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Fetching = 2,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Fetched = 3,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        NotAllowedToFetch = 4,
+    }
+    
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="SlaveState", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public enum SlaveState : int
+    {
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Idle = 0,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Calculating = 1,
+        
+        [System.Runtime.Serialization.EnumMemberAttribute()]
+        Offline = 2,
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="Heartbeat", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common.DataTra" +
+        "nsfer")]
+    public partial class Heartbeat : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
+    {
+        
+        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
+        
+        private int FreeCoresField;
+        
+        private int FreeMemoryField;
+        
+        private bool IsAllowedToCalculateField;
+        
+        private System.Collections.Generic.Dictionary<System.Guid, System.TimeSpan> JobProgressField;
+        
+        private System.Guid SlaveIdField;
+        
+        public System.Runtime.Serialization.ExtensionDataObject ExtensionData
+        {
+            get
+            {
+                return this.extensionDataField;
+            }
+            set
+            {
+                this.extensionDataField = value;
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public int FreeCores
+        {
+            get
+            {
+                return this.FreeCoresField;
+            }
+            set
+            {
+                if ((this.FreeCoresField.Equals(value) != true))
+                {
+                    this.FreeCoresField = value;
+                    this.RaisePropertyChanged("FreeCores");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public int FreeMemory
+        {
+            get
+            {
+                return this.FreeMemoryField;
+            }
+            set
+            {
+                if ((this.FreeMemoryField.Equals(value) != true))
+                {
+                    this.FreeMemoryField = value;
+                    this.RaisePropertyChanged("FreeMemory");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public bool IsAllowedToCalculate
+        {
+            get
+            {
+                return this.IsAllowedToCalculateField;
+            }
+            set
+            {
+                if ((this.IsAllowedToCalculateField.Equals(value) != true))
+                {
+                    this.IsAllowedToCalculateField = value;
+                    this.RaisePropertyChanged("IsAllowedToCalculate");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Collections.Generic.Dictionary<System.Guid, System.TimeSpan> JobProgress
+        {
+            get
+            {
+                return this.JobProgressField;
+            }
+            set
+            {
+                if ((object.ReferenceEquals(this.JobProgressField, value) != true))
+                {
+                    this.JobProgressField = value;
+                    this.RaisePropertyChanged("JobProgress");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public System.Guid SlaveId
+        {
+            get
+            {
+                return this.SlaveIdField;
+            }
+            set
+            {
+                if ((this.SlaveIdField.Equals(value) != true))
+                {
+                    this.SlaveIdField = value;
+                    this.RaisePropertyChanged("SlaveId");
+                }
+            }
+        }
+        
+        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
+        
+        protected void RaisePropertyChanged(string propertyName)
+        {
+            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
+            if ((propertyChanged != null))
+            {
+                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
+            }
+        }
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+    [System.Runtime.Serialization.DataContractAttribute(Name="MessageContainer", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common")]
+    public partial class MessageContainer : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
+    {
+        
+        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
+        
+        private System.Guid JobIdk__BackingFieldField;
+        
+        private HeuristicLab.Clients.Hive.MessageContainer.MessageType Messagek__BackingFieldField;
+        
+        public System.Runtime.Serialization.ExtensionDataObject ExtensionData
+        {
+            get
+            {
+                return this.extensionDataField;
+            }
+            set
+            {
+                this.extensionDataField = value;
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute(Name="<JobId>k__BackingField", IsRequired=true)]
+        public System.Guid JobIdk__BackingField
+        {
+            get
+            {
+                return this.JobIdk__BackingFieldField;
+            }
+            set
+            {
+                if ((this.JobIdk__BackingFieldField.Equals(value) != true))
+                {
+                    this.JobIdk__BackingFieldField = value;
+                    this.RaisePropertyChanged("JobIdk__BackingField");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute(Name="<Message>k__BackingField", IsRequired=true)]
+        public HeuristicLab.Clients.Hive.MessageContainer.MessageType Messagek__BackingField
+        {
+            get
+            {
+                return this.Messagek__BackingFieldField;
+            }
+            set
+            {
+                if ((this.Messagek__BackingFieldField.Equals(value) != true))
+                {
+                    this.Messagek__BackingFieldField = value;
+                    this.RaisePropertyChanged("Messagek__BackingField");
+                }
+            }
+        }
+        
+        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
+        
+        protected void RaisePropertyChanged(string propertyName)
+        {
+            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
+            if ((propertyChanged != null))
+            {
+                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
+            }
+        }
+        
+        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
+        [System.Runtime.Serialization.DataContractAttribute(Name="MessageContainer.MessageType", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Hive.Common")]
+        public enum MessageType : int
+        {
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            FetchJob = 0,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            AbortJob = 1,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            JobAborted = 2,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            FinishedJob = 3,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            NoMessage = 4,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            SnapshotReady = 5,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            Shutdown = 6,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            JobFailed = 7,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            UptimeLimitDisconnect = 8,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            UpdateCalendar = 9,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            AddChildJob = 10,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            PauseJob = 11,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            GetChildJobs = 12,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            DeleteChildJobs = 13,
+            
+            [System.Runtime.Serialization.EnumMemberAttribute()]
+            AddSlaveInfo = 14,
+        }
+    }
+    
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="HeuristicLab.Clients.Hive.IHiveService")]
+    public interface IHiveService
+    {
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/AddJob", ReplyAction="http://tempuri.org/IHiveService/AddJobResponse")]
+        System.Guid AddJob(HeuristicLab.Clients.Hive.Job jobDto, HeuristicLab.Clients.Hive.JobData jobDataDto);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/AddChildJob", ReplyAction="http://tempuri.org/IHiveService/AddChildJobResponse")]
+        System.Guid AddChildJob(System.Guid parentJobId, HeuristicLab.Clients.Hive.Job jobDto, HeuristicLab.Clients.Hive.JobData jobDataDto);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetJob", ReplyAction="http://tempuri.org/IHiveService/GetJobResponse")]
+        HeuristicLab.Clients.Hive.Job GetJob(System.Guid jobId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetJobs", ReplyAction="http://tempuri.org/IHiveService/GetJobsResponse")]
+        HeuristicLab.Clients.Hive.Job[] GetJobs();
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetLightweightJobs", ReplyAction="http://tempuri.org/IHiveService/GetLightweightJobsResponse")]
+        HeuristicLab.Clients.Hive.LightweightJob[] GetLightweightJobs(System.Guid[] jobIds);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetLightweightChildJobs", ReplyAction="http://tempuri.org/IHiveService/GetLightweightChildJobsResponse")]
+        HeuristicLab.Clients.Hive.LightweightJob[] GetLightweightChildJobs(System.Nullable<System.Guid> parentJobId, bool recursive, bool includeParent);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetJobData", ReplyAction="http://tempuri.org/IHiveService/GetJobDataResponse")]
+        HeuristicLab.Clients.Hive.JobData GetJobData(System.Guid jobId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetJobDataStreamed", ReplyAction="http://tempuri.org/IHiveService/GetJobDataStreamedResponse")]
+        System.IO.Stream GetJobDataStreamed(System.Guid jobId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/UpdateJob", ReplyAction="http://tempuri.org/IHiveService/UpdateJobResponse")]
+        void UpdateJob(HeuristicLab.Clients.Hive.Job jobDto, HeuristicLab.Clients.Hive.JobData jobDataDto);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/UpdateJobDataStreamed", ReplyAction="http://tempuri.org/IHiveService/UpdateJobDataStreamedResponse")]
+        void UpdateJobDataStreamed(System.IO.Stream stream);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/DeleteChildJobs", ReplyAction="http://tempuri.org/IHiveService/DeleteChildJobsResponse")]
+        void DeleteChildJobs(System.Guid parentJobId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/AquireJob", ReplyAction="http://tempuri.org/IHiveService/AquireJobResponse")]
+        HeuristicLab.Clients.Hive.Job AquireJob(System.Guid slaveId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/AbortJob", ReplyAction="http://tempuri.org/IHiveService/AbortJobResponse")]
+        void AbortJob(System.Guid jobId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/PauseJob", ReplyAction="http://tempuri.org/IHiveService/PauseJobResponse")]
+        HeuristicLab.Clients.Hive.Job PauseJob(HeuristicLab.Clients.Hive.JobData serializedJob);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetHiveExperiment", ReplyAction="http://tempuri.org/IHiveService/GetHiveExperimentResponse")]
+        HeuristicLab.Clients.Hive.HiveExperiment GetHiveExperiment(System.Guid id);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetHiveExperiments", ReplyAction="http://tempuri.org/IHiveService/GetHiveExperimentsResponse")]
+        HeuristicLab.Clients.Hive.HiveExperiment[] GetHiveExperiments();
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/AddHiveExperiment", ReplyAction="http://tempuri.org/IHiveService/AddHiveExperimentResponse")]
+        System.Guid AddHiveExperiment(HeuristicLab.Clients.Hive.HiveExperiment hiveExperimentDto);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/UpdateHiveExperiment", ReplyAction="http://tempuri.org/IHiveService/UpdateHiveExperimentResponse")]
+        void UpdateHiveExperiment(HeuristicLab.Clients.Hive.HiveExperiment hiveExperimentDto);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/DeleteHiveExperiment", ReplyAction="http://tempuri.org/IHiveService/DeleteHiveExperimentResponse")]
+        void DeleteHiveExperiment(System.Guid hiveExperimentId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetAllProjects", ReplyAction="http://tempuri.org/IHiveService/GetAllProjectsResponse")]
+        HeuristicLab.Clients.Hive.Project GetAllProjects();
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/CreateProject", ReplyAction="http://tempuri.org/IHiveService/CreateProjectResponse")]
+        void CreateProject(HeuristicLab.Clients.Hive.Project project);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/ChangeProject", ReplyAction="http://tempuri.org/IHiveService/ChangeProjectResponse")]
+        void ChangeProject(HeuristicLab.Clients.Hive.Project project);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/DeleteProject", ReplyAction="http://tempuri.org/IHiveService/DeleteProjectResponse")]
+        void DeleteProject(System.Guid projectId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetJobsByProject", ReplyAction="http://tempuri.org/IHiveService/GetJobsByProjectResponse")]
+        HeuristicLab.Clients.Hive.Job[] GetJobsByProject(System.Guid projectId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/ProcessHeartbeat", ReplyAction="http://tempuri.org/IHiveService/ProcessHeartbeatResponse")]
+        HeuristicLab.Clients.Hive.MessageContainer[] ProcessHeartbeat(HeuristicLab.Clients.Hive.Heartbeat heartbeat);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetPlugins", ReplyAction="http://tempuri.org/IHiveService/GetPluginsResponse")]
+        HeuristicLab.Clients.Hive.HivePluginData[] GetPlugins(HeuristicLab.Clients.Hive.HivePlugin[] pluginList);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetStreamedPlugins", ReplyAction="http://tempuri.org/IHiveService/GetStreamedPluginsResponse")]
+        System.IO.Stream GetStreamedPlugins(HeuristicLab.Clients.Hive.HivePlugin[] pluginList);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetCalendar", ReplyAction="http://tempuri.org/IHiveService/GetCalendarResponse")]
+        HeuristicLab.Clients.Hive.Appointment[] GetCalendar(System.Guid slaveId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/SetCalendarStatus", ReplyAction="http://tempuri.org/IHiveService/SetCalendarStatusResponse")]
+        void SetCalendarStatus(System.Guid clientId, HeuristicLab.Clients.Hive.CalendarState state);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetUptimeCalendarForResource", ReplyAction="http://tempuri.org/IHiveService/GetUptimeCalendarForResourceResponse")]
+        HeuristicLab.Clients.Hive.Appointment[] GetUptimeCalendarForResource(System.Guid guid);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/SetUptimeCalendarForResource", ReplyAction="http://tempuri.org/IHiveService/SetUptimeCalendarForResourceResponse")]
+        void SetUptimeCalendarForResource(System.Guid guid, HeuristicLab.Clients.Hive.Appointment[] appointments, bool isForced);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/AddSlaveGroup", ReplyAction="http://tempuri.org/IHiveService/AddSlaveGroupResponse")]
+        System.Guid AddSlaveGroup(HeuristicLab.Clients.Hive.SlaveGroup slaveGroup);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetSlaves", ReplyAction="http://tempuri.org/IHiveService/GetSlavesResponse")]
+        HeuristicLab.Clients.Hive.Slave[] GetSlaves();
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/GetSlaveGroups", ReplyAction="http://tempuri.org/IHiveService/GetSlaveGroupsResponse")]
+        HeuristicLab.Clients.Hive.SlaveGroup[] GetSlaveGroups();
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/DeleteSlaveGroup", ReplyAction="http://tempuri.org/IHiveService/DeleteSlaveGroupResponse")]
+        void DeleteSlaveGroup(System.Guid clientGroupId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/AddResourceToGroup", ReplyAction="http://tempuri.org/IHiveService/AddResourceToGroupResponse")]
+        void AddResourceToGroup(System.Guid slaveGroupId, HeuristicLab.Clients.Hive.Resource resource);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/RemoveResourceFromGroup", ReplyAction="http://tempuri.org/IHiveService/RemoveResourceFromGroupResponse")]
+        void RemoveResourceFromGroup(System.Guid slaveGroupId, System.Guid resourceId);
+        
+        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHiveService/UpdateSlave", ReplyAction="http://tempuri.org/IHiveService/UpdateSlaveResponse")]
+        void UpdateSlave(HeuristicLab.Clients.Hive.Slave slave);
+    }
+    
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+    public interface IHiveServiceChannel : HeuristicLab.Clients.Hive.IHiveService, System.ServiceModel.IClientChannel
+    {
+    }
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
+    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+    public partial class HiveServiceClient : System.ServiceModel.ClientBase<HeuristicLab.Clients.Hive.IHiveService>, HeuristicLab.Clients.Hive.IHiveService
+    {
+        
+        public HiveServiceClient()
+        {
+        }
+        
+        public HiveServiceClient(string endpointConfigurationName) : 
+                base(endpointConfigurationName)
+        {
+        }
+        
+        public HiveServiceClient(string endpointConfigurationName, string remoteAddress) : 
+                base(endpointConfigurationName, remoteAddress)
+        {
+        }
+        
+        public HiveServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
+                base(endpointConfigurationName, remoteAddress)
+        {
+        }
+        
+        public HiveServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
+                base(binding, remoteAddress)
+        {
+        }
+        
+        public System.Guid AddJob(HeuristicLab.Clients.Hive.Job jobDto, HeuristicLab.Clients.Hive.JobData jobDataDto)
+        {
+            return base.Channel.AddJob(jobDto, jobDataDto);
+        }
+        
+        public System.Guid AddChildJob(System.Guid parentJobId, HeuristicLab.Clients.Hive.Job jobDto, HeuristicLab.Clients.Hive.JobData jobDataDto)
+        {
+            return base.Channel.AddChildJob(parentJobId, jobDto, jobDataDto);
+        }
+        
+        public HeuristicLab.Clients.Hive.Job GetJob(System.Guid jobId)
+        {
+            return base.Channel.GetJob(jobId);
+        }
+        
+        public HeuristicLab.Clients.Hive.Job[] GetJobs()
+        {
+            return base.Channel.GetJobs();
+        }
+        
+        public HeuristicLab.Clients.Hive.LightweightJob[] GetLightweightJobs(System.Guid[] jobIds)
+        {
+            return base.Channel.GetLightweightJobs(jobIds);
+        }
+        
+        public HeuristicLab.Clients.Hive.LightweightJob[] GetLightweightChildJobs(System.Nullable<System.Guid> parentJobId, bool recursive, bool includeParent)
+        {
+            return base.Channel.GetLightweightChildJobs(parentJobId, recursive, includeParent);
+        }
+        
+        public HeuristicLab.Clients.Hive.JobData GetJobData(System.Guid jobId)
+        {
+            return base.Channel.GetJobData(jobId);
+        }
+        
+        public System.IO.Stream GetJobDataStreamed(System.Guid jobId)
+        {
+            return base.Channel.GetJobDataStreamed(jobId);
+        }
+        
+        public void UpdateJob(HeuristicLab.Clients.Hive.Job jobDto, HeuristicLab.Clients.Hive.JobData jobDataDto)
+        {
+            base.Channel.UpdateJob(jobDto, jobDataDto);
+        }
+        
+        public void UpdateJobDataStreamed(System.IO.Stream stream)
+        {
+            base.Channel.UpdateJobDataStreamed(stream);
+        }
+        
+        public void DeleteChildJobs(System.Guid parentJobId)
+        {
+            base.Channel.DeleteChildJobs(parentJobId);
+        }
+        
+        public HeuristicLab.Clients.Hive.Job AquireJob(System.Guid slaveId)
+        {
+            return base.Channel.AquireJob(slaveId);
+        }
+        
+        public void AbortJob(System.Guid jobId)
+        {
+            base.Channel.AbortJob(jobId);
+        }
+        
+        public HeuristicLab.Clients.Hive.Job PauseJob(HeuristicLab.Clients.Hive.JobData serializedJob)
+        {
+            return base.Channel.PauseJob(serializedJob);
+        }
+        
+        public HeuristicLab.Clients.Hive.HiveExperiment GetHiveExperiment(System.Guid id)
+        {
+            return base.Channel.GetHiveExperiment(id);
+        }
+        
+        public HeuristicLab.Clients.Hive.HiveExperiment[] GetHiveExperiments()
+        {
+            return base.Channel.GetHiveExperiments();
+        }
+        
+        public System.Guid AddHiveExperiment(HeuristicLab.Clients.Hive.HiveExperiment hiveExperimentDto)
+        {
+            return base.Channel.AddHiveExperiment(hiveExperimentDto);
+        }
+        
+        public void UpdateHiveExperiment(HeuristicLab.Clients.Hive.HiveExperiment hiveExperimentDto)
+        {
+            base.Channel.UpdateHiveExperiment(hiveExperimentDto);
+        }
+        
+        public void DeleteHiveExperiment(System.Guid hiveExperimentId)
+        {
+            base.Channel.DeleteHiveExperiment(hiveExperimentId);
+        }
+        
+        public HeuristicLab.Clients.Hive.Project GetAllProjects()
+        {
+            return base.Channel.GetAllProjects();
+        }
+        
+        public void CreateProject(HeuristicLab.Clients.Hive.Project project)
+        {
+            base.Channel.CreateProject(project);
+        }
+        
+        public void ChangeProject(HeuristicLab.Clients.Hive.Project project)
+        {
+            base.Channel.ChangeProject(project);
+        }
+        
+        public void DeleteProject(System.Guid projectId)
+        {
+            base.Channel.DeleteProject(projectId);
+        }
+        
+        public HeuristicLab.Clients.Hive.Job[] GetJobsByProject(System.Guid projectId)
+        {
+            return base.Channel.GetJobsByProject(projectId);
+        }
+        
+        public HeuristicLab.Clients.Hive.MessageContainer[] ProcessHeartbeat(HeuristicLab.Clients.Hive.Heartbeat heartbeat)
+        {
+            return base.Channel.ProcessHeartbeat(heartbeat);
+        }
+        
+        public HeuristicLab.Clients.Hive.HivePluginData[] GetPlugins(HeuristicLab.Clients.Hive.HivePlugin[] pluginList)
+        {
+            return base.Channel.GetPlugins(pluginList);
+        }
+        
+        public System.IO.Stream GetStreamedPlugins(HeuristicLab.Clients.Hive.HivePlugin[] pluginList)
+        {
+            return base.Channel.GetStreamedPlugins(pluginList);
+        }
+        
+        public HeuristicLab.Clients.Hive.Appointment[] GetCalendar(System.Guid slaveId)
+        {
+            return base.Channel.GetCalendar(slaveId);
+        }
+        
+        public void SetCalendarStatus(System.Guid clientId, HeuristicLab.Clients.Hive.CalendarState state)
+        {
+            base.Channel.SetCalendarStatus(clientId, state);
+        }
+        
+        public HeuristicLab.Clients.Hive.Appointment[] GetUptimeCalendarForResource(System.Guid guid)
+        {
+            return base.Channel.GetUptimeCalendarForResource(guid);
+        }
+        
+        public void SetUptimeCalendarForResource(System.Guid guid, HeuristicLab.Clients.Hive.Appointment[] appointments, bool isForced)
+        {
+            base.Channel.SetUptimeCalendarForResource(guid, appointments, isForced);
+        }
+        
+        public System.Guid AddSlaveGroup(HeuristicLab.Clients.Hive.SlaveGroup slaveGroup)
+        {
+            return base.Channel.AddSlaveGroup(slaveGroup);
+        }
+        
+        public HeuristicLab.Clients.Hive.Slave[] GetSlaves()
+        {
+            return base.Channel.GetSlaves();
+        }
+        
+        public HeuristicLab.Clients.Hive.SlaveGroup[] GetSlaveGroups()
+        {
+            return base.Channel.GetSlaveGroups();
+        }
+        
+        public void DeleteSlaveGroup(System.Guid clientGroupId)
+        {
+            base.Channel.DeleteSlaveGroup(clientGroupId);
+        }
+        
+        public void AddResourceToGroup(System.Guid slaveGroupId, HeuristicLab.Clients.Hive.Resource resource)
+        {
+            base.Channel.AddResourceToGroup(slaveGroupId, resource);
+        }
+        
+        public void RemoveResourceFromGroup(System.Guid slaveGroupId, System.Guid resourceId)
+        {
+            base.Channel.RemoveResourceFromGroup(slaveGroupId, resourceId);
+        }
+        
+        public void UpdateSlave(HeuristicLab.Clients.Hive.Slave slave)
+        {
+            base.Channel.UpdateSlave(slave);
+        }
+    }
+}
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 4649)
@@ -105,10 +105,10 @@
 
     private void RegisterServiceEvents() {
-      disposableService.OnDisposing += new EventHandler(disposableService_OnDisposing);
+      disposableService.Disposing += disposableService_Disposing;
       ((ICommunicationObject)disposableService.Obj).Faulted += new EventHandler(WcfServicePool_Faulted);
     }
 
     private void DeregisterServiceEvents() {
-      disposableService.OnDisposing -= new EventHandler(disposableService_OnDisposing);
+      disposableService.Disposing -= disposableService_Disposing;
       ((ICommunicationObject)disposableService.Obj).Faulted -= new EventHandler(WcfServicePool_Faulted);
     }
@@ -122,5 +122,5 @@
     }
 
-    private void disposableService_OnDisposing(object sender, EventArgs e) {
+    private void disposableService_Disposing(object sender, EventArgs<T> e) {
       DisposeService();
     }
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 4649)
@@ -3,28 +3,30 @@
     <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">
+            <wsHttpBinding>
+                <binding name="HttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
+                    receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
+                    transactionFlow="false" hostNameComparisonMode="StrongWildcard"
+                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
+                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
+                    allowCookies="false">
                     <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 mode="Message">
+                        <transport clientCredentialType="Windows" proxyCredentialType="None"
+                            realm="" />
+                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
+                            algorithmSuite="Default" />
                     </security>
                 </binding>
-            </netTcpBinding>
+            </wsHttpBinding>
         </bindings>
         <client>
-            <endpoint address="net.tcp://localhost:9000/HiveService" binding="netTcpBinding"
-                bindingConfiguration="TcpEndpoint" contract="HeuristicLab.Services.Hive.Common.ServiceContracts.IHiveService"
-                name="TcpEndpoint">
+            <endpoint address="http://localhost:9000/HiveService" binding="wsHttpBinding"
+                bindingConfiguration="HttpBinding" contract="HeuristicLab.Clients.Hive.IHiveService"
+                name="HttpBinding">
                 <identity>
-                    <dns value="localhost" />
+                    <userPrincipalName value="S0920454044@hagenberg.fhooe.at" />
                 </identity>
             </endpoint>
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveExperiment.cs	(revision 4649)
@@ -30,6 +30,4 @@
   public class HiveExperiment : NamedHiveItem {
     [DataMember]
-    public string ResourceIds { get; set; }
-    [DataMember]
     public Guid UserId { get; set; }
     [DataMember]
@@ -37,10 +35,9 @@
 
     public override string ToString() {
-      return base.ToString() + "Name: " + Name + ", Description: " + Description + ", ResourceIds: " + ResourceIds;
+      return base.ToString() + "Name: " + Name + ", Description: " + Description;
     }
     
     public override IDeepCloneable Clone(Cloner cloner) {
       var clone = (HiveExperiment)base.Clone(cloner);
-      clone.ResourceIds = this.ResourceIds;
       clone.RootJobId = this.RootJobId;
       clone.UserId = this.UserId;
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveItem.cs	(revision 4649)
@@ -8,18 +8,14 @@
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
   [DataContract]
-  public abstract class HiveItem : IDeepCloneable {
+  [Serializable]
+  public abstract class HiveItem : HiveItemBase {
     [DataMember]
     public Guid Id { get; set; }
 
     public virtual IDeepCloneable Clone(Cloner cloner) {
-      HiveItem clone = (HiveItem)Activator.CreateInstance(this.GetType(), true);
-      cloner.RegisterClonedObject(this, clone);
+      HiveItem clone = (HiveItem)base.Clone(cloner);
       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/HiveItemBase.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveItemBase.cs	(revision 4649)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/HiveItemBase.cs	(revision 4649)
@@ -0,0 +1,22 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using System.Runtime.Serialization;
+
+namespace HeuristicLab.Services.Hive.Common.DataTransfer {
+  [DataContract]
+  [Serializable]
+  public class HiveItemBase : IDeepCloneable {
+    public virtual IDeepCloneable Clone(Cloner cloner) {
+      HiveItem clone = (HiveItem)Activator.CreateInstance(this.GetType(), true);
+      cloner.RegisterClonedObject(this, clone);
+      return clone;
+    }
+
+    public object Clone() {
+      return Clone(new Cloner());
+    }
+  }
+}
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Job.cs	(revision 4649)
@@ -27,5 +27,4 @@
 
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
-
   [DataContract]
   [Serializable]
@@ -40,18 +39,12 @@
     public int MemoryNeeded { get; set; }
     [DataMember]
-    public List<Guid> PluginsNeededIds { get; set; }
-    [DataMember]
-    public List<Guid> AssignedResourceIds { get; set; }
-    [DataMember]
-    public Guid ProjectId { get; set; }
+    public Guid? ProjectId { get; set; }
 
     public override string ToString() {
-      return base.ToString() + "State: " + State + ", [SlaveId : " + SlaveId + " ] , DateCreated: " + DateCreated + ", DateCalculated: " + DateCalculated +
-        "Priority: " + Priority + ", CoresNeeded: " + CoresNeeded + "AssignedResources: " + AssignedResourceIds;
+      return base.ToString() + "State: " + JobState + ", [SlaveId : " + SlaveId + " ] , DateCreated: " + DateCreated + ", DateCalculated: " + DateCalculated +
+        "Priority: " + Priority + ", CoresNeeded: " + CoresNeeded;
     }
 
     public Job() {
-      PluginsNeededIds = new List<Guid>();
-      AssignedResourceIds = new List<Guid>();
     }
 
@@ -62,6 +55,4 @@
       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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/JobData.cs	(revision 4649)
@@ -28,5 +28,5 @@
   [DataContract]
   [Serializable]
-  public class JobData : HiveItem {
+  public class JobData : HiveItemBase {
     [DataMember]
     public Guid JobId { get; set; }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/JobState.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/JobState.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/JobState.cs	(revision 4649)
@@ -23,8 +23,8 @@
 namespace HeuristicLab.Services.Hive.Common.DataTransfer {
   public enum JobState {
-    /// <summary>
-    /// Job is actively calculated on a Slave
+        /// <summary>
+    /// A job is offline as long as he is not yet submitted to the hive
     /// </summary>
-    Calculating,
+    Offline,
 
     /// <summary>
@@ -33,4 +33,14 @@
     Waiting,
 
+        /// <summary>
+    /// The job is paused and waits on the server to be sent back to a Slave when all of its child jobs are Finished.
+    /// </summary>
+    WaitingForChildJobs,
+
+    /// <summary>
+    /// Job is actively calculated on a Slave
+    /// </summary>
+    Calculating,
+    
     /// <summary>
     /// Job as finished and is ready to be collected by the Client
@@ -46,10 +56,5 @@
     /// Job as been aborted due to an error. Results are ready to be collected
     /// </summary>
-    Failed,
-
-    /// <summary>
-    /// The job is paused and waits on the server to be sent back to a Slave when all of its child jobs are Finished.
-    /// </summary>
-    WaitForChildJobs
+    Failed
   };
 
@@ -67,5 +72,5 @@
     public static bool IsWaiting(this JobState jobState) {
       return jobState == JobState.Waiting ||
-        jobState == JobState.WaitForChildJobs;
+        jobState == JobState.WaitingForChildJobs;
     }
 
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/LightweightJob.cs	(revision 4649)
@@ -29,9 +29,9 @@
   public class LightweightJob : HiveItem {
     [DataMember]
-    public Guid SlaveId { get; set; }
+    public Guid? SlaveId { get; set; }
     [DataMember]
-    public JobState State { get; set; }
+    public JobState JobState { get; set; }
     [DataMember]
-    public TimeSpan ExecutionTime { get; set; }
+    public TimeSpan? ExecutionTime { get; set; }
     [DataMember]
     public String Exception { get; set; }
@@ -45,9 +45,11 @@
     public Guid? ParentJobId { get; set; }
 
-    public LightweightJob() { }
+    public LightweightJob() {
+      JobState = DataTransfer.JobState.Offline;
+    }
 
     public LightweightJob(Job job) {
       this.SlaveId = job.SlaveId;
-      this.State = job.State;
+      this.JobState = job.JobState;
       this.ExecutionTime = job.ExecutionTime;
       this.Exception = job.Exception;
@@ -61,5 +63,5 @@
       var clone = (LightweightJob)base.Clone(cloner);
       clone.SlaveId = this.SlaveId;
-      clone.State = this.State;
+      clone.JobState = this.JobState;
       clone.ExecutionTime = this.ExecutionTime;
       clone.Exception = this.Exception;
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/Slave.cs	(revision 4649)
@@ -33,5 +33,5 @@
     public int? FreeCores { get; set; }
     [DataMember]
-    public int? CpuSpeedPerCore { get; set; }
+    public int? CpuSpeed { get; set; }
     [DataMember]
     public int? Memory { get; set; }
@@ -39,14 +39,18 @@
     public int? FreeMemory { get; set; }
     [DataMember]
-    public SlaveState State { get; set; }
+    public SlaveState SlaveState { get; set; }
     [DataMember]
-    public CalendarState CalendarSyncStatus { get; set; }
+    public CalendarState CalendarSyncState { get; set; }
     [DataMember]
-    public Guid SlaveConfigId { get; set; }
+    public Guid? SlaveConfigId { get; set; }
     [DataMember]
     public bool IsAllowedToCalculate { get; set; }
 
+    public Slave() {
+      SlaveState = DataTransfer.SlaveState.Idle;
+    }
+
     public override string ToString() {
-      return base.ToString() + ", NrOfCores: " + Cores + ", NrOfFreeCores " + FreeCores + ", State: " + State;
+      return base.ToString() + ", NrOfCores: " + Cores + ", NrOfFreeCores " + FreeCores + ", State: " + SlaveState;
     }
 
@@ -55,9 +59,9 @@
       clone.Cores = this.Cores;
       clone.FreeCores = this.FreeCores;
-      clone.CpuSpeedPerCore = this.CpuSpeedPerCore;
+      clone.CpuSpeed = this.CpuSpeed;
       clone.Memory = this.Memory;
       clone.FreeMemory = this.FreeMemory;
-      clone.State = this.State;
-      clone.CalendarSyncStatus = this.CalendarSyncStatus;
+      clone.SlaveState = this.SlaveState;
+      clone.CalendarSyncState = this.CalendarSyncState;
       clone.SlaveConfigId = this.SlaveConfigId;
       clone.IsAllowedToCalculate = this.IsAllowedToCalculate;
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/DataTransfer/SlaveGroup.cs	(revision 4649)
@@ -30,13 +30,16 @@
   public class SlaveGroup : Resource {
     [DataMember]
-    public List<Guid> ResourcesIds { get; set; }
+    public List<Guid> ChildResourcesIds { get; set; }
+    [DataMember]
+    public List<Guid> ParentResourcesIds { get; set; }
 
     public SlaveGroup() {
-      ResourcesIds = new List<Guid>();
+      ChildResourcesIds = new List<Guid>();
     }
 
     public override IDeepCloneable Clone(Cloner cloner) {
       var clone = (SlaveGroup)base.Clone(cloner);
-      clone.ResourcesIds = new List<Guid>(this.ResourcesIds);
+      clone.ChildResourcesIds = new List<Guid>(this.ChildResourcesIds);
+      clone.ParentResourcesIds = new List<Guid>(this.ParentResourcesIds);
       return clone;
     }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/Disposable.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/Disposable.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/Disposable.cs	(revision 4649)
@@ -21,4 +21,5 @@
 
 using System;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Services.Hive.Common {
@@ -34,9 +35,9 @@
 
     public void Dispose() {
-      if (OnDisposing != null)
-        OnDisposing(this, new EventArgs());
+      if (Disposing != null)
+        Disposing(this, new EventArgs<T>(obj));
     }
 
-    public event EventHandler OnDisposing;
+    public event EventHandler<EventArgs<T>> Disposing;
   }
 }
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/HeuristicLab.Services.Hive.Common-3.3.csproj	(revision 4649)
@@ -67,4 +67,5 @@
     <Compile Include="DataTransfer\HiveExperiment.cs" />
     <Compile Include="DataTransfer\HiveItem.cs" />
+    <Compile Include="DataTransfer\HiveItemBase.cs" />
     <Compile Include="DataTransfer\HivePluginData.cs" />
     <Compile Include="DataTransfer\HivePlugin.cs" />
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.Common/3.3/ServiceContracts/IHiveService.cs	(revision 4649)
@@ -156,4 +156,7 @@
     #region Slave Methods
     [OperationContract]
+    Guid AddSlave(Slave slave);
+
+    [OperationContract]
     Guid AddSlaveGroup(SlaveGroup slaveGroup);
 
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 4629)
+++ 	(revision )
@@ -1,139 +1,0 @@
-﻿#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.Data.Linq;
-using System.Threading;
-using System.Transactions;
-using HeuristicLab.Tracing;
-using HeuristicLab.Services.Hive.Common;
-using HeuristicLab.Services.Hive.DataAccess.Properties;
-
-
-namespace HeuristicLab.Services.Hive.DataAccess {
-  public delegate T CreateDataContext<T>() where T : DataContext;
-
-  /// <summary>
-  /// This class handles creates one Context for each Thread which asks for one.
-  /// If one Thread calls GetContext several times, it always gets the same Context object.
-  /// A context object is removed from the cache when it is disposed. 
-  /// 
-  /// Every context has a DB-Transaction over its livetime. After using the context object
-  /// it has to be disposed in order to finish the corresponding transaction.
-  /// </summary>
-  public class ContextFactory<T> : IContextFactory<T> where T : DataContext {
-    private static object locker = new object();
-    private static IDictionary<int, Disposable<T>> contexts = new Dictionary<int, Disposable<T>>();
-    private static IDictionary<int, TransactionScope> transactions = new Dictionary<int, TransactionScope>();
-    private CreateDataContext<T> createDataContext;
-
-    public ContextFactory(CreateDataContext<T> createDataContext) {
-      this.createDataContext = createDataContext;
-    }
-
-    public IDisposable GetContext() {
-      return GetContext(true);
-    }
-
-    public IDisposable GetContext(bool withTransaction) {
-      lock (locker) {
-        int threadId = Thread.CurrentThread.ManagedThreadId;
-
-        if (contexts.ContainsKey(threadId)) {
-          Logger.Error("ERROR: Context for this Thread already defined. Will dispose it and then create a new one.");
-          RemoveContext();
-          RemoveAndCompleteTransaction();
-        }
-
-        T context = createDataContext();
-       
-        Disposable<T> disposableContext = new Disposable<T>(context);
-        disposableContext.OnDisposing += new EventHandler(context_OnDisposing);
-        contexts.Add(threadId, disposableContext);
-
-        if (withTransaction) {
-          TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = ApplicationConstants.ISOLATION_LEVEL_SCOPE });
-          transactions.Add(threadId, transaction);
-        }
-        return disposableContext;
-      }
-    }
-
-    void context_OnDisposing(object sender, EventArgs e) {
-      lock (locker) {
-        RemoveContext();
-        RemoveAndCompleteTransaction();
-      }
-    }
-
-    public void RollbackTransaction() {
-      int threadId = Thread.CurrentThread.ManagedThreadId;
-
-      TransactionScope transaction = transactions[threadId];
-      transaction.Dispose();
-    }
-
-    public void RemoveContext() {
-      lock (locker) {
-        int threadId = Thread.CurrentThread.ManagedThreadId;
-        contexts[threadId].Obj.Dispose();
-        contexts.Remove(threadId);
-        // context gets disposed implicitly, when it is used as IDisposable
-      }
-    }
-
-    public void RemoveAndCompleteTransaction() {
-      lock (locker) {
-        int threadId = Thread.CurrentThread.ManagedThreadId;
-
-        // context does not always have an associated transaction
-        if (transactions.ContainsKey(threadId)) {
-          try {
-            transactions[threadId].Complete();
-            transactions[threadId].Dispose();
-          }
-          catch (Exception) { }
-          finally {
-            transactions.Remove(threadId);
-          }
-        }
-      }
-    }
-
-    public T CurrentContext {
-      get {
-        lock (locker) {
-          int threadId = Thread.CurrentThread.ManagedThreadId;
-          if (contexts.ContainsKey(threadId)) {
-            return contexts[threadId].Obj;
-          } else {
-            return default(T);
-          }
-        }
-      }
-    }
-
-    public static HiveDataContext CreateHiveContext() {
-      return new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString);
-    }
-  }
-}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Convert.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Convert.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/Convert.cs	(revision 4649)
@@ -24,21 +24,49 @@
 using System.Linq;
 using DT = HeuristicLab.Services.Hive.Common.DataTransfer;
+using System;
 
 namespace HeuristicLab.Services.Hive.DataAccess {
   public static class Convert {
-
-   
     #region Job
     public static DT.Job ToDto(Job source) {
       if (source == null) return null;
-      return new DT.Job { Id = source.JobId };// todo
+      return new DT.Job {
+        Id = source.JobId,
+        CoresNeeded = source.CoresNeeded,
+        DateCalculated = source.DateCalculated,
+        DateCreated = source.DateCreated,
+        DateFinished = source.DateFinished,
+        Exception = source.Exception,
+        ExecutionTime = source.ExecutionTime,
+        MemoryNeeded = source.MemoryNeeded,
+        ParentJobId = source.ParentJobId,
+        Priority = source.Priority,
+        ProjectId = source.ProjectId,
+        SlaveId = source.SlaveId,
+        JobState = source.JobState,
+        UserId = source.UserId
+      };
     }
     public static Job ToEntity(DT.Job source) {
       if (source == null) return null;
-      return new Job { JobId = source.Id };// todo
+      var entity = new Job(); ToEntity(source, entity);
+      return entity;
     }
     public static void ToEntity(DT.Job source, Job target) {
       if ((source != null) && (target != null)) {
-        target.JobId = source.Id;// todo
+        target.JobId = source.Id;
+        target.CoresNeeded = source.CoresNeeded;
+        target.DateCalculated = source.DateCalculated;
+        target.DateCreated = source.DateCreated;
+        target.DateFinished = source.DateFinished;
+        target.Exception = source.Exception;
+        target.ExecutionTime = source.ExecutionTime;
+        target.MemoryNeeded = source.MemoryNeeded;
+        target.ParentJobId = source.ParentJobId;
+        target.Priority = source.Priority;
+        target.ProjectId = source.ProjectId;
+        target.SlaveId = source.SlaveId;
+        target.JobState = source.JobState;
+        target.UserId = source.UserId;
       }
     }
@@ -48,29 +76,31 @@
     public static DT.JobData ToDto(JobData source) {
       if (source == null) return null;
-      return new DT.JobData { JobId = source.JobId };// todo
+      return new DT.JobData { JobId = source.JobId, Data = source.Data.ToArray() };
     }
     public static JobData ToEntity(DT.JobData source) {
       if (source == null) return null;
-      return new JobData { JobId = source.Id };// todo
+      var entity = new JobData(); ToEntity(source, entity);
+      return entity;
     }
     public static void ToEntity(DT.JobData source, JobData target) {
       if ((source != null) && (target != null)) {
-        target.JobId = source.Id;// todo
+        target.JobId = source.JobId; target.Data = new Binary(source.Data);
       }
     }
     #endregion
-    
+
     #region HiveExperiment
     public static DT.HiveExperiment ToDto(HiveExperiment source) {
       if (source == null) return null;
-      return new DT.HiveExperiment { Id = source.HiveExperimentId };// todo
+      return new DT.HiveExperiment { Id = source.HiveExperimentId, Description = source.Description, Name = source.Name, RootJobId = source.RootJobId, UserId = source.UserId };
     }
     public static HiveExperiment ToEntity(DT.HiveExperiment source) {
       if (source == null) return null;
-      return new HiveExperiment { HiveExperimentId = source.Id };// todo
+      var entity = new HiveExperiment(); ToEntity(source, entity);
+      return entity;
     }
     public static void ToEntity(DT.HiveExperiment source, HiveExperiment target) {
       if ((source != null) && (target != null)) {
-        target.HiveExperimentId = source.Id;// todo
+        target.HiveExperimentId = source.Id; target.Description = source.Description; target.Name = source.Name; target.RootJobId = source.RootJobId; target.UserId = source.UserId;
       }
     }
@@ -80,13 +110,14 @@
     public static DT.Slave ToDto(Slave source) {
       if (source == null) return null;
-      return new DT.Slave { Id = source.ResourceId };// todo
+      return new DT.Slave { Id = source.ResourceId, CalendarSyncState = source.CalendarSyncState, Cores = source.Cores, CpuSpeed = source.CpuSpeed, FreeCores = source.FreeCores, FreeMemory = source.FreeMemory, IsAllowedToCalculate = source.IsAllowedToCalculate, Memory = source.Memory, Name = source.Name, SlaveConfigId = source.SlaveConfigId, SlaveState = source.SlaveState };
     }
     public static Slave ToEntity(DT.Slave source) {
       if (source == null) return null;
-      return new Slave { ResourceId = source.Id };// todo
+      var entity = new Slave(); ToEntity(source, entity);
+      return entity;
     }
     public static void ToEntity(DT.Slave source, Slave target) {
       if ((source != null) && (target != null)) {
-        target.ResourceId = source.Id;// todo
+        target.ResourceId = source.Id; target.CalendarSyncState = source.CalendarSyncState; target.Cores = source.Cores; target.CpuSpeed = source.CpuSpeed; target.FreeCores = source.FreeCores; target.FreeMemory = source.FreeMemory; target.IsAllowedToCalculate = source.IsAllowedToCalculate; target.Memory = source.Memory; target.Name = source.Name; target.SlaveConfigId = source.SlaveConfigId; target.SlaveState = source.SlaveState;
       }
     }
@@ -96,13 +127,17 @@
     public static DT.SlaveGroup ToDto(SlaveGroup source) {
       if (source == null) return null;
-      return new DT.SlaveGroup { Id = source.ResourceId };// todo
+      return new DT.SlaveGroup { Id = source.ResourceId, Name = source.Name, ChildResourcesIds = source.SlaveGroup_Resources_Children.Select(x => x.ResourceId).ToList(), ParentResourcesIds = source.SlaveGroup_Resources_Parents.Select(x => x.ResourceId).ToList() };
     }
     public static SlaveGroup ToEntity(DT.SlaveGroup source) {
       if (source == null) return null;
-      return new SlaveGroup { ResourceId = source.Id };// todo
+      var entity = new SlaveGroup(); ToEntity(source, entity);
+      return entity;
     }
     public static void ToEntity(DT.SlaveGroup source, SlaveGroup target) {
       if ((source != null) && (target != null)) {
-        target.ResourceId = source.Id;// todo
+        target.ResourceId = source.Id;
+        target.Name = source.Name; 
+        //target.SlaveGroup_Resources_Children = // TODO: see how working with groups will work, then decide how to handle enumerations in here
+        //target.SlaveGroup_Resources_Parents = 
       }
     }
@@ -112,13 +147,14 @@
     public static DT.Resource ToDto(Resource source) {
       if (source == null) return null;
-      return new DT.Resource { Id = source.ResourceId };// todo
+      return new DT.Resource { Id = source.ResourceId, Name = source.Name };
     }
     public static Resource ToEntity(DT.Resource source) {
       if (source == null) return null;
-      return new Resource { ResourceId = source.Id };// todo
+      var entity = new Resource(); ToEntity(source, entity);
+      return entity;
     }
     public static void ToEntity(DT.Resource source, Resource target) {
       if ((source != null) && (target != null)) {
-        target.ResourceId = source.Id;// todo
+        target.ResourceId = source.Id; target.Name = source.Name;
       }
     }
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj	(revision 4649)
@@ -61,5 +61,4 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="ContextFactory.cs" />
     <Compile Include="Convert.cs" />
     <Compile Include="HeuristicLabServicesHiveDataAccessPlugin.cs" />
@@ -82,4 +81,5 @@
     </Compile>
     <Compile Include="Tools\CreateHiveDatabaseApplication.cs" />
+    <Compile Include="TransactionManager.cs" />
   </ItemGroup>
   <ItemGroup>
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 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDao.cs	(revision 4649)
@@ -8,63 +8,78 @@
   using DT = HeuristicLab.Services.Hive.Common.DataTransfer;
   using HeuristicLab.Services.Hive.Common.DataTransfer;
+  using HeuristicLab.Services.Hive.DataAccess.Properties;
 
   public class HiveDao : IHiveDao {
-    private IContextFactory<HiveDataContext> contextFactory;
-    private DataAccess.HiveDataContext db { get { return contextFactory.CurrentContext; } }
-
-    public HiveDao(IContextFactory<HiveDataContext> contextFactory) {
-      this.contextFactory = contextFactory;
+    public HiveDataContext CreateContext() {
+      return new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString);
+    }
+
+    public HiveDao() {
     }
 
     #region Job Methods
     public DT.Job GetJob(Guid id) {
-      return Convert.ToDto(db.Jobs.SingleOrDefault(x => x.JobId == id));
+      using (var db = CreateContext()) {
+        return Convert.ToDto(db.Jobs.SingleOrDefault(x => x.JobId == id));
+      }
     }
 
     public IEnumerable<DT.Job> GetJobs(Expression<Func<Job, bool>> predicate) {
-      return db.Jobs.Where(predicate).Select(x => Convert.ToDto(x));
+      using (var db = CreateContext()) {
+        return db.Jobs.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
+      }
     }
 
     public Guid AddJob(DT.Job dto) {
-      var entity = Convert.ToEntity(dto);
-      db.Jobs.InsertOnSubmit(entity);
-      db.SubmitChanges();
-      return entity.JobId;
+      using (var db = CreateContext()) {
+        var entity = Convert.ToEntity(dto);
+        db.Jobs.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.JobId;
+      }
     }
 
     public void UpdateJob(DT.Job dto) {
-      var entity = db.Jobs.FirstOrDefault(x => x.JobId == dto.Id);
-      if (entity == null) db.Jobs.InsertOnSubmit(Convert.ToEntity(dto));
-      else Convert.ToEntity(dto, entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.Jobs.FirstOrDefault(x => x.JobId == dto.Id);
+        if (entity == null) db.Jobs.InsertOnSubmit(Convert.ToEntity(dto));
+        else Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
     }
 
     public void DeleteJob(Guid id) {
-      var entity = db.Jobs.FirstOrDefault(x => x.JobId == id);
-      if (entity != null) db.Jobs.DeleteOnSubmit(entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.Jobs.FirstOrDefault(x => x.JobId == id);
+        if (entity != null) db.Jobs.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
     }
 
     public IEnumerable<DT.Job> GetAvailableParentJobs(Guid slaveId) {
-      // todo: slaveId is unused!
-      var query = from ar in db.AssignedResources
-                  where ar.Job.JobState == JobState.WaitForChildJobs &&
-                    (from child in db.Jobs
-                     where child.ParentJobId == ar.Job.JobId
-                     select child.JobState == JobState.Finished).All(x => x) &&
-                    (from child in db.Jobs // avoid returning WaitForChildJobs jobs where no child-jobs exist (yet)
-                     where child.ParentJobId == ar.Job.JobId
-                     select child).Count() > 0
-                  orderby ar.Job.Priority descending
-                  select Convert.ToDto(ar.Job);
-      return query;
+      using (var db = CreateContext()) {
+        // todo: slaveId is unused!
+        var query = from ar in db.AssignedResources
+                    where ar.Job.JobState == JobState.WaitingForChildJobs &&
+                      (from child in db.Jobs
+                       where child.ParentJobId == ar.Job.JobId
+                       select child.JobState == JobState.Finished).All(x => x) &&
+                      (from child in db.Jobs // avoid returning WaitForChildJobs jobs where no child-jobs exist (yet)
+                       where child.ParentJobId == ar.Job.JobId
+                       select child).Count() > 0
+                    orderby ar.Job.Priority descending
+                    select Convert.ToDto(ar.Job);
+        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();
+      using (var db = CreateContext()) {
+        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
@@ -73,29 +88,39 @@
 
     public DT.JobData GetJobData(Guid id) {
-      return Convert.ToDto(db.JobDatas.SingleOrDefault(x => x.JobId == id));
+      using (var db = CreateContext()) {
+        return Convert.ToDto(db.JobDatas.SingleOrDefault(x => x.JobId == id));
+      }
     }
 
     public IEnumerable<DT.JobData> GetJobDatas(Expression<Func<JobData, bool>> predicate) {
-      return db.JobDatas.Where(predicate).Select(x => Convert.ToDto(x));
+      using (var db = CreateContext()) {
+        return db.JobDatas.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
+      }
     }
 
     public Guid AddJobData(DT.JobData dto) {
-      var entity = Convert.ToEntity(dto);
-      db.JobDatas.InsertOnSubmit(entity);
-      db.SubmitChanges();
-      return entity.JobId;
+      using (var db = CreateContext()) {
+        var entity = Convert.ToEntity(dto);
+        db.JobDatas.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.JobId;
+      }
     }
 
     public void UpdateJobData(DT.JobData dto) {
-      var entity = db.JobDatas.FirstOrDefault(x => x.JobId == dto.Id);
-      if (entity == null) db.JobDatas.InsertOnSubmit(Convert.ToEntity(dto));
-      else Convert.ToEntity(dto, entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.JobDatas.FirstOrDefault(x => x.JobId == dto.JobId);
+        if (entity == null) db.JobDatas.InsertOnSubmit(Convert.ToEntity(dto));
+        else Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
     }
 
     public void DeleteJobData(Guid id) {
-      var entity = db.JobDatas.FirstOrDefault(x => x.JobId == id); // check if all the byte[] is loaded into memory here. otherwise work around to delete without loading it
-      if (entity != null) db.JobDatas.DeleteOnSubmit(entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.JobDatas.FirstOrDefault(x => x.JobId == id); // check if all the byte[] is loaded into memory here. otherwise work around to delete without loading it
+        if (entity != null) db.JobDatas.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
     }
     #endregion
@@ -103,60 +128,79 @@
     #region HiveExperiment Methods
     public DT.HiveExperiment GetHiveExperiment(Guid id) {
-      return Convert.ToDto(db.HiveExperiments.SingleOrDefault(x => x.HiveExperimentId == id));
+      using (var db = CreateContext()) {
+        return Convert.ToDto(db.HiveExperiments.SingleOrDefault(x => x.HiveExperimentId == id));
+      }
     }
 
     public IEnumerable<DT.HiveExperiment> GetHiveExperiments(Expression<Func<HiveExperiment, bool>> predicate) {
-      return db.HiveExperiments.Where(predicate).Select(x => Convert.ToDto(x));
+      using (var db = CreateContext()) {
+        return db.HiveExperiments.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
+      }
     }
 
     public Guid AddHiveExperiment(DT.HiveExperiment dto) {
-      var entity = Convert.ToEntity(dto);
-      db.HiveExperiments.InsertOnSubmit(entity);
-      db.SubmitChanges();
-      return entity.HiveExperimentId;
+      using (var db = CreateContext()) {
+        var entity = Convert.ToEntity(dto);
+        db.HiveExperiments.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.HiveExperimentId;
+      }
     }
 
     public void UpdateHiveExperiment(DT.HiveExperiment dto) {
-      var entity = db.HiveExperiments.FirstOrDefault(x => x.HiveExperimentId == dto.Id);
-      if (entity == null) db.HiveExperiments.InsertOnSubmit(Convert.ToEntity(dto));
-      else Convert.ToEntity(dto, entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.HiveExperiments.FirstOrDefault(x => x.HiveExperimentId == dto.Id);
+        if (entity == null) db.HiveExperiments.InsertOnSubmit(Convert.ToEntity(dto));
+        else Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
     }
 
     public void DeleteHiveExperiment(Guid id) {
-      var entity = db.HiveExperiments.FirstOrDefault(x => x.HiveExperimentId == id);
-      if (entity != null) db.HiveExperiments.DeleteOnSubmit(entity);
-      db.SubmitChanges();
-    }
-    #endregion
-
+      using (var db = CreateContext()) {
+        var entity = db.HiveExperiments.FirstOrDefault(x => x.HiveExperimentId == id);
+        if (entity != null) db.HiveExperiments.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
+    #endregion
 
     #region Slave Methods
     public DT.Slave GetSlave(Guid id) {
-      return Convert.ToDto(db.Resources.OfType<Slave>().SingleOrDefault(x => x.ResourceId == id));
+      using (var db = CreateContext()) {
+        return Convert.ToDto(db.Resources.OfType<Slave>().SingleOrDefault(x => x.ResourceId == id));
+      }
     }
 
     public IEnumerable<DT.Slave> GetSlaves(Expression<Func<Slave, bool>> predicate) {
-      return db.Resources.OfType<Slave>().Where(predicate).Select(x => Convert.ToDto(x));
+      using (var db = CreateContext()) {
+        return db.Resources.OfType<Slave>().Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
+      }
     }
 
     public Guid AddSlave(DT.Slave dto) {
-      var entity = Convert.ToEntity(dto);
-      db.Resources.InsertOnSubmit(entity);
-      db.SubmitChanges();
-      return entity.ResourceId;
+      using (var db = CreateContext()) {
+        var entity = Convert.ToEntity(dto);
+        db.Resources.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.ResourceId;
+      }
     }
 
     public void UpdateSlave(DT.Slave dto) {
-      var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == dto.Id);
-      if (entity == null) db.Resources.InsertOnSubmit(Convert.ToEntity(dto));
-      else Convert.ToEntity(dto, entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == dto.Id);
+        if (entity == null) db.Resources.InsertOnSubmit(Convert.ToEntity(dto));
+        else Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
     }
 
     public void DeleteSlave(Guid id) {
-      var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == id);
-      if (entity != null) db.Resources.DeleteOnSubmit(entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == id);
+        if (entity != null) db.Resources.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
     }
     #endregion
@@ -164,29 +208,39 @@
     #region SlaveGroup Methods
     public DT.SlaveGroup GetSlaveGroup(Guid id) {
-      return Convert.ToDto(db.Resources.OfType<SlaveGroup>().SingleOrDefault(x => x.ResourceId == id));
+      using (var db = CreateContext()) {
+        return Convert.ToDto(db.Resources.OfType<SlaveGroup>().SingleOrDefault(x => x.ResourceId == id));
+      }
     }
 
     public IEnumerable<DT.SlaveGroup> GetSlaveGroups(Expression<Func<SlaveGroup, bool>> predicate) {
-      return db.Resources.OfType<SlaveGroup>().Where(predicate).Select(x => Convert.ToDto(x));
+      using (var db = CreateContext()) {
+        return db.Resources.OfType<SlaveGroup>().Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
+      }
     }
 
     public Guid AddSlaveGroup(DT.SlaveGroup dto) {
-      var entity = Convert.ToEntity(dto);
-      db.Resources.InsertOnSubmit(entity);
-      db.SubmitChanges();
-      return entity.ResourceId;
+      using (var db = CreateContext()) {
+        var entity = Convert.ToEntity(dto);
+        db.Resources.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.ResourceId;
+      }
     }
 
     public void UpdateSlaveGroup(DT.SlaveGroup dto) {
-      var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == dto.Id);
-      if (entity == null) db.Resources.InsertOnSubmit(Convert.ToEntity(dto));
-      else Convert.ToEntity(dto, entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == dto.Id);
+        if (entity == null) db.Resources.InsertOnSubmit(Convert.ToEntity(dto));
+        else Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
     }
 
     public void DeleteSlaveGroup(Guid id) {
-      var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == id);
-      if (entity != null) db.Resources.DeleteOnSubmit(entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == id);
+        if (entity != null) db.Resources.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
     }
     #endregion
@@ -194,29 +248,39 @@
     #region Resource Methods
     public DT.Resource GetResource(Guid id) {
-      return Convert.ToDto(db.Resources.SingleOrDefault(x => x.ResourceId == id));
+      using (var db = CreateContext()) {
+        return Convert.ToDto(db.Resources.SingleOrDefault(x => x.ResourceId == id));
+      }
     }
 
     public IEnumerable<DT.Resource> GetResources(Expression<Func<Resource, bool>> predicate) {
-      return db.Resources.Where(predicate).Select(x => Convert.ToDto(x));
+      using (var db = CreateContext()) {
+        return db.Resources.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
+      }
     }
 
     public Guid AddResource(DT.Resource dto) {
-      var entity = Convert.ToEntity(dto);
-      db.Resources.InsertOnSubmit(entity);
-      db.SubmitChanges();
-      return entity.ResourceId;
+      using (var db = CreateContext()) {
+        var entity = Convert.ToEntity(dto);
+        db.Resources.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.ResourceId;
+      }
     }
 
     public void UpdateResource(DT.Resource dto) {
-      var entity = db.Resources.FirstOrDefault(x => x.ResourceId == dto.Id);
-      if (entity == null) db.Resources.InsertOnSubmit(Convert.ToEntity(dto));
-      else Convert.ToEntity(dto, entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.Resources.FirstOrDefault(x => x.ResourceId == dto.Id);
+        if (entity == null) db.Resources.InsertOnSubmit(Convert.ToEntity(dto));
+        else Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
     }
 
     public void DeleteResource(Guid id) {
-      var entity = db.Resources.FirstOrDefault(x => x.ResourceId == id);
-      if (entity != null) db.Resources.DeleteOnSubmit(entity);
-      db.SubmitChanges();
+      using (var db = CreateContext()) {
+        var entity = db.Resources.FirstOrDefault(x => x.ResourceId == id);
+        if (entity != null) db.Resources.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
     }
     #endregion
@@ -224,12 +288,12 @@
     #region Authorization Methods
     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;
-      return userIds.All(x => x == userId);
-    }
-    #endregion
-
-
+      using (var db = CreateContext()) {
+        var userIds = from job in db.Jobs // this needs to be fast!
+                      where jobIds.Contains(job.JobId)
+                      select job.UserId;
+        return userIds.All(x => x == userId);
+      }
+    }
+    #endregion
   }
 }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml	(revision 4649)
@@ -70,13 +70,13 @@
       <Association Name="Resource_UptimeCalendar" Member="UptimeCalendars" ThisKey="ResourceId" OtherKey="ResourceId" Type="UptimeCalendar" />
       <Type Name="Slave" InheritanceCode="Slave" IsInheritanceDefault="true">
-        <Column Name="CPUSpeed" Type="System.Int32" DbType="Int" CanBeNull="true" />
+        <Column Name="CpuSpeed" Storage="_CPUSpeed" Type="System.Int32" DbType="Int" CanBeNull="true" />
         <Column Name="Memory" Type="System.Int32" DbType="Int" CanBeNull="true" />
         <Column Name="Login" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
-        <Column Name="Status" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
-        <Column Name="CalendarSyncStatus" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
+        <Column Name="SlaveState" Storage="_Status" Type="global::HeuristicLab.Services.Hive.Common.DataTransfer.SlaveState" DbType="VarChar(15)" CanBeNull="true" />
+        <Column Name="CalendarSyncState" Storage="_CalendarSyncStatus" Type="global::HeuristicLab.Services.Hive.Common.DataTransfer.CalendarState" DbType="VarChar(MAX)" CanBeNull="true" />
         <Column Name="UseCalendarFromResourceId" Type="System.Guid" DbType="UniqueIdentifier" CanBeNull="true" />
         <Column Name="SlaveConfigId" Type="System.Guid" DbType="UniqueIdentifier" CanBeNull="true" />
-        <Column Name="NumberOfCores" Type="System.Int32" DbType="Int" CanBeNull="true" />
-        <Column Name="NumberOfFreeCores" Type="System.Int32" DbType="Int" CanBeNull="true" />
+        <Column Name="Cores" Storage="_NumberOfCores" Type="System.Int32" DbType="Int" CanBeNull="true" />
+        <Column Name="FreeCores" Storage="_NumberOfFreeCores" Type="System.Int32" DbType="Int" CanBeNull="true" />
         <Column Name="FreeMemory" Type="System.Int32" DbType="Int" CanBeNull="true" />
         <Column Name="IsAllowedToCalculate" Type="System.Boolean" DbType="Bit" CanBeNull="false" />
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs	(revision 4649)
@@ -1569,7 +1569,7 @@
 		private System.Nullable<System.DateTime> _Login;
 		
-		private string _Status;
-		
-		private string _CalendarSyncStatus;
+		private global::HeuristicLab.Services.Hive.Common.DataTransfer.SlaveState _Status;
+		
+		private global::HeuristicLab.Services.Hive.Common.DataTransfer.CalendarState _CalendarSyncStatus;
 		
 		private System.Nullable<System.Guid> _UseCalendarFromResourceId;
@@ -1595,22 +1595,22 @@
     partial void OnValidate(System.Data.Linq.ChangeAction action);
     partial void OnCreated();
-    partial void OnCPUSpeedChanging(System.Nullable<int> value);
-    partial void OnCPUSpeedChanged();
+    partial void OnCpuSpeedChanging(System.Nullable<int> value);
+    partial void OnCpuSpeedChanged();
     partial void OnMemoryChanging(System.Nullable<int> value);
     partial void OnMemoryChanged();
     partial void OnLoginChanging(System.Nullable<System.DateTime> value);
     partial void OnLoginChanged();
-    partial void OnStatusChanging(string value);
-    partial void OnStatusChanged();
-    partial void OnCalendarSyncStatusChanging(string value);
-    partial void OnCalendarSyncStatusChanged();
+    partial void OnSlaveStateChanging(global::HeuristicLab.Services.Hive.Common.DataTransfer.SlaveState value);
+    partial void OnSlaveStateChanged();
+    partial void OnCalendarSyncStateChanging(global::HeuristicLab.Services.Hive.Common.DataTransfer.CalendarState value);
+    partial void OnCalendarSyncStateChanged();
     partial void OnUseCalendarFromResourceIdChanging(System.Nullable<System.Guid> value);
     partial void OnUseCalendarFromResourceIdChanged();
     partial void OnSlaveConfigIdChanging(System.Nullable<System.Guid> value);
     partial void OnSlaveConfigIdChanged();
-    partial void OnNumberOfCoresChanging(System.Nullable<int> value);
-    partial void OnNumberOfCoresChanged();
-    partial void OnNumberOfFreeCoresChanging(System.Nullable<int> value);
-    partial void OnNumberOfFreeCoresChanged();
+    partial void OnCoresChanging(System.Nullable<int> value);
+    partial void OnCoresChanged();
+    partial void OnFreeCoresChanging(System.Nullable<int> value);
+    partial void OnFreeCoresChanged();
     partial void OnFreeMemoryChanging(System.Nullable<int> value);
     partial void OnFreeMemoryChanged();
@@ -1628,5 +1628,5 @@
 		
 		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CPUSpeed", DbType="Int")]
-		public System.Nullable<int> CPUSpeed
+		public System.Nullable<int> CpuSpeed
 		{
 			get
@@ -1638,9 +1638,9 @@
 				if ((this._CPUSpeed != value))
 				{
-					this.OnCPUSpeedChanging(value);
+					this.OnCpuSpeedChanging(value);
 					this.SendPropertyChanging();
 					this._CPUSpeed = value;
-					this.SendPropertyChanged("CPUSpeed");
-					this.OnCPUSpeedChanged();
+					this.SendPropertyChanged("CpuSpeed");
+					this.OnCpuSpeedChanged();
 				}
 			}
@@ -1687,6 +1687,6 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Status", DbType="VarChar(MAX)")]
-		public string Status
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Status", DbType="VarChar(15)", CanBeNull=true)]
+		public global::HeuristicLab.Services.Hive.Common.DataTransfer.SlaveState SlaveState
 		{
 			get
@@ -1698,15 +1698,15 @@
 				if ((this._Status != value))
 				{
-					this.OnStatusChanging(value);
+					this.OnSlaveStateChanging(value);
 					this.SendPropertyChanging();
 					this._Status = value;
-					this.SendPropertyChanged("Status");
-					this.OnStatusChanged();
-				}
-			}
-		}
-		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CalendarSyncStatus", DbType="VarChar(MAX)")]
-		public string CalendarSyncStatus
+					this.SendPropertyChanged("SlaveState");
+					this.OnSlaveStateChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CalendarSyncStatus", DbType="VarChar(MAX)", CanBeNull=true)]
+		public global::HeuristicLab.Services.Hive.Common.DataTransfer.CalendarState CalendarSyncState
 		{
 			get
@@ -1718,9 +1718,9 @@
 				if ((this._CalendarSyncStatus != value))
 				{
-					this.OnCalendarSyncStatusChanging(value);
+					this.OnCalendarSyncStateChanging(value);
 					this.SendPropertyChanging();
 					this._CalendarSyncStatus = value;
-					this.SendPropertyChanged("CalendarSyncStatus");
-					this.OnCalendarSyncStatusChanged();
+					this.SendPropertyChanged("CalendarSyncState");
+					this.OnCalendarSyncStateChanged();
 				}
 			}
@@ -1772,5 +1772,5 @@
 		
 		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_NumberOfCores", DbType="Int")]
-		public System.Nullable<int> NumberOfCores
+		public System.Nullable<int> Cores
 		{
 			get
@@ -1782,9 +1782,9 @@
 				if ((this._NumberOfCores != value))
 				{
-					this.OnNumberOfCoresChanging(value);
+					this.OnCoresChanging(value);
 					this.SendPropertyChanging();
 					this._NumberOfCores = value;
-					this.SendPropertyChanged("NumberOfCores");
-					this.OnNumberOfCoresChanged();
+					this.SendPropertyChanged("Cores");
+					this.OnCoresChanged();
 				}
 			}
@@ -1792,5 +1792,5 @@
 		
 		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_NumberOfFreeCores", DbType="Int")]
-		public System.Nullable<int> NumberOfFreeCores
+		public System.Nullable<int> FreeCores
 		{
 			get
@@ -1802,9 +1802,9 @@
 				if ((this._NumberOfFreeCores != value))
 				{
-					this.OnNumberOfFreeCoresChanging(value);
+					this.OnFreeCoresChanging(value);
 					this.SendPropertyChanging();
 					this._NumberOfFreeCores = value;
-					this.SendPropertyChanged("NumberOfFreeCores");
-					this.OnNumberOfFreeCoresChanged();
+					this.SendPropertyChanged("FreeCores");
+					this.OnFreeCoresChanged();
 				}
 			}
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 4649)
@@ -27,11 +27,9 @@
 
     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();
+      var dao = new HiveDao();
+      using (var db = dao.CreateContext()) {
+        if (db.DatabaseExists())
+          db.DeleteDatabase();
+        db.CreateDatabase();
       }
     }
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/TransactionManager.cs
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/TransactionManager.cs	(revision 4649)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive.DataAccess/3.3/TransactionManager.cs	(revision 4649)
@@ -0,0 +1,23 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Services.Hive.Common;
+using System.Transactions;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Services.Hive.DataAccess {
+  public class TransactionManager {
+    public Disposable<TransactionScope> OpenTransaction() {
+      TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = ApplicationConstants.ISOLATION_LEVEL_SCOPE });
+      var disposable = new Disposable<TransactionScope>(transaction);
+      disposable.Disposing += disposable_Disposing;
+      return disposable;
+    }
+
+    void disposable_Disposing(object sender, EventArgs<TransactionScope> scope) {
+      scope.Value.Complete();
+      scope.Value.Dispose();
+    }
+  }
+}
Index: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/MergeConfigs.cmd
===================================================================
--- branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/MergeConfigs.cmd	(revision 4629)
+++ branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/MergeConfigs.cmd	(revision 4649)
@@ -6,5 +6,5 @@
 copy "%SolutionDir%HeuristicLab 3.3.exe.config" "%TargetDir%"
 
-%SolutionDir%ConfigMerger "%SolutionDir%HeuristicLab.Hive-3.3.dll.config" "HeuristicLab 3.3.exe.config"
-
-copy "HeuristicLab 3.3.exe.config" "%target%"
+%SolutionDir%ConfigMerger "%TargetDir%HeuristicLab.Hive-3.3.dll.config" "%TargetDir%HeuristicLab 3.3.exe.config"
+copy "%TargetDir%HeuristicLab 3.3.exe.config" "asdf.config"
+copy "%TargetDir%HeuristicLab 3.3.exe.config" "%target%"
