Index: stable/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- stable/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 13199)
+++ stable/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 13282)
@@ -163,4 +163,6 @@
     <Compile Include="Interfaces\ISimilarityBasedOperator.cs" />
     <Compile Include="Interfaces\ISolutionSimilarityCalculator.cs" />
+    <Compile Include="Interfaces\ITerminationBasedOperator.cs" />
+    <Compile Include="Interfaces\ITerminator.cs" />
     <Compile Include="MetaOptimizers\BatchRun.cs" />
     <Compile Include="MetaOptimizers\Experiment.cs" />
@@ -173,4 +175,11 @@
     <Compile Include="RunCollectionModification\RunCollectionValueRemover.cs" />
     <Compile Include="Interfaces\IRunCollectionModifier.cs" />
+    <Compile Include="Termination\ComparisonTerminator.cs" />
+    <Compile Include="Termination\ExecutionTimeTerminator.cs" />
+    <Compile Include="Termination\MultiTerminator.cs" />
+    <Compile Include="Termination\SingleObjectiveQualityTerminator.cs" />
+    <Compile Include="Termination\TerminationOperator.cs" />
+    <Compile Include="Termination\Terminator.cs" />
+    <Compile Include="Termination\ThresholdTerminator.cs" />
     <None Include="Plugin.cs.frame" />
     <Compile Include="Algorithms\Algorithm.cs" />
