Index: branches/RuntimeOptimizer/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs
===================================================================
--- branches/RuntimeOptimizer/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs	(revision 8971)
+++ branches/RuntimeOptimizer/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs	(revision 8975)
@@ -175,5 +175,5 @@
       repetitions = 10;
       repetitionsCounter = 0;
-      Runs = new RunCollection { AlgorithmName = Name };
+      Runs = new RunCollection { OptimizerName = Name };
     }
     public BatchRun(string name)
@@ -185,5 +185,5 @@
       repetitions = 10;
       repetitionsCounter = 0;
-      Runs = new RunCollection { AlgorithmName = Name };
+      Runs = new RunCollection { OptimizerName = Name };
     }
     public BatchRun(string name, string description)
@@ -194,5 +194,5 @@
       repetitions = 10;
       repetitionsCounter = 0;
-      Runs = new RunCollection { AlgorithmName = Name };
+      Runs = new RunCollection { OptimizerName = Name };
     }
     [StorableConstructor]
@@ -237,6 +237,5 @@
         batchRunAction = BatchRunAction.Prepare;
         // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-        try { Optimizer.Prepare(clearRuns); }
-        catch (InvalidOperationException) { }
+        try { Optimizer.Prepare(clearRuns); } catch (InvalidOperationException) { }
       } else {
         ExecutionState = ExecutionState.Stopped;
@@ -250,6 +249,5 @@
       if (Optimizer.ExecutionState == ExecutionState.Stopped) Optimizer.Prepare();
       // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-      try { Optimizer.Start(); }
-      catch (InvalidOperationException) { }
+      try { Optimizer.Start(); } catch (InvalidOperationException) { }
     }
     public void Pause() {
@@ -260,6 +258,5 @@
       if (Optimizer.ExecutionState != ExecutionState.Started) return;
       // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-      try { Optimizer.Pause(); }
-      catch (InvalidOperationException) { }
+      try { Optimizer.Pause(); } catch (InvalidOperationException) { }
     }
     public void Stop() {
@@ -273,6 +270,5 @@
       }
       // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-      try { Optimizer.Stop(); }
-      catch (InvalidOperationException) { }
+      try { Optimizer.Stop(); } catch (InvalidOperationException) { }
     }
 
@@ -280,5 +276,5 @@
     protected override void OnNameChanged() {
       base.OnNameChanged();
-      runs.AlgorithmName = Name;
+      runs.OptimizerName = Name;
     }
 
Index: branches/RuntimeOptimizer/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs
===================================================================
--- branches/RuntimeOptimizer/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs	(revision 8971)
+++ branches/RuntimeOptimizer/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs	(revision 8975)
@@ -117,5 +117,5 @@
       executionTime = TimeSpan.Zero;
       optimizers = new OptimizerList();
-      Runs = new RunCollection { AlgorithmName = Name };
+      Runs = new RunCollection { OptimizerName = Name };
       Initialize();
     }
@@ -126,5 +126,5 @@
       executionTime = TimeSpan.Zero;
       optimizers = new OptimizerList();
-      Runs = new RunCollection { AlgorithmName = Name };
+      Runs = new RunCollection { OptimizerName = Name };
       Initialize();
     }
@@ -134,5 +134,5 @@
       executionTime = TimeSpan.Zero;
       optimizers = new OptimizerList();
-      Runs = new RunCollection { AlgorithmName = Name };
+      Runs = new RunCollection { OptimizerName = Name };
       Initialize();
     }
@@ -180,6 +180,5 @@
       foreach (IOptimizer optimizer in Optimizers.Where(x => x.ExecutionState != ExecutionState.Started)) {
         // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-        try { optimizer.Prepare(clearRuns); }
-        catch (InvalidOperationException) { }
+        try { optimizer.Prepare(clearRuns); } catch (InvalidOperationException) { }
       }
     }
@@ -194,6 +193,5 @@
       if (optimizer != null) {
         // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-        try { optimizer.Start(); }
-        catch (InvalidOperationException) { }
+        try { optimizer.Start(); } catch (InvalidOperationException) { }
       }
     }
