Index: branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/HeuristicLab.Hive.Experiment-3.3.csproj
===================================================================
--- branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/HeuristicLab.Hive.Experiment-3.3.csproj	(revision 4116)
+++ branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/HeuristicLab.Hive.Experiment-3.3.csproj	(revision 4119)
@@ -42,8 +42,15 @@
     <PlatformTarget>AnyCPU</PlatformTarget>
     <OutputPath>bin\Debug\</OutputPath>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
     <PlatformTarget>AnyCPU</PlatformTarget>
     <OutputPath>bin\Release\</OutputPath>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
@@ -89,4 +96,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="OptimizerJob.cs" />
     <Compile Include="HeuristicLabHiveExperimentPlugin.cs" />
     <Compile Include="HiveExperiment.cs" />
@@ -102,4 +110,5 @@
   <ItemGroup>
     <None Include="app.config" />
+    <None Include="HeuristicLab.snk" />
     <None Include="Properties\AssemblyInfo.frame" />
     <None Include="Properties\Settings.settings">
@@ -112,4 +121,8 @@
       <Project>{134F93D7-E7C8-4ECD-9923-7F63259A60D8}</Project>
       <Name>HeuristicLab.Hive.Contracts-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Hive.JobBase\3.3\HeuristicLab.Hive.JobBase-3.3.csproj">
+      <Project>{21187322-52DD-4243-80A4-A85F0263E63B}</Project>
+      <Name>HeuristicLab.Hive.JobBase-3.3</Name>
     </ProjectReference>
   </ItemGroup>
Index: branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/HiveExperiment.cs
===================================================================
--- branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/HiveExperiment.cs	(revision 4116)
+++ branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/HiveExperiment.cs	(revision 4119)
@@ -38,4 +38,7 @@
 using System.Threading;
 using HeuristicLab.Tracing;