Index: stable/HeuristicLab.Optimization/3.3/Interfaces/ITerminationBasedOperator.cs
===================================================================
--- stable/HeuristicLab.Optimization/3.3/Interfaces/ITerminationBasedOperator.cs	(revision 13282)
+++ stable/HeuristicLab.Optimization/3.3/Interfaces/ITerminationBasedOperator.cs	(revision 13282)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface ITerminationBasedOperator : IOperator {
+    ILookupParameter<BoolValue> TerminateParameter { get; }
+  }
+}
Index: stable/HeuristicLab.Optimization/3.3/Interfaces/ITerminator.cs
===================================================================
--- stable/HeuristicLab.Optimization/3.3/Interfaces/ITerminator.cs	(revision 13282)
+++ stable/HeuristicLab.Optimization/3.3/Interfaces/ITerminator.cs	(revision 13282)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for checking a termination criterion.
+  /// </summary>
+  public interface ITerminator : ITerminationBasedOperator {
+  }
+}
Index: stable/HeuristicLab.Optimization/3.3/Termination/ComparisonTerminator.cs
===================================================================
--- stable/HeuristicLab.Optimization/3.3/Termination/ComparisonTerminator.cs	(revision 13282)
+++ stable/HeuristicLab.Optimization/3.3/Termination/ComparisonTerminator.cs	(revision 13282)
@@ -0,0 +1,135 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("ComparisonTerminator", "An termination criterion which compares two values.")]
+  [StorableClass]
+  public class ComparisonTerminator<T> : ThresholdTerminator<T> where T : class, IItem, IComparable, IStringConvertibleValue, new() {
+    public ILookupParameter<T> ComparisonValueParameter {
+      get { return (ILookupParameter<T>)Parameters["ComparisonValue"]; }
+    }
+
+    private IFixedValueParameter<Comparison> ComparisonParameter {
+      get { return (IFixedValueParameter<Comparison>)Parameters["Comparison"]; }
+    }
+
+    public ComparisonType ComparisonType {
+      get { return ComparisonParameter.Value.Value; }
+      set { ComparisonParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected ComparisonTerminator(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+    protected ComparisonTerminator(ComparisonTerminator<T> original, Cloner cloner)
+      : base(original, cloner) {
+      Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ComparisonTerminator<T>(this, cloner);
+    }
+
+    public ComparisonTerminator()
+      : this(new T()) { }
+    public ComparisonTerminator(T threshold)
+      : base(threshold) {
+      Parameters.Add(new LookupParameter<T>("ComparisonValue", "The left side value of the comparison.") { Hidden = false });
+      Parameters.Add(new FixedValueParameter<Comparison>("Comparison", "The type of comparison."));
+      Initialize();
+    }
+    public ComparisonTerminator(string comparisonValueActualName, ComparisonType comparisonType, T threshold)
+      : this(threshold) {
+      ComparisonValueParameter.ActualName = comparisonValueActualName;
+      ComparisonType = comparisonType;
+    }
+    public ComparisonTerminator(string comparisonValueActualName, ComparisonType comparisonType, IFixedValueParameter<T> thresholdParameter)
+      : this() {
+      ComparisonValueParameter.ActualName = comparisonValueActualName;
+      ComparisonType = comparisonType;
+      ThresholdParameter = thresholdParameter;
+    }
+
+    protected override bool CheckContinueCriterion() {
+      IComparable lhs = ComparisonValueParameter.ActualValue;
+      IComparable rhs = ThresholdParameter.Value;
+
+      return ComparisonType.Compare(lhs, rhs);
+    }
+
+    private void Initialize() {
+      ComparisonParameter.Value.ValueChanged += new EventHandler(ComparisonType_ValueChanged);
+    }
+    private void ComparisonType_ValueChanged(object sender, EventArgs e) {
+      OnComparisonTypeChanged();
+    }
+    protected virtual void OnComparisonTypeChanged() {
+      OnToStringChanged();
+    }
+
+    public override void CollectParameterValues(IDictionary<string, IItem> values) {
+      base.CollectParameterValues(values);
+      values.Add(ComparisonValueParameter.Name, new StringValue(ComparisonValueParameter.ActualName));
+    }
+
+    public override string ToString() {
+      if (Threshold == null) return Name;
+      else return string.Format("{0} {1} {2}", Name, ComparisonType.ToSymbol(), ThresholdParameter.Value);
+    }
+  }
+
+  internal static class ComparisonTypeHelper {
+    public static bool Compare(this ComparisonType comparison, IComparable lhs, IComparable rhs) {
+      int i = lhs.CompareTo(rhs);
+      switch (comparison) {
+        case ComparisonType.Less: return i < 0;
+        case ComparisonType.LessOrEqual: return i <= 0;
+        case ComparisonType.Equal: return i == 0;
+        case ComparisonType.GreaterOrEqual: return i >= 0;
+        case ComparisonType.Greater: return i > 0;
+        case ComparisonType.NotEqual: return i != 0;
+        default: throw new InvalidOperationException(comparison + " is not supported.");
+      }
+    }
+
+    public static string ToSymbol(this ComparisonType comparison) {
+      switch (comparison) {
+        case ComparisonType.Less: return "<";
+        case ComparisonType.LessOrEqual: return "<=";
+        case ComparisonType.Equal: return "=";
+        case ComparisonType.GreaterOrEqual: return ">=";
+        case ComparisonType.Greater: return ">";
+        case ComparisonType.NotEqual: return "!=";
+        default: throw new InvalidOperationException(comparison + " is not supported.");
+      }
+    }
+  }
+}
Index: stable/HeuristicLab.Optimization/3.3/Termination/ExecutionTimeTerminator.cs
===================================================================
--- stable/HeuristicLab.Optimization/3.3/Termination/ExecutionTimeTerminator.cs	(revision 13282)
+++ stable/HeuristicLab.Optimization/3.3/Termination/ExecutionTimeTerminator.cs	(revision 13282)
@@ -0,0 +1,63 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("ExecutionTimeTerminator", "A termination criterion based on execution time of an algorithm.")]
+  [StorableClass]
+  public class ExecutionTimeTerminator : ThresholdTerminator<TimeSpanValue> {
+
+    [Storable]
+    private readonly IExecutable executable;
+
+    [StorableConstructor]
+    protected ExecutionTimeTerminator(bool deserializing) : base(deserializing) { }
+    protected ExecutionTimeTerminator(ExecutionTimeTerminator original, Cloner cloner)
+      : base(original, cloner) {
+      executable = cloner.Clone(executable);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExecutionTimeTerminator(this, cloner);
+    }
+    public ExecutionTimeTerminator(IExecutable executable)
+      : this(executable, new TimeSpanValue(new TimeSpan(0, 10, 0))) { }
+    public ExecutionTimeTerminator(IExecutable executable, TimeSpanValue maximumExecutionTime)
+      : base(maximumExecutionTime) {
+      this.executable = executable;
+      Name = "Execution Time";
+    }
+
+    protected override bool CheckContinueCriterion() {
+      var max = ThresholdParameter.Value.Value;
+      return executable.ExecutionTime < max;
+    }
+
+    public override string ToString() {
+      if (Threshold == null) return Name;
+      else return string.Format("{0} {1} {2}", Name, "<", ThresholdParameter.Value);
+    }
+  }
+}
Index: stable/HeuristicLab.Optimization/3.3/Termination/MultiTerminator.cs
===================================================================
--- stable/HeuristicLab.Optimization/3.3/Termination/MultiTerminator.cs	(revision 13282)
+++ stable/HeuristicLab.Optimization/3.3/Termination/MultiTerminator.cs	(revision 13282)
@@ -0,0 +1,78 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("MultiTerminator", "A multi operator, containing termination criteria.")]
+  [StorableClass]
+  public sealed class MultiTerminator : CheckedMultiOperator<ITerminator>, ITerminator {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.FlagRed; }
+    }
+
+    public ILookupParameter<BoolValue> TerminateParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Terminate"]; }
+    }
+
+    [StorableConstructor]
+    private MultiTerminator(bool deserializing) : base(deserializing) { }
+    private MultiTerminator(MultiTerminator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new MultiTerminator(this, cloner); }
+
+    public MultiTerminator()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Terminate", "The parameter which will be set to determine if execution should be terminated or should continue."));
+    }
+
+    public override IOperation InstrumentedApply() {
+      if (!Operators.CheckedItems.Any()) throw new InvalidOperationException(Name + ": Please add at least one termination criterion.");
+
+      var next = new OperationCollection(base.InstrumentedApply());
+      foreach (var item in Operators.CheckedItems)
+        next.Add(ExecutionContext.CreateOperation(item.Value));
+      return next;
+    }
+
+    public override void CollectParameterValues(IDictionary<string, IItem> values) {
+      foreach (var opParam in OperatorParameters) {
+        var op = opParam.Value;
+        var @checked = Operators.ItemChecked(op);
+        if (!@checked) continue;
+        var children = GetCollectedValues(opParam);
+        foreach (var c in children) {
+          if (String.IsNullOrEmpty(c.Key))
+            values.Add(opParam.Name, new StringValue(opParam.Value.ToString()));
+          else values.Add(opParam.Name + "." + c.Key, c.Value);
+        }
+      }
+    }
+  }
+}
Index: stable/HeuristicLab.Optimization/3.3/Termination/SingleObjectiveQualityTerminator.cs
===================================================================
--- stable/HeuristicLab.Optimization/3.3/Termination/SingleObjectiveQualityTerminator.cs	(revision 13282)
+++ stable/HeuristicLab.Optimization/3.3/Termination/SingleObjectiveQualityTerminator.cs	(revision 13282)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("SingleObjectiveQualityTerminator", "A termination criterion which uses a quality parameter (eg. current best quality) for termination.")]
+  [StorableClass]
+  public class SingleObjectiveQualityTerminator : ComparisonTerminator<DoubleValue> {
+    [StorableConstructor]
+    protected SingleObjectiveQualityTerminator(bool deserializing) : base(deserializing) { }
+    protected SingleObjectiveQualityTerminator(SingleObjectiveQualityTerminator original, Cloner cloner)
+      : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectiveQualityTerminator(this, cloner);
+    }
+    public SingleObjectiveQualityTerminator() { }
+
+    public void Parameterize(IParameter qualityParameter, ISingleObjectiveHeuristicOptimizationProblem problem) {
+      ComparisonValueParameter.ActualName = qualityParameter.Name;
+      if (problem == null) return;
+
+      var maximizationParameter = (IValueParameter<BoolValue>)problem.MaximizationParameter;
+      if (maximizationParameter != null) {
+        bool maximization = maximizationParameter.Value.Value;
+        ComparisonType = maximization ? ComparisonType.Less : ComparisonType.Greater;
+        Threshold.Value = maximization ? double.MaxValue : double.MinValue;
+      }
+    }
+  }
+}
Index: stable/HeuristicLab.Optimization/3.3/Termination/TerminationOperator.cs
===================================================================
--- stable/HeuristicLab.Optimization/3.3/Termination/TerminationOperator.cs	(revision 13282)
+++ stable/HeuristicLab.Optimization/3.3/Termination/TerminationOperator.cs	(revision 13282)
@@ -0,0 +1,92 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("TerminationOperator", "An operator which either calls the terminate- or the continue branch.")]
+  [StorableClass]
+  public sealed class TerminationOperator : InstrumentedOperator, ITerminationBasedOperator {
+    public ILookupParameter<ITerminator> TerminatorParameter {
+      get { return (ILookupParameter<ITerminator>)Parameters["Terminator"]; }
+    }
+    public ILookupParameter<BoolValue> TerminateParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Terminate"]; }
+    }
+    private OperatorParameter ContinueBranchParameter {
+      get { return (OperatorParameter)Parameters["ContinueBranch"]; }
+    }
+    private OperatorParameter TerminateBranchParameter {
+      get { return (OperatorParameter)Parameters["TerminateBranch"]; }
+    }
+
+    public IOperator ContinueBranch {
+      get { return ContinueBranchParameter.Value; }
+      set { ContinueBranchParameter.Value = value; }
+    }
+    public IOperator TerminateBranch {
+      get { return TerminateBranchParameter.Value; }
+      set { TerminateBranchParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    private TerminationOperator(bool deserializing) : base(deserializing) { }
+    private TerminationOperator(TerminationOperator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TerminationOperator(this, cloner);
+    }
+
+    public TerminationOperator()
+      : base() {
+      Parameters.Add(new LookupParameter<ITerminator>("Terminator", "The termination criteria which sould be checked."));
+      Parameters.Add(new LookupParameter<BoolValue>("Terminate", "The parameter which will be set to determine if execution should be terminated or schould continue."));
+      Parameters.Add(new OperatorParameter("ContinueBranch", "The operator which is executed if no termination criteria has met."));
+      Parameters.Add(new OperatorParameter("TerminateBranch", "The operator which is executed if any termination criteria has met."));
+
+      var assigner = new Assigner() { Name = "Terminate = false" };
+      assigner.LeftSideParameter.ActualName = TerminateParameter.Name;
+      assigner.RightSideParameter.Value = new BoolValue(false);
+
+      var placeholder = new Placeholder() { Name = "Check termination criteria (Placeholder)" };
+      placeholder.OperatorParameter.ActualName = TerminatorParameter.Name;
+
+      BeforeExecutionOperators.Add(assigner);
+      BeforeExecutionOperators.Add(placeholder);
+    }
+
+    public override IOperation InstrumentedApply() {
+      var next = new OperationCollection(base.InstrumentedApply());
+      if (TerminateParameter.ActualValue.Value) {
+        if (TerminateBranch != null) next.Insert(0, ExecutionContext.CreateOperation(TerminateBranch));
+      } else {
+        if (ContinueBranch != null) next.Insert(0, ExecutionContext.CreateOperation(ContinueBranch));
+      }
+      return next;
+    }
+  }
+}
Index: stable/HeuristicLab.Optimization/3.3/Termination/Terminator.cs
===================================================================
--- stable/HeuristicLab.Optimization/3.3/Termination/Terminator.cs	(revision 13282)
+++ stable/HeuristicLab.Optimization/3.3/Termination/Terminator.cs	(revision 13282)
@@ -0,0 +1,67 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Terminator", "A base class for all termination criteria.")]
+  [StorableClass]
+  public abstract class Terminator : SingleSuccessorOperator, ITerminator {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.FlagRed; }
+    }
+
+    public ILookupParameter<BoolValue> TerminateParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Terminate"]; }
+    }
+
+    [StorableConstructor]
+    protected Terminator(bool deserializing) : base(deserializing) { }
+    protected Terminator(Terminator original, Cloner cloner) : base(original, cloner) { }
+
+    protected Terminator()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Terminate", "The parameter which will be set to determine if execution should be terminated or should continue."));
+    }
+
+    public sealed override IOperation Apply() {
+      if (!TerminateParameter.ActualValue.Value) { // If terminate flag is already set, no need to check further termination criteria.
+        bool terminate = !CheckContinueCriterion();
+        TerminateParameter.ActualValue.Value = terminate;
+      }
+      return base.Apply();
+    }
+
+    protected abstract bool CheckContinueCriterion();
+
+    public override void CollectParameterValues(IDictionary<string, IItem> values) {
+      base.CollectParameterValues(values);
+      values["Type"] = new StringValue(GetType().GetPrettyName(false));
+    }
+  }
+}
Index: stable/HeuristicLab.Optimization/3.3/Termination/ThresholdTerminator.cs
===================================================================
--- stable/HeuristicLab.Optimization/3.3/Termination/ThresholdTerminator.cs	(revision 13282)
+++ stable/HeuristicLab.Optimization/3.3/Termination/ThresholdTerminator.cs	(revision 13282)
@@ -0,0 +1,96 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("ThresholdTerminator", "Base class for all termination criteria which specifies some threshold.")]
+  [StorableClass]
+  public abstract class ThresholdTerminator<T> : Terminator where T : class, IItem, IStringConvertibleValue, new() {
+    [Storable]
+    private IFixedValueParameter<T> thresholdParameter;
+    public IFixedValueParameter<T> ThresholdParameter {
+      get { return thresholdParameter; }
+      set {
+        if (value == null) throw new ArgumentNullException("Threshold parameter must not be null.");
+        if (value.Value == null) throw new ArgumentNullException("Threshold parameter value must not be null.");
+        if (thresholdParameter == value) return;
+
+        if (thresholdParameter != null) Parameters.Remove(thresholdParameter);
+        thresholdParameter = value;
+        Parameters.Add(thresholdParameter);
+        OnThresholdParameterChanged();
+      }
+    }
+
+    public T Threshold {
+      get { return ThresholdParameter.Value; }
+    }
+
+    [StorableConstructor]
+    protected ThresholdTerminator(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+    protected ThresholdTerminator(ThresholdTerminator<T> original, Cloner cloner)
+      : base(original, cloner) {
+      thresholdParameter = cloner.Clone(original.thresholdParameter);
+      Initialize();
+    }
+    protected ThresholdTerminator()
+      : this(new T()) { }
+    protected ThresholdTerminator(T threshold)
+      : base() {
+      if (threshold == null) throw new ArgumentNullException("threshold");
+      thresholdParameter = new FixedValueParameter<T>("Threshold", "The limit of the termiation criterion.", threshold);
+      Parameters.Add(thresholdParameter);
+      Initialize();
+    }
+
+    private void Initialize() {
+      RegisterThresholdParameterEvents();
+    }
+    private void RegisterThresholdParameterEvents() {
+      Threshold.ValueChanged += new EventHandler(Threshold_ValueChanged);
+    }
+    private void OnThresholdParameterChanged() {
+      RegisterThresholdParameterEvents();
+    }
+
+    private void Threshold_ValueChanged(object sender, EventArgs e) {
+      OnThresholdChanged();
+    }
+    protected virtual void OnThresholdChanged() {
+      OnToStringChanged();
+    }
+
+    public override string ToString() {
+      if (ThresholdParameter.Value == null) return Name;
+      else return Name + ": " + ThresholdParameter.Value;
+    }
+  }
+}