@@ -207,6 +205,5 @@
       foreach (IOptimizer optimizer in Optimizers.Where(x => x.ExecutionState == ExecutionState.Started)) {
         // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-        try { optimizer.Pause(); }
-        catch (InvalidOperationException) { }
+        try { optimizer.Pause(); } catch (InvalidOperationException) { }
       }
     }
@@ -221,6 +218,5 @@
         foreach (var optimizer in Optimizers.Where(x => (x.ExecutionState == ExecutionState.Started) || (x.ExecutionState == ExecutionState.Paused))) {
           // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-          try { optimizer.Stop(); }
-          catch (InvalidOperationException) { }
+          try { optimizer.Stop(); } catch (InvalidOperationException) { }
         }
       } else {
@@ -232,5 +228,5 @@
     protected override void OnNameChanged() {
       base.OnNameChanged();
-      Runs.AlgorithmName = Name;
+      Runs.OptimizerName = Name;
     }
 
Index: branches/RuntimeOptimizer/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs
===================================================================
--- branches/RuntimeOptimizer/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs	(revision 8971)
+++ branches/RuntimeOptimizer/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs	(revision 8975)
@@ -25,7 +25,5 @@
 using System.Drawing;
 using System.Linq;
-using System.Threading;
 using System.Threading.Tasks;
-using System.Timers;
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
@@ -33,5 +31,4 @@
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using Timer = System.Timers.Timer;
 
 namespace HeuristicLab.Optimization {
@@ -56,10 +53,6 @@
     #endregion
 
-    private Timer snapTimer, runTimer;
-    private readonly ManualResetEvent algorithmStarted = new ManualResetEvent(false);
-    private readonly ManualResetEvent algorithmPaused = new ManualResetEvent(false);
-    private readonly ManualResetEvent algorithmStopped = new ManualResetEvent(false);
-    [Storable]
-    private bool snapshotTimesDirty;
+    private bool pausedForSnapshot = false;
+    private bool pausedForTermination = false;
 
     [Storable]
@@ -70,5 +63,4 @@
         if (maximumExecutionTime == value) return;
         maximumExecutionTime = value;
-        runTimer.Interval = (maximumExecutionTime - ExecutionTime).TotalMilliseconds;
         OnPropertyChanged("MaximumExecutionTime");
       }
@@ -84,5 +76,6 @@
         if (snapshotTimes == value) return;
         snapshotTimes = value;
-        snapshotTimesDirty = true;
+        snapshotTimes.Sort();
+        FindNextSnapshotTimeIndex(ExecutionTime);
         OnPropertyChanged("SnapshotTimes");
       }
@@ -131,10 +124,4 @@
         if (algorithm != null) {
           RegisterAlgorithmEvents();
-          if (algorithm.ExecutionState == ExecutionState.Started) algorithmStarted.Set();
-          else algorithmStarted.Reset();
-          if (algorithm.ExecutionState == ExecutionState.Paused) algorithmPaused.Set();
-          else algorithmPaused.Reset();
-          if (algorithm.ExecutionState == ExecutionState.Stopped) algorithmStopped.Set();
-          else algorithmStopped.Reset();
         }
         OnPropertyChanged("Algorithm");
@@ -173,23 +160,7 @@
       snapshotTimesIndex = original.snapshotTimesIndex;
       snapshots = cloner.Clone(original.snapshots);
-      snapshotTimesDirty = original.snapshotTimesDirty;
       storeAlgorithmInEachSnapshot = original.storeAlgorithmInEachSnapshot;
       algorithm = cloner.Clone(original.algorithm);
       runs = cloner.Clone(original.runs);
-
-      snapTimer = new Timer() {
-        AutoReset = original.snapTimer.AutoReset,
-        Interval = original.snapTimer.Interval
-      };
-      runTimer = new Timer() {
-        AutoReset = original.runTimer.AutoReset,
-        Interval = original.runTimer.Interval
-      };
-      if (original.algorithm != null && original.algorithm.ExecutionState == ExecutionState.Started)
-        algorithmStarted.Set();
-      if (original.algorithm != null && original.algorithm.ExecutionState == ExecutionState.Paused)
-        algorithmPaused.Set();
-      if (original.algorithm != null && original.algorithm.ExecutionState == ExecutionState.Stopped)
-        algorithmStopped.Set();
 
       Initialize();
@@ -199,22 +170,12 @@
       name = ItemName;
       description = ItemDescription;
