Index: trunk/sources/HeuristicLab.Core/3.3/Engine.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Engine.cs	(revision 3261)
+++ trunk/sources/HeuristicLab.Core/3.3/Engine.cs	(revision 3262)
@@ -22,115 +22,47 @@
 using System;
 using System.Collections.Generic;
-using System.Drawing;
 using System.Threading;
-using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Core {
-  /// <summary>
-  /// Base class to represent an engine, which is an interpreter, holding the code, the data and 
-  /// the actual state, which is the runtime stack and a pointer onto the next operation. It represents
-  /// one execution and can handle parallel executions.
-  /// </summary>
   [Item("Engine", "A base class for engines.")]
   [StorableClass]
-  public abstract class Engine : Item, IEngine {
-    public override Image ItemImage {
-      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event; }
-    }
-
-    [Storable]
-    private TimeSpan executionTime;
-    /// <summary>
-    /// Gets or sets the execution time.
-    /// </summary>
-    /// <remarks>Calls <see cref="OnExecutionTimeChanged"/> in the setter.</remarks>
-    public TimeSpan ExecutionTime {
-      get { return executionTime; }
-      protected set {
-        executionTime = value;
-        OnExecutionTimeChanged();
-      }
-    }
-
-    /// <summary>
-    /// Field of the current instance that represent the execution stack.
-    /// </summary>
+  public abstract class Engine : Executable, IEngine {
     [Storable]
     private Stack<IOperation> executionStack;
-    /// <summary>
-    /// Gets the current execution stack.
-    /// </summary>
     protected Stack<IOperation> ExecutionStack {
       get { return executionStack; }
     }
 
-    /// <summary>
-    /// Flag of the current instance whether it is currently running.
-    /// </summary>
-    private bool running;
-    /// <summary>
-    /// Gets information whether the instance is currently running.
-    /// </summary>
-    public bool Running {
-      get { return running; }
-      private set {
-        if (running != value) {
-          running = value;
-          OnRunningChanged();
-        }
-      }
+    private bool pausePending, stopPending;
+    private DateTime lastUpdateTime;
+    private System.Timers.Timer timer;
+
+    protected Engine()
+      : base() {
+      executionStack = new Stack<IOperation>();
+      pausePending = stopPending = false;
+      timer = new System.Timers.Timer(100);
+      timer.AutoReset = true;
+      timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
     }
 
-    /// <summary>
-    /// Flag of the current instance whether it is canceled.
-    /// </summary>
-    private bool canceled;
-    /// <summary>
-    /// Gets information whether the instance is currently canceled.
-    /// </summary>
-    protected bool Canceled {
-      get { return canceled; }
-      private set {
-        if (canceled != value) {
-          canceled = value;
-          OnCanceledChanged();
-        }
-      }
-    }
-    /// <summary>
-    /// Gets information whether the instance has already terminated.
-    /// </summary>
-    public bool Finished {
-      get { return executionStack.Count == 0; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of <see cref="EngineBase"/> with a new global scope.
-    /// </summary>
-    protected Engine() {
-      executionStack = new Stack<IOperation>();
-    }
-
-    /// <summary>
-    /// Clones the current instance (deep clone).
-    /// </summary>
-    /// <remarks>Deep clone through <see cref="cloner.Clone"/> method of helper class 
-    /// <see cref="Auxiliary"/>.</remarks>
-    /// <param name="clonedObjects">Dictionary of all already clone objects. (Needed to avoid cycles.)</param>
-    /// <returns>The cloned object as <see cref="EngineBase"/>.</returns>
     public override IDeepCloneable Clone(Cloner cloner) {
       Engine clone = (Engine)base.Clone(cloner);
-      clone.executionTime = executionTime;
       IOperation[] contexts = executionStack.ToArray();
       for (int i = contexts.Length - 1; i >= 0; i--)
         clone.executionStack.Push((IOperation)cloner.Clone(contexts[i]));
-      clone.running = running;
-      clone.canceled = canceled;
+      clone.pausePending = pausePending;
+      clone.stopPending = stopPending;
       return clone;
     }
 
+    public sealed override void Prepare() {
+      base.Prepare();
+      executionStack.Clear();
+      OnPrepared();
+    }
     public void Prepare(IOperation initialOperation) {
-      ExecutionTime = new TimeSpan();
+      base.Prepare();
       executionStack.Clear();
       if (initialOperation != null)
@@ -138,124 +70,45 @@
       OnPrepared();
     }
-    /// <inheritdoc/>
-    /// <remarks>Calls <see cref="ThreadPool.QueueUserWorkItem(System.Threading.WaitCallback, object)"/> 
-    /// of class <see cref="ThreadPool"/>.</remarks>
-    public void Start() {
+    public override void Start() {
+      base.Start();
       ThreadPool.QueueUserWorkItem(new WaitCallback(Run), null);
     }
-    /// <inheritdoc/>
-    /// <remarks>Calls <see cref="ThreadPool.QueueUserWorkItem(System.Threading.WaitCallback, object)"/> 
-    /// of class <see cref="ThreadPool"/>.</remarks>
-    public void Step() {
-      ThreadPool.QueueUserWorkItem(new WaitCallback(RunStep), null);
+    public override void Pause() {
+      base.Pause();
+      pausePending = true;
     }
-    /// <inheritdoc/>
-    /// <remarks>Sets the protected flag <c>myCanceled</c> to <c>true</c>.</remarks>
-    public void Stop() {
-      Canceled = true;
+    public override void Stop() {
+      base.Stop();
+      stopPending = true;
+      if (ExecutionState == ExecutionState.Paused) OnStopped();
     }
 
     private void Run(object state) {
       OnStarted();
-      Running = true;
-      Canceled = false;
-      DateTime start = DateTime.Now;
-      DateTime end;
-      while ((!Canceled) && (!Finished)) {
+      pausePending = stopPending = false;
+
+      lastUpdateTime = DateTime.Now;
+      timer.Start();
+      while (!pausePending && !stopPending && (executionStack.Count > 0)) {
         ProcessNextOperator();
-        end = DateTime.Now;
-        ExecutionTime += end - start;
-        start = end;
       }
-      ExecutionTime += DateTime.Now - start;
-      Canceled = false;
-      Running = false;
-      OnStopped();
-    }
-    private void RunStep(object state) {
-      OnStarted();
-      Running = true;
-      Canceled = false;
-      DateTime start = DateTime.Now;
-      if ((!Canceled) && (!Finished))
-        ProcessNextOperator();
-      ExecutionTime += DateTime.Now - start;
-      Canceled = false;
-      Running = false;
-      OnStopped();
+      timer.Stop();
+      ExecutionTime += DateTime.Now - lastUpdateTime;
+
+      if (pausePending) OnPaused();
+      else OnStopped();
     }
 
-    /// <summary>
-    /// Performs the next operation.
-    /// </summary>
     protected abstract void ProcessNextOperator();
 
-    /// <summary>
-    /// Occurs when the execution time changed.
-    /// </summary>
-    public event EventHandler ExecutionTimeChanged;
-    /// <summary>
-    /// Fires a new <c>ExecutionTimeChanged</c> event.
-    /// </summary>
-    protected virtual void OnExecutionTimeChanged() {
-      if (ExecutionTimeChanged != null)
-        ExecutionTimeChanged(this, EventArgs.Empty);
+    protected override void OnPrepared() {
+      if (executionStack.Count > 0) base.OnPrepared();
+      else base.OnStopped();
     }
-    /// <summary>
-    /// Occurs when the running flag changed.
-    /// </summary>
-    public event EventHandler RunningChanged;
-    /// <summary>
-    /// Fires a new <c>RunningChanged</c> event.
-    /// </summary>
-    protected virtual void OnRunningChanged() {
-      if (RunningChanged != null)
-        RunningChanged(this, EventArgs.Empty);
-    }
-    /// <summary>
-    /// Occurs when the execution is prepared for a new run.
-    /// </summary>
-    public event EventHandler Prepared;
-    /// <summary>
-    /// Fires a new <c>Prepared</c> event.
-    /// </summary>
-    protected virtual void OnPrepared() {
-      if (Prepared != null)
-        Prepared(this, EventArgs.Empty);
-    }
-    /// <summary>
-    /// Occurs when the execution is executed.
-    /// </summary>
-    public event EventHandler Started;
-    /// <summary>
-    /// Fires a new <c>Started</c> event.
-    /// </summary>
-    protected virtual void OnStarted() {
-      if (Started != null)
-        Started(this, EventArgs.Empty);
-    }
-    /// <summary>
-    /// Occurs when the execution is finished.
-    /// </summary>
-    public event EventHandler Stopped;
-    /// <summary>
-    /// Fires a new <c>Stopped</c> event.
-    /// </summary>
-    protected virtual void OnStopped() {
-      if (Stopped != null)
-        Stopped(this, EventArgs.Empty);
-    }
-    protected virtual void OnCanceledChanged() { }
-    /// <summary>
-    /// Occurs when an exception occured during the execution.
-    /// </summary>
-    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
-    /// <summary>
-    /// Aborts the execution and fires a new <c>ExceptionOccurred</c> event.
-    /// </summary>
-    /// <param name="exception">The exception that was thrown.</param>
-    protected virtual void OnExceptionOccurred(Exception exception) {
-      if (ExceptionOccurred != null)
-        ExceptionOccurred(this, new EventArgs<Exception>(exception));
+
+    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
+      DateTime now = DateTime.Now;
+      ExecutionTime += now - lastUpdateTime;
+      lastUpdateTime = now;
     }
   }
Index: trunk/sources/HeuristicLab.Core/3.3/Executable.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Executable.cs	(revision 3262)
+++ trunk/sources/HeuristicLab.Core/3.3/Executable.cs	(revision 3262)
@@ -0,0 +1,127 @@
+#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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Core {
+  [Item("Executable", "A base class for executables.")]
+  [StorableClass]
+  public abstract class Executable : Item, IExecutable {
+    public override Image ItemImage {
+      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event; }
+    }
+
+    [Storable]
+    private ExecutionState executionState;
+    public ExecutionState ExecutionState {
+      get { return executionState; }
+      private set {
+        if (executionState != value) {
+          executionState = value;
+          OnExecutionStateChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private TimeSpan executionTime;
+    public TimeSpan ExecutionTime {
+      get { return executionTime; }
+      protected set {
+        executionTime = value;
+        OnExecutionTimeChanged();
+      }
+    }
+
+    protected Executable() {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      Executable clone = (Executable)base.Clone(cloner);
+      clone.executionState = executionState;
+      clone.executionTime = executionTime;
+      return clone;
+    }
+
+    public virtual void Prepare() {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
+        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
+      ExecutionTime = TimeSpan.Zero;
+    }
+    public virtual void Start() {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
+    }
+    public virtual void Pause() {
+      if (ExecutionState != ExecutionState.Started)
+        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
+    }
+    public virtual void Stop() {
+      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
+    }
+
+    public event EventHandler ExecutionStateChanged;
+    protected virtual void OnExecutionStateChanged() {
+      EventHandler handler = ExecutionStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ExecutionTimeChanged;
+    protected virtual void OnExecutionTimeChanged() {
+      EventHandler handler = ExecutionTimeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Prepared;
+    protected virtual void OnPrepared() {
+      ExecutionState = ExecutionState.Prepared;
+      EventHandler handler = Prepared;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Started;
+    protected virtual void OnStarted() {
+      ExecutionState = ExecutionState.Started;
+      EventHandler handler = Started;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Paused;
+    protected virtual void OnPaused() {
+      ExecutionState = ExecutionState.Paused;
+      EventHandler handler = Paused;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Stopped;
+    protected virtual void OnStopped() {
+      ExecutionState = ExecutionState.Stopped;
+      EventHandler handler = Stopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+    protected virtual void OnExceptionOccurred(Exception exception) {
+      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
+      if (handler != null) handler(this, new EventArgs<Exception>(exception));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Core/3.3/ExecutionState.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/ExecutionState.cs	(revision 3262)
+++ trunk/sources/HeuristicLab.Core/3.3/ExecutionState.cs	(revision 3262)
@@ -0,0 +1,29 @@
+#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
+
+namespace HeuristicLab.Core {
+  public enum ExecutionState {
+    Prepared,
+    Started,
+    Paused,
+    Stopped
+  }
+}
Index: trunk/sources/HeuristicLab.Core/3.3/HeuristicLab.Core-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/HeuristicLab.Core-3.3.csproj	(revision 3261)
+++ trunk/sources/HeuristicLab.Core/3.3/HeuristicLab.Core-3.3.csproj	(revision 3262)
@@ -103,4 +103,7 @@
     <Compile Include="Attributes\CreatableAttribute.cs" />
     <None Include="HeuristicLabCorePlugin.cs.frame" />
+    <Compile Include="Executable.cs" />
+    <Compile Include="ExecutionState.cs" />
+    <Compile Include="Interfaces\IExecutable.cs" />
     <Compile Include="Interfaces\IParameterizedNamedItem.cs" />
     <Compile Include="Interfaces\IParameterizedItem.cs" />
Index: trunk/sources/HeuristicLab.Core/3.3/Interfaces/IEngine.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Interfaces/IEngine.cs	(revision 3261)
+++ trunk/sources/HeuristicLab.Core/3.3/Interfaces/IEngine.cs	(revision 3262)
@@ -24,65 +24,6 @@
 
 namespace HeuristicLab.Core {
-  /// <summary>
-  /// Interface to represent one run. (An engine is an interpreter, holding the code, 
-  /// the data and the actual state, which is the runtime stack and a pointer onto the next operation.).
-  /// It is responsible for operator execution and able to deal with parallelism.
-  /// </summary>
-  public interface IEngine : IItem {
-    /// <summary>
-    /// Gets the execution time of the current instance.
-    /// </summary>
-    TimeSpan ExecutionTime { get; }
-
-    /// <summary>
-    /// Gets information whether the engine is currently running.
-    /// </summary>
-    bool Running { get; }
-    /// <summary>
-    /// Gets information whether the engine has already terminated.
-    /// </summary>
-    bool Finished { get; }
-
-    /// <summary>
-    /// Prepares the engine with a given initial operation.
-    /// </summary>
+  public interface IEngine : IExecutable {
     void Prepare(IOperation initialOperation);
-    /// <summary>
-    /// Executes the whole run.
-    /// </summary>
-    void Start();
-    /// <summary>
-    /// Executes one step (one operation).
-    /// </summary>
-    void Step();
-    /// <summary>
-    /// Aborts the engine run.
-    /// </summary>
-    void Stop();
-
-    /// <summary>
-    /// Occurs when the execution time was changed.
-    /// </summary>
-    event EventHandler ExecutionTimeChanged;
-    /// <summary>
-    /// Occurs when the running flag was changed.
-    /// </summary>
-    event EventHandler RunningChanged;
-    /// <summary>
-    /// Occurs when the engine is prepared for a new run.
-    /// </summary>
-    event EventHandler Prepared;
-    /// <summary>
-    /// Occurs when the engine is executed.
-    /// </summary>
-    event EventHandler Started;
-    /// <summary>
-    /// Occurs when the engine is finished.
-    /// </summary>
-    event EventHandler Stopped;
-    /// <summary>
-    /// Occurs when an exception was thrown.
-    /// </summary>
-    event EventHandler<EventArgs<Exception>> ExceptionOccurred;
   }
 }
Index: trunk/sources/HeuristicLab.Core/3.3/Interfaces/IExecutable.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Interfaces/IExecutable.cs	(revision 3262)
+++ trunk/sources/HeuristicLab.Core/3.3/Interfaces/IExecutable.cs	(revision 3262)
@@ -0,0 +1,43 @@
+#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 HeuristicLab.Common;
+
+namespace HeuristicLab.Core {
+  public interface IExecutable : IItem {
+    ExecutionState ExecutionState { get; }
+    TimeSpan ExecutionTime { get; }
+
+    void Prepare();
+    void Start();
+    void Pause();
+    void Stop();
+
+    event EventHandler ExecutionStateChanged;
+    event EventHandler ExecutionTimeChanged;
+    event EventHandler Prepared;
+    event EventHandler Started;
+    event EventHandler Paused;
+    event EventHandler Stopped;
+    event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+  }
+}