+using HeuristicLab.Hive.JobBase;
+using System.Diagnostics;
+using System.Collections;
 
 namespace HeuristicLab.Hive.Experiment {
@@ -50,9 +53,14 @@
     private const string itemDescription = "An experiment which contains multiple batch runs of algorithms which are executed in the Hive.";
     private const int resultPollingIntervalMs = 10000;
+
     private const int maxSnapshotRetries = 20;
 
-    private IDictionary<Guid, SerializedJob> jobs = null;
+    [Storable]
+    private IDictionary<Guid, IOptimizer> sentOptimizers = null;
+
     private object locker = new object();
-
+    private DateTime startTime;
+
+    [Storable]
     private string serverUrl;
     public string ServerUrl {
@@ -60,10 +68,6 @@
       set { serverUrl = value; OnServerUrlChanged(); }
     }
-    public event EventHandler ServerUrlChanged;
-    protected virtual void OnServerUrlChanged() {
-      EventHandler handler = ServerUrlChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-
+
+    [Storable]
     private string resourceIds;
     public string ResourceIds {
@@ -71,8 +75,34 @@
       set { resourceIds = value; OnResourceIdsChanged(); }
     }
-    public event EventHandler ResourceIdsChanged;
-    protected virtual void OnResourceIdsChanged() {
-      EventHandler handler = ResourceIdsChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
+
+    [Storable]
+    private HeuristicLab.Optimization.Experiment experiment;
+    public HeuristicLab.Optimization.Experiment Experiment {
+      get { return experiment; }
+      set { experiment = value; OnExperimentChanged(); }
+    }
+
+    [StorableConstructor]
+    public HiveExperiment(bool deserializing)
+      : base(deserializing) {
+    }
+
+    public HiveExperiment()
+      : base(itemName, itemDescription) {
+      this.ServerUrl = HeuristicLab.Hive.Experiment.Properties.Settings.Default.HiveServerUrl;
+      this.ResourceIds = HeuristicLab.Hive.Experiment.Properties.Settings.Default.ResourceIds;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      HiveExperiment clone = (HiveExperiment)base.Clone(cloner);
+      clone.resourceIds = this.resourceIds;
+      clone.serverUrl = this.serverUrl;
+      clone.experiment = (HeuristicLab.Optimization.Experiment)cloner.Clone(experiment);
+      clone.executionState = this.executionState;
+      clone.executionTime = this.executionTime;
+      clone.sentOptimizers = new Dictionary<Guid, IOptimizer>();
+      foreach (var pair in this.sentOptimizers)
+        clone.sentOptimizers[pair.Key] = (IOptimizer)cloner.Clone(pair.Value);
+      return clone;
     }
 
@@ -86,37 +116,27 @@
       }
     }
-
-    private HeuristicLab.Optimization.Experiment experiment;
-    public HeuristicLab.Optimization.Experiment Experiment {
-      get { return experiment; }
-      set { experiment = value; OnExperimentChanged(); }
-    }
-    public event EventHandler ExperimentChanged;
-    protected virtual void OnExperimentChanged() {
-      EventHandler handler = ExperimentChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-
-    public HiveExperiment()
-      : base(itemName, itemDescription) {
-      this.ServerUrl = HeuristicLab.Hive.Experiment.Properties.Settings.Default.HiveServerUrl;
-      this.ResourceIds = HeuristicLab.Hive.Experiment.Properties.Settings.Default.ResourceIds;
-    }
-
     #region IExecutable Members
 
-    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
-
+    [Storable]
+    private Core.ExecutionState executionState;
     public ExecutionState ExecutionState {
-      get { return Core.ExecutionState.Stopped; } // [chn] todo 
-    }
-
-    public event EventHandler ExecutionStateChanged;
-
+      get { return executionState; }
+      private set {
+        if (executionState != value) {
+          executionState = value;
+          OnExecutionStateChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private TimeSpan executionTime;
     public TimeSpan ExecutionTime {
-      get { return new TimeSpan(); } // [chn] todo 
-    }
-
-    public event EventHandler ExecutionTimeChanged;
+      get { return executionTime; }
+      private set {
+        executionTime = value;
+        OnExecutionTimeChanged();
+      }
+    }
 
     public void Pause() {
@@ -124,32 +144,27 @@
     }
 
-    public event EventHandler Paused;
-
     public void Prepare() {
-
-    }
-
-    public event EventHandler Prepared;
+      // [chn] needed?
+      if (experiment != null) {
+        experiment.Prepare();
+        OnPrepared();
+      }
+    }
 
     public void Start() {
+      this.startTime = DateTime.Now;
+      this.ExecutionState = Core.ExecutionState.Started;
       IExecutionEngineFacade executionEngineFacade = ServiceLocator.CreateExecutionEngineFacade(ServerUrl);
 
-      IList<SerializedJob> serializedJobs = new List<SerializedJob>();
+      sentOptimizers = new Dictionary<Guid, IOptimizer>();
+      IEnumerable<string> groups = ResourceGroups;
+
       foreach (IOptimizer optimizer in Experiment.Optimizers) {
-        serializedJobs.Add(CreateJob(optimizer));
-      }
-
-      jobs = new Dictionary<Guid, SerializedJob>();
-
-      IEnumerable<string> groups = ResourceGroups;
-      foreach (SerializedJob job in serializedJobs) {
-        ResponseObject<JobDto> response = executionEngineFacade.AddJobWithGroupStrings(job, groups);
-        
-        jobs.Add(response.Obj.Id, job);
+        SerializedJob serializedJob = CreateSerializedJob(optimizer);
+        ResponseObject<JobDto> response = executionEngineFacade.AddJobWithGroupStrings(serializedJob, groups);
+        sentOptimizers.Add(response.Obj.Id, optimizer);
         StartResultPollingThread(response.Obj);
       }
     }
-
-    public event EventHandler Started;
 
     public void Stop() {
@@ -157,13 +172,18 @@
     }
 
-    public event EventHandler Stopped;
     private bool abortRequested;
 
     #endregion
 
-    private SerializedJob CreateJob(IOptimizer optimizer) {
-      // serialize optimizer
+    private SerializedJob CreateSerializedJob(IOptimizer optimizer) {
+      IJob job = new OptimizerJob() {
+        Optimizer = optimizer
+      };
+
+      // serialize job
       MemoryStream memStream = new MemoryStream();
-      XmlGenerator.Serialize(optimizer, memStream);
+      XmlGenerator.Serialize(job, memStream);
+      byte[] jobByteArray = memStream.ToArray();
+      memStream.Dispose();
 
       // find out which which plugins are needed for the given object
@@ -172,6 +192,5 @@
         select new HivePluginInfoDto() {
           Name = p.Name,
-          Version = p.Version,
-          BuildDate = p.BuildDate,
+          Version = p.Version
         }).ToList();
 
@@ -186,7 +205,6 @@
       SerializedJob serializedJob = new SerializedJob() {
         JobInfo = jobDto,
-        SerializedJobData = memStream.ToArray()
+        SerializedJobData = jobByteArray
       };
-      memStream.Dispose();
 
       return serializedJob;
@@ -196,5 +214,5 @@
       Thread t = new Thread(() => {
         IExecutionEngineFacade executionEngineFacade = ServiceLocator.CreateExecutionEngineFacade(ServerUrl);
-        IOptimizer restoredObject = null;
+        IJob restoredObject = null;
 
         do {
@@ -211,18 +229,30 @@
             // 4. the result that we get from the server is a snapshot and not the final result
             if (response.Success && response.Obj != null && response.StatusMessage != ApplicationConstants.RESPONSE_JOB_RESULT_NOT_YET_HERE) {
-              
+
               // [chn] todo: deserialization into interface is not possible! how to find out correct static type?
-              restoredObject = XmlParser.Deserialize<IOptimizer>(new MemoryStream(response.Obj.SerializedJobData));
+              restoredObject = XmlParser.Deserialize<IJob>(new MemoryStream(response.Obj.SerializedJobData));
             }
           }
-        } while (restoredObject == null || restoredObject.ExecutionState == Core.ExecutionState.Stopped);
+        } while (restoredObject == null || restoredObject.ExecutionState != Core.ExecutionState.Stopped);
 
         // job retrieved... replace the existing optimizers with the finished one
-        // todo
+        IOptimizer originalOptimizer = sentOptimizers[job.Id];
+        IOptimizer restoredOptimizer = ((OptimizerJob)restoredObject).Optimizer;
+
+        int originalOptimizerIndex = experiment.Optimizers.IndexOf(originalOptimizer);
+        experiment.Optimizers[originalOptimizerIndex] = restoredOptimizer;
+        sentOptimizers.Remove(job.Id);
+
+        if (sentOptimizers.Count == 0) {
+          // finished
+          this.ExecutionState = Core.ExecutionState.Stopped;
+          OnStopped();
+        }
       });
-      
+
       Logger.Debug("HiveEngine: Starting results-polling thread");
       t.Start();
     }