-      maximumExecutionTime = TimeSpan.FromMinutes(1);
+      maximumExecutionTime = TimeSpan.FromMinutes(.5);
       snapshotTimes = new ObservableList<TimeSpan>(new[] {
           TimeSpan.FromSeconds(5),
           TimeSpan.FromSeconds(10),
-          TimeSpan.FromSeconds(30) });
+          TimeSpan.FromSeconds(15) });
       snapshotTimesIndex = 0;
-      snapTimer = new Timer() {
-        AutoReset = false,
-        Enabled = false,
-        Interval = 100
-      };
-      runTimer = new Timer() {
-        AutoReset = false,
-        Enabled = false,
-        Interval = MaximumExecutionTime.TotalMilliseconds
-      };
       snapshots = new RunCollection();
-      Runs = new RunCollection { AlgorithmName = Name };
+      Runs = new RunCollection { OptimizerName = Name };
       Initialize();
     }
@@ -222,44 +183,22 @@
       : base(name) {
       description = ItemDescription;
-      maximumExecutionTime = TimeSpan.FromMinutes(1);
+      maximumExecutionTime = TimeSpan.FromMinutes(.5);
       snapshotTimes = new ObservableList<TimeSpan>(new[] {
           TimeSpan.FromSeconds(5),
           TimeSpan.FromSeconds(10),
-          TimeSpan.FromSeconds(30) });
+          TimeSpan.FromSeconds(15) });
       snapshotTimesIndex = 0;
-      snapTimer = new Timer() {
-        AutoReset = false,
-        Enabled = false,
-        Interval = 100
-      };
-      snapshots = new RunCollection();
-      runTimer = new Timer() {
-        AutoReset = false,
-        Enabled = false,
-        Interval = MaximumExecutionTime.TotalMilliseconds
-      };
-      Runs = new RunCollection { AlgorithmName = Name };
+      Runs = new RunCollection { OptimizerName = Name };
       Initialize();
     }
     public TimeLimitRun(string name, string description)
       : base(name, description) {
-      maximumExecutionTime = TimeSpan.FromMinutes(1);
+      maximumExecutionTime = TimeSpan.FromMinutes(.5);
       snapshotTimes = new ObservableList<TimeSpan>(new[] {
           TimeSpan.FromSeconds(5),
           TimeSpan.FromSeconds(10),
-          TimeSpan.FromSeconds(30) });
+          TimeSpan.FromSeconds(15) });
       snapshotTimesIndex = 0;
-      snapTimer = new Timer() {
-        AutoReset = false,
-        Enabled = false,
-        Interval = 100
-      };
-      snapshots = new RunCollection();
-      runTimer = new Timer() {
-        AutoReset = false,
-        Enabled = false,
-        Interval = MaximumExecutionTime.TotalMilliseconds
-      };
-      Runs = new RunCollection { AlgorithmName = Name };
+      Runs = new RunCollection { OptimizerName = Name };
       Initialize();
     }
@@ -272,24 +211,4 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
-      // the timers will not be serialized
-      snapTimer = new Timer() {
-        AutoReset = false,
-        Enabled = false,
-        Interval = 100
-      };
-      runTimer = new Timer() {
-        AutoReset = false,
-        Enabled = false,
-        Interval = double.MaxValue
-      };
-      if (Algorithm != null && Algorithm.ExecutionState == ExecutionState.Started)
-        algorithmStarted.Set();
-      else algorithmStarted.Reset();
-      if (Algorithm != null && Algorithm.ExecutionState == ExecutionState.Paused)
-        algorithmPaused.Set();
-      else algorithmPaused.Reset();
-      if (Algorithm != null && Algorithm.ExecutionState == ExecutionState.Stopped)
-        algorithmStopped.Set();
-      else algorithmStopped.Reset();
       Initialize();
     }
@@ -302,44 +221,153 @@
       snapshotTimes.ItemsReplaced += snapshotTimes_Changed;
       snapshotTimes.CollectionReset += snapshotTimes_Changed;