+
 
     #region Required Plugin Search
@@ -310,4 +340,65 @@
     }
     #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() {
+      EventHandler handler = ExecutionStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+
+    public event EventHandler Started;
+    private void OnStarted() {
+      EventHandler handler = Started;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Stopped;
+    private void OnStopped() {
+      EventHandler handler = Stopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Paused;
+    private void OnPaused() {
+      EventHandler handler = Paused;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Prepared;
+    protected virtual void OnPrepared() {
+      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 ExperimentChanged;
+    protected virtual void OnExperimentChanged() {
+      EventHandler handler = ExperimentChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler ServerUrlChanged;
+    protected virtual void OnServerUrlChanged() {
+      EventHandler handler = ServerUrlChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+
+    #endregion
   }
 }
Index: branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/OptimizerJob.cs
===================================================================
--- branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/OptimizerJob.cs	(revision 4119)
+++ branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/OptimizerJob.cs	(revision 4119)
@@ -0,0 +1,106 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Hive.JobBase;
+using HeuristicLab.Optimization;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Hive.Experiment {
+  [StorableClass]
+  class OptimizerJob : IJob {
+
+    [Storable]
+    private IOptimizer optimizer;
+    public IOptimizer Optimizer {
+      get { return optimizer;  }
+      set {
+        if (optimizer != null && value != optimizer) {
+          DeregisterEvents();
+        }
+        optimizer = value;
+        if (optimizer != null) {
+          RegisterEvents();
+        }
+      }
+    }
+
+    [Storable]
+    private double progress = 0.0;
+
+    public OptimizerJob() {
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    #region IJob Members
+
+    public long JobId {
+      get;
+      set;
+    }
+
+    public double Progress {
+      get { return optimizer.ExecutionState == ExecutionState.Stopped ? 1.0 : this.progress; }
+    }
+
+    public ExecutionState ExecutionState {
+      get { return optimizer.ExecutionState; }
+    }
+
+    public void Run() {
+      throw new NotSupportedException();
+    }
+
+    // [chn] needed?
+    public void Prepare(Core.IOperation initialOperation) {
+      throw new NotImplementedException(); 
+    }
+
+    public void Start() {
+      optimizer.Start();
+    }
+
+    public void Stop() {
+      optimizer.Stop();
+    }
+
+    public event EventHandler JobStopped;
+
+    public event EventHandler JobFailed;
+
+    #endregion
+
+    #region Events
+    private void RegisterEvents() {
+      optimizer.Stopped += new EventHandler(optimizer_Stopped);
+      optimizer.ExceptionOccurred += new EventHandler<Common.EventArgs<Exception>>(optimizer_ExceptionOccurred);
+    }
+
+    private void DeregisterEvents() {
+      optimizer.Stopped -= new EventHandler(optimizer_Stopped);
+      optimizer.ExceptionOccurred -= new EventHandler<Common.EventArgs<Exception>>(optimizer_ExceptionOccurred);
+    }
+
+    void optimizer_ExceptionOccurred(object sender, Common.EventArgs<Exception> e) {
+      if (optimizer.ExecutionState != ExecutionState.Stopped) this.progress = 0.0;
+      else this.progress = 1.0;
+      EventHandler handler = JobFailed;
+      if (handler != null) handler(this, e);
+    }
+
+    void optimizer_Stopped(object sender, EventArgs e) {
+      if (optimizer.ExecutionState != ExecutionState.Stopped) this.progress = 0.0;
+      else this.progress = 1.0;
+      EventHandler handler = JobStopped;
+      if (handler != null) handler(this, e);
+    }
+    #endregion
+
+
+  }
+}
Index: branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/Properties/AssemblyInfo.cs
===================================================================
--- branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/Properties/AssemblyInfo.cs	(revision 4116)
+++ branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Experiment/3.3/Properties/AssemblyInfo.cs	(revision 4119)
@@ -55,5 +55,5 @@
 // You can specify all the values or you can default the Revision and Build Numbers 
 // by using the '*' as shown below:
-[assembly: AssemblyVersion("3.3.0.4111")]
-[assembly: AssemblyFileVersion("3.3.0.4111")]
-[assembly: AssemblyBuildDate("2010/07/27 18:31:34")]
+[assembly: AssemblyVersion("3.3.0.4116")]
+[assembly: AssemblyFileVersion("3.3.0.4116")]
+[assembly: AssemblyBuildDate("2010/07/28 17:42:02")]