-      snapTimer.Elapsed += snapshotTimer_Elapsed;
-      runTimer.Elapsed += runTimer_Elapsed;
-    }
-
-    private void snapshotTimes_Changed(object sender, EventArgs e) {
-      snapshotTimesDirty = true;
-    }
-
-    private readonly object snapshotLock = new object();
-    private void snapshotTimer_Elapsed(object sender, ElapsedEventArgs e) {
-      snapTimer.Stop();
-      lock (snapshotLock) {
-        try {
-          if (Algorithm == null) return;
-          if (ExecutionState != ExecutionState.Started) return;
-
-          var execTime = ExecutionTime;
-          if (snapshotTimesIndex < SnapshotTimes.Count &&
-              SnapshotTimes[snapshotTimesIndex] <= execTime) {
-            DoSnapshot();
-            snapshotTimesIndex++;
-            try {
-              Algorithm.Start();
-              algorithmStarted.WaitOne();
-            } catch (InvalidOperationException) { }
-          }
-        } catch { }
-        snapTimer.Start();
-      }
-    }
-
-    private void runTimer_Elapsed(object sender, ElapsedEventArgs e) {
-      snapTimer.Stop();
-      lock (snapshotLock) {
-        try {
-          Algorithm.Stop();
-          algorithmStopped.WaitOne();
-        } catch (InvalidOperationException) { }
-      }
-    }
+    }
+
+    private void snapshotTimes_Changed(object sender, CollectionItemsChangedEventArgs<IndexedItem<TimeSpan>> e) {
+      if (e.Items.Any()) snapshotTimes.Sort();
+      FindNextSnapshotTimeIndex(ExecutionTime);
+    }
+
+    public void Snapshot() {
+      if (Algorithm == null || Algorithm.ExecutionState != ExecutionState.Paused) throw new InvalidOperationException("Snapshot not allowed in execution states other than Paused");
+      Task.Factory.StartNew(MakeSnapshot);
+    }
+
+    public void Prepare() {
+      Prepare(false);
+    }
+    public void Prepare(bool clearRuns) {
+      Algorithm.Prepare(clearRuns);
+    }
+    public void Start() {
+      Algorithm.Start();
+    }
+    public void Pause() {
+      Algorithm.Pause();
+    }
+    public void Stop() {
+      Algorithm.Stop();
+    }
+
+    #region Events
+    protected override void OnNameChanged() {
+      base.OnNameChanged();
+      runs.OptimizerName = Name;
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    private void OnPropertyChanged(string property) {
+      var handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(property));
+    }
+
+    #region IExecutable Events
+    public event EventHandler ExecutionStateChanged;
+    private void OnExecutionStateChanged() {
+      var handler = ExecutionStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ExecutionTimeChanged;
+    private void OnExecutionTimeChanged() {
+      var handler = ExecutionTimeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Prepared;
+    private void OnPrepared() {
+      var handler = Prepared;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Started;
+    private void OnStarted() {
+      var handler = Started;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Paused;
+    private void OnPaused() {
+      var handler = Paused;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Stopped;
+    private void OnStopped() {
+      var handler = Stopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+    private void OnExceptionOccurred(Exception exception) {
+      var handler = ExceptionOccurred;
+      if (handler != null) handler(this, new EventArgs<Exception>(exception));
+    }
+    #endregion
+
+    #region Algorithm Events
+    private void RegisterAlgorithmEvents() {
+      algorithm.ExceptionOccurred += Algorithm_ExceptionOccurred;
+      algorithm.ExecutionTimeChanged += Algorithm_ExecutionTimeChanged;
+      algorithm.ExecutionStateChanged += Algorithm_ExecutionStateChanged;
+      algorithm.Paused += Algorithm_Paused;
+      algorithm.Prepared += Algorithm_Prepared;
+      algorithm.Started += Algorithm_Started;
+      algorithm.Stopped += Algorithm_Stopped;
+    }
+    private void DeregisterAlgorithmEvents() {
+      algorithm.ExceptionOccurred -= Algorithm_ExceptionOccurred;
+      algorithm.ExecutionTimeChanged -= Algorithm_ExecutionTimeChanged;
+      algorithm.ExecutionStateChanged -= Algorithm_ExecutionStateChanged;
+      algorithm.Paused -= Algorithm_Paused;
+      algorithm.Prepared -= Algorithm_Prepared;
+      algorithm.Started -= Algorithm_Started;
+      algorithm.Stopped -= Algorithm_Stopped;
+    }
+    private void Algorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      OnExceptionOccurred(e.Value);
+    }
+    private void Algorithm_ExecutionTimeChanged(object sender, EventArgs e) {
+      if (snapshotTimesIndex < SnapshotTimes.Count && ExecutionTime >= SnapshotTimes[snapshotTimesIndex]
+        && !pausedForSnapshot) {
+        pausedForSnapshot = true;
+        Algorithm.Pause();
+      }
+      if (ExecutionTime >= MaximumExecutionTime && !pausedForTermination) {
+        pausedForTermination = true;
+        if (!pausedForSnapshot) Algorithm.Pause();
+      }
+      OnExecutionTimeChanged();
+    }
+    private void Algorithm_ExecutionStateChanged(object sender, EventArgs e) {
+      OnExecutionStateChanged();
+    }
+    private void Algorithm_Paused(object sender, EventArgs e) {
+      var action = pausedForTermination ? ExecutionState.Stopped : (pausedForSnapshot ? ExecutionState.Started : ExecutionState.Paused);
+      if (pausedForSnapshot || pausedForTermination) {
+        pausedForSnapshot = pausedForTermination = false;
+        MakeSnapshot();
+        snapshotTimesIndex++;
+      }
+      OnPaused();
+      if (action == ExecutionState.Started) Algorithm.Start();
+      else if (action == ExecutionState.Stopped) Algorithm.Stop();
+    }
+    private void Algorithm_Prepared(object sender, EventArgs e) {
+      snapshotTimesIndex = 0;
+      snapshots.Clear();
+      OnPrepared();
+    }
+    private void Algorithm_Started(object sender, EventArgs e) {
+      OnStarted();
+    }
+    private void Algorithm_Stopped(object sender, EventArgs e) {
+      var cloner = new Cloner();
+      var algRun = cloner.Clone(Algorithm.Runs.Last());
+      var clonedSnapshots = cloner.Clone(snapshots);
+      try {
+        algRun.Results.Add("Snapshots", clonedSnapshots);
+      } catch (ArgumentException ex) { // Snapshots already exists
+        // TODO strategy?
+      }
+      Runs.Add(algRun);
+      Algorithm.Runs.Clear();
+      OnStopped();
+    }
+    #endregion
+    #endregion
 
     private void FindNextSnapshotTimeIndex(TimeSpan reference) {
@@ -349,26 +377,4 @@
       };
       snapshotTimesIndex = index;
-    }
-
-    private void DoSnapshot() {
-      lock (snapshotLock) {
-        var wasPaused = Algorithm.ExecutionState == ExecutionState.Paused;
-        var error = false;
-        try {
-          Algorithm.Pause();
-          algorithmPaused.WaitOne();
-        } catch (InvalidOperationException) {
-          error = true;
-        }
-        if (error && ExecutionState != ExecutionState.Paused) return; // Algorithm is either stopped or prepared
-
-        MakeSnapshot();
-        if (!wasPaused) {
-          try {
-            Algorithm.Start();
-            algorithmStarted.WaitOne();
-          } catch (InvalidOperationException) { }
-        }
-      }
     }
 
@@ -397,157 +403,4 @@
       snapshots.Add(run);
     }
-
-    public void Snapshot() {
-      Task.Factory.StartNew(DoSnapshot);
-    }
-
-    public void Prepare() {
-      Prepare(false);
-    }
-    public void Prepare(bool clearRuns) {
-      Algorithm.Prepare(clearRuns);
-    }
-    public void Start() {
-      Algorithm.Start();
-    }
-    public void Pause() {
-      Algorithm.Pause();
-    }
-    public void Stop() {
-      Algorithm.Stop();
-    }
-
-    #region Events
-    protected override void OnNameChanged() {
-      base.OnNameChanged();
-      runs.AlgorithmName = Name;
-    }
-
-    public event PropertyChangedEventHandler PropertyChanged;
-    private void OnPropertyChanged(string property) {
-      var handler = PropertyChanged;
-      if (handler != null) handler(this, new PropertyChangedEventArgs(property));
-    }
-
-    #region IExecutable Events
-    public event EventHandler ExecutionStateChanged;
-    private void OnExecutionStateChanged() {
-      var handler = ExecutionStateChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-    public event EventHandler ExecutionTimeChanged;
-    private void OnExecutionTimeChanged() {
-      var handler = ExecutionTimeChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-    public event EventHandler Prepared;
-    private void OnPrepared() {
-      var handler = Prepared;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-    public event EventHandler Started;
-    private void OnStarted() {
-      var handler = Started;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-    public event EventHandler Paused;
-    private void OnPaused() {
-      var handler = Paused;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-    public event EventHandler Stopped;
-    private void OnStopped() {
-      var handler = Stopped;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
-    private void OnExceptionOccurred(Exception exception) {
-      var handler = ExceptionOccurred;
-      if (handler != null) handler(this, new EventArgs<Exception>(exception));
-    }
-    #endregion
-
-    #region Algorithm Events
-    private void RegisterAlgorithmEvents() {
-      algorithm.ExceptionOccurred += Algorithm_ExceptionOccurred;
-      algorithm.ExecutionTimeChanged += Algorithm_ExecutionTimeChanged;
-      algorithm.ExecutionStateChanged += Algorithm_ExecutionStateChanged;
-      algorithm.Paused += Algorithm_Paused;
-      algorithm.Prepared += Algorithm_Prepared;
-      algorithm.Started += Algorithm_Started;
-      algorithm.Stopped += Algorithm_Stopped;
-    }
-    private void DeregisterAlgorithmEvents() {
-      algorithm.ExceptionOccurred -= Algorithm_ExceptionOccurred;
-      algorithm.ExecutionTimeChanged -= Algorithm_ExecutionTimeChanged;
-      algorithm.ExecutionStateChanged -= Algorithm_ExecutionStateChanged;
-      algorithm.Paused -= Algorithm_Paused;
-      algorithm.Prepared -= Algorithm_Prepared;
-      algorithm.Started -= Algorithm_Started;
-      algorithm.Stopped -= Algorithm_Stopped;
-    }
-    private void Algorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
-      OnExceptionOccurred(e.Value);
-    }
-    private void Algorithm_ExecutionTimeChanged(object sender, EventArgs e) {
-      OnExecutionTimeChanged();
-    }
-    private void Algorithm_ExecutionStateChanged(object sender, EventArgs e) {
-      OnExecutionStateChanged();
-    }
-    private void Algorithm_Paused(object sender, EventArgs e) {
-      algorithmStarted.Reset();
-      algorithmPaused.Set();
-      algorithmStopped.Reset();
-      OnPaused();
-    }
-    private void Algorithm_Prepared(object sender, EventArgs e) {
-      algorithmStarted.Reset();
-      algorithmPaused.Reset();
-      algorithmStopped.Reset();
-      snapTimer.Stop();
-      runTimer.Stop();
-      snapshotTimesIndex = 0;
-      snapshots.Clear();
-      OnPrepared();
-    }
-    private void Algorithm_Started(object sender, EventArgs e) {
-      algorithmStarted.Set();
-      algorithmPaused.Reset();
-      algorithmStopped.Reset();
-      var execTime = ExecutionTime;
-      if (snapshotTimesDirty) {
-        SnapshotTimes.Sort();
-        snapshotTimesDirty = false; // sort will mark it dirty again
-        FindNextSnapshotTimeIndex(execTime);
-      }
-      runTimer.Interval = (MaximumExecutionTime - execTime).TotalMilliseconds;
-      snapTimer.Start();
-      runTimer.Start();
-      OnStarted();
-    }
-    private void Algorithm_Stopped(object sender, EventArgs e) {
-      algorithmStarted.Reset();
-      algorithmPaused.Reset();
-      algorithmStopped.Set();
-      lock (snapshotLock) {
-        snapTimer.Stop();
-        runTimer.Stop();
-        MakeSnapshot();
-      }
-      var cloner = new Cloner();
-      var algRun = cloner.Clone(Algorithm.Runs.Last());
-      var clonedSnapshots = cloner.Clone(snapshots);
-      try {
-        algRun.Results.Add("Snapshots", clonedSnapshots);
-      } catch (ArgumentException ex) {
-        // TODO strategy?
-      }
-      Runs.Add(algRun);
-      Algorithm.Runs.Clear();
-      OnStopped();
-    }
-    #endregion
-    #endregion
   }
 }
